如何格式化我在Google App Script中从Google文档复制的文字? [英] How do I format text I am copying from Google Document in Google App Script?

查看:116
本文介绍了如何格式化我在Google App Script中从Google文档复制的文字?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图从一个文档复制格式化文本并将其粘贴到另一个文档中。我想通过Google应用程序脚本获取整个文档并将其添加到另一个文档。
$ b

调用 body.getText()满足我的用例,但将文本作为字符串获取,未格式化。

能够将格式化文本从一个文档复制到另一个文档是非常棒的。

编辑:
接受建议我目前写了更多的代码。几乎完全遵循另一个答案,我仍然只获取文本而不是格式化。

  for(var i = 0; i< numElements; ++ i){
var element = copyBody。 getChild(i)
var type = element.getType();
if(type == DocumentApp.ElementType.PARAGRAPH)
{
var newElement = element.copy()。asParagraph();
newBody.appendParagraph(newElement);

else if(type == DocumentApp.ElementType.TABLE)
{
var newElement = element.copy()。asTable();
newBody.appendTable(newElement);
}
else if(type == DocumentApp.ElementType.LIST_ITEM)
{
var newElement = element.copy()。asListItem();
newBody.appendListItem(newElement);
}
其他{
Logger.log(WRONG ELEMENT)
}
}


解决方案

这个答案涵盖它。

您需要遍历源文档的元素,将每个元素附加到目标文档。您不要复制文本版本的段落等,而是复制整个元素,包括格式等。



脚本



由于文档现在支持可编程UI元素,因此这里是一个基于Henrique以前答案的脚本(上面),其中包括一个用于驱动文档合并的自定义菜单。您可以选择包含附加文档之间的分页符 - 如果您正在尝试创建多分章文档,则很有用。



此脚本必须包含在文档中(或者没有UI

  / ** 
*当Google Docs文档为$ b $时,onOpen函数会自动运行b *打开。
* /
函数onOpen(){
DocumentApp.getUi()。createMenu('Custom Menu')
.addItem('Append Document','appendDoc')
.addToUi();
}

/ **
*在Google Docs编辑器上方的对话框中显示自定义HTML用户界面。
* /
函数appendDoc(){
//表单的HTML在这里呈现为内联。
var html =
'< script>'
+'function showOutput(message){'
+'var div = document.getElementById(output);'
+'div.innerHTML = message''
+'}'
+'< / script>'
+'< form id =appendDoc>'
+'源文档ID:< input type =textsize = 60 name =docID>< br>'
+'插入分页符:< input type =checkbox name =pagebreakvalue =pagebreak>'
+'< input type =buttonvalue =Begin'
+'onclick =google.script.run.withSuccessHandler showOutput).processAppendDocForm(this.parentNode)/>'
+'< / form>'
+'< br>'
+'< div id =输出>< / div>'

DocumentApp.getUi()。showDialog(
HtmlService.createHtmlOutput(html)
.setTitle('Append Document')
.setWidth(400 / *像素* /)
.setHeight(150 / *像素* /));
}

/ **
*当appendDoc表单提交时,Handler调用。
* /
函数processAppendDocForm(formObject){
Logger.log(JSON.stringify(formObject));
var pagebreak =(formObject.pagebreak =='pagebreak');
mergeDocs([DocumentApp.getActiveDocument()。getId(),formObject.docID],pagebreak);
返回附加文档。
}

/ **
*通过附加其他所有内容更新列表中的第一个文档。
*
* Henrique的mergeDocs()的修改版本。
* https://stackoverflow.com/a/10833393/1677912
*
* @param {Array} docIDs要合并的文档数组。
* @param {Boolean} pagebreak如果在附加文档之间需要分页符
*,则设置为true。
* /
函数mergeDocs(docIDs,pagebreak){
var baseDoc = DocumentApp.openById(docIDs [0]);
var body = baseDoc.getBody(); (变量i = 1; i< docIDs.length; ++ i){
if(pagebreak)body.appendPageBreak();


var otherBody = DocumentApp.openById(docIDs [i])。getBody();
Logger.log(otherBody.getAttributes());
var totalElements = otherBody.getNumChildren();
var latestElement; (var j = 0; j var element = otherBody.getChild(j).copy();
var attributes = otherBody.getChild(j).getAttributes();
//用于比较的日志属性
Logger.log(attributes);
Logger.log(element.getAttributes());
var type = element.getType();
if(type == DocumentApp.ElementType.PARAGRAPH){
if(element.asParagraph()。getNumChildren()!= 0&& element.asParagraph()。getChild(0).getType ()== DocumentApp.ElementType.INLINE_IMAGE){
var pictattr = element.asParagraph()。getChild(0).asInlineImage()。getAttributes();
var blob = element.asParagraph()。getChild(0).asInlineImage()。getBlob();
//图像属性,例如大小,不复存在,需要单独申请
latestElement = body.appendImage(blob);
latestElement.setAttributes(clean(pictattr));
}
else latestElement = body.appendParagraph(element);
}
else if(type == DocumentApp.ElementType.TABLE)
latestElement = body.appendTable(element);
else if(type == DocumentApp.ElementType.LIST_ITEM)
latestElement = body.appendListItem(element);
else
抛出错误(Unsupported element type:+ type);
//如果您发现元素属性未通过,请取消注释以下
//行以明确复制原始文档中的元素属性。
//latestElement.setAttributes (clean(attributes));
}
}
}


/ **
*删除样式对象中的空属性,通过调用
获得* .getAttributes()。
* https://code.google.com/p/google-apps-script-issues/issues/detail?id=2899
* /
function clean(style){
for(var attr in style){
if(style [attr] == null)delete style [attr];
}
返回样式;
}

编辑:通过处理来自Serge's回答,处理图像大小属性。正如注释所表明的那样,在append中存在一些属性被阻塞的问题,因此引入了 clean()辅助函数并使用了 .setAttributes()然而,你会注意到对 .setAttributes()的调用被注释掉了;这是因为它也有一个副作用,会删除一些格式。这是你想要处理的烦恼的选择。


I am trying to copy formatted text from one document and paste it into another. I want to take the entirety of one document and add it to another via Google App Script.

The call body.getText() satisfies my use case but gets the text as a string, not formatted.

It would be great to be able to copy formatted text from one document to another.

EDIT: Taking the advice I currently wrote some more code. Following the other answer almost exactly, I am still only getting the text and not the formatting too.

  for(var i = 0; i < numElements; ++i) {
  var element = copyBody.getChild(i)
  var type = element.getType();
   if (type == DocumentApp.ElementType.PARAGRAPH)
   {
     var newElement = element.copy().asParagraph();
     newBody.appendParagraph(newElement); 
   }
   else if(type == DocumentApp.ElementType.TABLE)
   {
     var newElement = element.copy().asTable();
     newBody.appendTable(newElement); 
   }
   else if(type == DocumentApp.ElementType.LIST_ITEM)
   {     
     var newElement = element.copy().asListItem();
     newBody.appendListItem(newElement);
   }
    else{
    Logger.log("WRONG ELEMENT")    
    }
  }    

解决方案

This answer covers it.

You need to iterate through the elements of the source document, appending each to the destination doc. You don't copy Text versions of paragraphs, etc., instead you copy the whole element including formatting etc.

Script

Since Documents now support programmable UI elements, here's a script based on Henrique's previous answer (above), that includes a Custom Menu to drive the merge of documents. You may optionally include page breaks between appended documents - useful if you are trying to create a multi-chapter document.

This script must be contained in a Document (or no UI for you)!

/**
 * The onOpen function runs automatically when the Google Docs document is
 * opened. 
 */
function onOpen() {
  DocumentApp.getUi().createMenu('Custom Menu')
      .addItem('Append Document','appendDoc')
      .addToUi();
}

/**
 * Shows a custom HTML user interface in a dialog above the Google Docs editor.
 */
function appendDoc() {
  // HTML for form is rendered inline here.
  var html =
      '<script>'
  +     'function showOutput(message) {'
  +       'var div = document.getElementById("output");'
  +       'div.innerHTML = message;'
  +     '}'
  +   '</script>'
  +   '<form id="appendDoc">'
  +     'Source Document ID: <input type="text" size=60 name="docID"><br>'
  +     'Insert Page Break: <input type="checkbox" name="pagebreak" value="pagebreak">'
  +     '<input type="button" value="Begin" '
  +       'onclick="google.script.run.withSuccessHandler(showOutput).processAppendDocForm(this.parentNode)" />'
  +   '</form>' 
  +   '<br>'
  +   '<div id="output"></div>'

  DocumentApp.getUi().showDialog(
    HtmlService.createHtmlOutput(html)
               .setTitle('Append Document')
               .setWidth(400 /* pixels */)
               .setHeight(150 /* pixels */));
}

/**
 * Handler called when appendDoc form submitted.
 */
function processAppendDocForm(formObject) {
  Logger.log(JSON.stringify(formObject));
  var pagebreak = (formObject.pagebreak == 'pagebreak');
  mergeDocs([DocumentApp.getActiveDocument().getId(),formObject.docID],pagebreak);
  return "Document appended.";
}

/**
 * Updates first document in list by appending all others.
 *
 * Modified version of Henrique's mergeDocs().
 * https://stackoverflow.com/a/10833393/1677912
 *
 * @param {Array} docIDs      Array of documents to merge.
 * @param {Boolean} pagebreak Set true if a page break is desired
 *                              between appended documents.
 */
function mergeDocs(docIDs,pagebreak) {
  var baseDoc = DocumentApp.openById(docIDs[0]);
  var body = baseDoc.getBody();

  for( var i = 1; i < docIDs.length; ++i ) {
    if (pagebreak) body.appendPageBreak();
    var otherBody = DocumentApp.openById(docIDs[i]).getBody(); 
    Logger.log(otherBody.getAttributes());
    var totalElements = otherBody.getNumChildren();
    var latestElement;
    for( var j = 0; j < totalElements; ++j ) {
      var element = otherBody.getChild(j).copy();
      var attributes = otherBody.getChild(j).getAttributes();
      // Log attributes for comparison
      Logger.log(attributes);
      Logger.log(element.getAttributes());
      var type = element.getType(); 
      if (type == DocumentApp.ElementType.PARAGRAPH) {
        if (element.asParagraph().getNumChildren() != 0 && element.asParagraph().getChild(0).getType() == DocumentApp.ElementType.INLINE_IMAGE) {
          var pictattr = element.asParagraph().getChild(0).asInlineImage().getAttributes();
          var blob = element.asParagraph().getChild(0).asInlineImage().getBlob();
          // Image attributes, e.g. size, do not survive the copy, and need to be applied separately
          latestElement = body.appendImage(blob);
          latestElement.setAttributes(clean(pictattr));
        }
        else latestElement = body.appendParagraph(element);
      }
      else if( type == DocumentApp.ElementType.TABLE )
        latestElement = body.appendTable(element);
      else if( type == DocumentApp.ElementType.LIST_ITEM )
        latestElement = body.appendListItem(element);
      else
        throw new Error("Unsupported element type: "+type);
      // If you find that element attributes are not coming through, uncomment the following
      // line to explicitly copy the element attributes from the original doc.
      //latestElement.setAttributes(clean(attributes));
    }
  }
}


/**
 * Remove null attributes in style object, obtained by call to
 * .getAttributes().
 * https://code.google.com/p/google-apps-script-issues/issues/detail?id=2899
 */
function clean(style) {
  for (var attr in style) {
    if (style[attr] == null) delete style[attr];
  }
  return style;
}

Edit: Adopted handling of inline images from Serge's answer, with handling of image size attributes. As the comments indicate, there have been problems with some attributes being snarfed in the append, thus the introduction of the clean() helper function and use of .setAttributes(). However, you'll note that the call to .setAttributes() is commented out; that's because it too has a side-effect that will remove some formatting. It's your choice about which annoyance you'd rather deal with.

这篇关于如何格式化我在Google App Script中从Google文档复制的文字?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆