
[英]While updating google spreadsheet from google app script I am getting error message “You do not have permission to access the requested document.”
[英]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.