繁体   English   中英

如何设置要在Google App脚本中从Google文档复制的文本的格式?

[英]How do I format text I am copying from Google Document in Google App Script?

我正在尝试从一个文档中复制格式文本并将其粘贴到另一个文档中。 我想将一个文档的全部内容通过Google App脚本添加到另一个文档中。

调用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);
   }
    else{
    Logger.log("WRONG ELEMENT")    
    }
  }    

这个答案涵盖了它。

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

脚本

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

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

/**
 * 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;
}

编辑:通过Serge的答案对内联图像进行处理,并处理图像大小属性。 正如评论所指出的那样,某些属性在附录中被塞住了,因此引入了clean()辅助函数以及.setAttributes()使用存在问题。 但是 ,您会注意到对.setAttributes()的调用已被注释掉。 那是因为它也有副作用,它将删除某些格式。 您要选择要处理哪种烦恼。

这对Mogsdad脚本略有改进,也可以复制内联图像。

唯一的问题是,如果图像已调整大小,但副本中没有保留此新尺寸,则会以原始尺寸显示图像...现在不知道如何解决该问题。

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();
    var totalElements = otherBody.getNumChildren();
    for( var j = 0; j < totalElements; ++j ) {
      var element = otherBody.getChild(j).copy();
      var type = element.getType(); 
      if (type == DocumentApp.ElementType.PARAGRAPH) {
        if (element.asParagraph().getNumChildren() != 0 && element.asParagraph().getChild(0).getType() == DocumentApp.ElementType.INLINE_IMAGE) {
          var blob = element.asParagraph().getChild(0).asInlineImage().getBlob();
          body.appendImage(blob);
        }
        else body.appendParagraph(element.asParagraph());
      }
      else if( type == DocumentApp.ElementType.TABLE )
        body.appendTable(element);
      else if( type == DocumentApp.ElementType.LIST_ITEM )
        body.appendListItem(element);
      else
        throw new Error("According to the doc this type couldn't appear in the body: "+type);
    }
  }
}

您可以在此doc ID上进行测试:1E6yoROb52QjICsEbGVXIBdz8KhdFU_5gimWlJUbu8DI

(执行成功[总运行时间为43.896秒])! 耐心一点 !

该代码来自另一篇文章

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM