【发布时间】:2019-08-22 10:08:12
【问题描述】:
我正在尝试将多个 Google 文档合并到一个文档中,但原始文档中的图像被插入了两次。一个在正确的位置,另一个在新创建的文档的末尾。
据我所见,这些图片被脚本检测为Paragraph。
正如您在下面的代码中看到的那样,我受到了此处发现的类似主题的启发。
其中一位建议在Paragraph Element 中搜索child Element,但调试显示没有。文档的相关部分将始终使用 appendParagraph 方法插入,因为脚本无法正确检测图像。
这就是为什么我发现的其他相关主题在这里不起作用:它建议在段落本身之前插入图像但它无法检测到它。
使用来自 Stackdriver 的默认 Logger 和 console.log 进行日志记录将显示类型为段落的对象。
一步一步的执行没有显示任何循环调用appendParagraph方法两次。
/* chosenParts contains list of Google Documents name */
function concatChosenFiles(chosenParts) {
var folders = DriveApp.getFoldersByName(folderName);
var folder = folders.hasNext() ? folders.next() : false;
var parentFolders = folder.getParents();
var parentFolder = parentFolders.next();
var file = null;
var gdocFile = null;
var fileContent = null;
var offerTitle = "New offer";
var gdocOffer = DocumentApp.create(offerTitle);
var gfileOffer = DriveApp.getFileById(gdocOffer.getId()); // transform Doc into File in order to choose its path with DriveApp
var offerHeader = gdocOffer.addHeader();
var offerContent = gdocOffer.getBody();
var header = null;
var headerSubPart = null;
var partBody= null;
var style = {};
parentFolder.addFile(gfileOffer); // place current offer inside generator folder
DriveApp.getRootFolder().removeFile(gfileOffer); // remove from home folder to avoid copy
for (var i = 0; i < chosenParts.length; i++) {
// First retrieve Document to combine
file = folder.getFilesByName(chosenParts[i]);
file = file.hasNext() ? file.next() : null;
gdocFile = DocumentApp.openById(file.getId());
header = gdocFile.getHeader();
// set Header from first doc
if ((0 === i) && (null !== header)) {
for (var j = 0; j < header.getNumChildren(); j++) {
headerSubPart = header.getChild(j).copy();
offerHeader.appendParagraph(headerSubPart); // Assume header content is always a paragraph
}
}
fileContent = gdocFile.getBody();
// Analyse file content and insert each part inside the offer with the right method
for (var j = 0; j < fileContent.getNumChildren(); j++) {
// There is a limit somewhere between 50-100 unsaved changed where the script
// wont continue until a batch is commited.
if (j % 50 == 0) {
gdocOffer.saveAndClose();
gdocOffer = DocumentApp.openById(gdocOffer.getId());
offerContent = gdocOffer.getBody();
}
partBody = fileContent.getChild(j).copy();
switch (partBody.getType()) {
case DocumentApp.ElementType.HORIZONTAL_RULE:
offerContent.appendHorizontalRule();
break;
case DocumentApp.ElementType.INLINE_IMAGE:
offerContent.appendImage(partBody);
break;
case DocumentApp.ElementType.LIST_ITEM:
offerContent.appendListItem(partBody);
break;
case DocumentApp.ElementType.PAGE_BREAK:
offerContent.appendPageBreak(partBody);
break;
case DocumentApp.ElementType.PARAGRAPH:
// Search for image inside parapraph type
if (partBody.asParagraph().getNumChildren() != 0 && partBody.asParagraph().getChild(0).getType() == DocumentApp.ElementType.INLINE_IMAGE)
{
offerContent.appendImage(partBody.asParagraph().getChild(0).asInlineImage().getBlob());
} else {
offerContent.appendParagraph(partBody.asParagraph());
}
break;
case DocumentApp.ElementType.TABLE:
offerContent.appendTable(partBody);
break;
default:
style[DocumentApp.Attribute.BOLD] = true;
offerContent.appendParagraph("Element type '" + partBody.getType() + "' from '" + file.getName() + "' could not be merged.").setAttributes(style);
console.log("Element type '" + partBody.getType() + "' from '" + file.getName() + "' could not be merged.");
Logger.log("Element type '" + partBody.getType() + "' from '" + file.getName() + "' could not be merged.");
}
}
// page break at the end of each part.
offerContent.appendPageBreak();
}
}
无论组合多少文件都会出现问题,使用一个就足以重现。
如果文件中只有一个图像(没有空格或换行),并且之后没有使用“appendPageBreak”,则不会发生。当某些文本位于图像旁边时,图像就会被复制。
最后一件事:有人建议这是“由于格式的自然继承”,但我没有找到如何防止这种情况。
非常感谢所有能够查看此内容的人 :)
编辑:我在@ziganotschka 建议之后修改了段落部分
它与this subject 非常相似,只是它的解决方案在这里不起作用。
这是新的代码:
case DocumentApp.ElementType.PARAGRAPH:
// Search for image inside parapraph type
if(partBody.asParagraph().getPositionedImages().length) {
// Assume only one image per paragraph (@TODO : to improve)
tmpImage = partBody.asParagraph().getPositionedImages()[0].getBlob().copyBlob();
// remove image from paragraph in order to add only the paragraph
partBody.asParagraph().removePositionedImage(partBody.asParagraph().getPositionedImages()[0].getId());
tmpParagraph = offerContent.appendParagraph(partBody.asParagraph());
// Then add the image afterward, without text
tmpParagraph.addPositionedImage(tmpImage);
} else if (partBody.asParagraph().getNumChildren() != 0 && partBody.asParagraph().getChild(0).getType() == DocumentApp.ElementType.INLINE_IMAGE) {
offerContent.appendImage(partBody.asParagraph().getChild(0).asInlineImage().getBlob());
} else {
offerContent.appendParagraph(partBody.asParagraph());
}
break;
不幸的是,它仍然复制图像。如果我注释插入图像的行 (tmpParagraph.addPositionedImage(tmpImage);),则根本不会插入任何图像。
编辑 2:这是 Google App Script 中的一个已知错误
https://issuetracker.google.com/issues/36763970
请参阅 cmets 了解一些解决方法。
【问题讨论】:
-
我复制了你的代码,没有遇到你描述的行为。您能否提供一个样本文档以允许重现该问题?
-
感谢您的宝贵时间;我很惊讶您无法重现:-/ 这是触发错误行为的文件的链接:docs.google.com/document/d/…
标签: google-apps-script google-docs