这个答案涵盖了它。
您需要遍历源文档的元素,将每个元素附加到目标文档。您不会复制Text
段落等的版本,而是复制整个元素,包括格式等。
脚本
由于 Documents 现在支持可编程 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()
. 但是,您会注意到对 to 的调用已.setAttributes()
被注释掉;那是因为它也有一个副作用,会删除一些格式。您可以选择处理哪种烦恼。