Iframe 有没有办法保存一个Google文档,使其具有与现有文档相同的唯一ID?
我需要创建一份带有特定ID的Google文档副本-不是像Iframe 有没有办法保存一个Google文档,使其具有与现有文档相同的唯一ID?,iframe,google-apps-script,google-docs,Iframe,Google Apps Script,Google Docs,我需要创建一份带有特定ID的Google文档副本-不是像MyDocument这样的“友好”名称,而是让它在Google领域独一无二的名称-像1x_tfTiA9-b5UwAf3k2fg6y6hyZSYQIvhSNn-saaDs4c这样的名称 下面是我为什么要这样做的场景: 我有一份谷歌文档形式的时事通讯。通过将文档嵌入元素中的网页,将新闻稿发布在网站上。同样以同样的方式发布的是“大号印刷”版本的新闻稿,除了默认的字体大小是24磅,而不是11磅 我正在尝试自动化大号打印版本的生产,但这样做不会改变大
MyDocument
这样的“友好”名称,而是让它在Google领域独一无二的名称-像1x_tfTiA9-b5UwAf3k2fg6y6hyZSYQIvhSNn-saaDs4c这样的名称
下面是我为什么要这样做的场景:
我有一份谷歌文档形式的时事通讯。通过将文档嵌入
元素中的网页,将新闻稿发布在网站上。同样以同样的方式发布的是“大号印刷”版本的新闻稿,除了默认的字体大小是24磅,而不是11磅
我正在尝试自动化大号打印版本的生产,但这样做不会改变大号打印文档的唯一ID,因此它的嵌入式
仍然有效
我过去曾尝试过使用谷歌应用程序脚本例程来创建文档的深度副本,但深度副本功能无法很好地处理图像和表格,因此我永远无法获得完整的副本。如果我可以实现一个“另存为”函数,其中操作数是一个现有的唯一ID,我想这可以满足我的需要
有人知道我是如何做到这一点的吗?我对此进行了深入研究,试图通过多种方式设置文件的“大号打印”版本的id:
via:var copiedFile=Drive.Files.copy(lpFile、spFile.id、选项)代码>
这会产生错误:
复制请求当前不支持生成的ID
via:var newFile=Drive.Files.insert(lpFile,doc.getBlob(),options)代码>
这会产生错误:
Google文档格式不支持生成的ID
via:Drive.Files.update(lpFile,lpFile.id,doc.getBlob(),选项)代码>
此方法成功地从小打印文件更新“大打印”文件。但是,这一行使用的方法在格式和来自的丰富内容方面存在问题。特别是,正如您所提到的,中的图像和表格不会被保留(除其他外,如字体的更改等)。比照
如果能够找到从文档导出格式化字节内容的适当方法,update()
方法似乎最有希望。请注意,应用程序脚本客户端库中的update()
方法需要Blob
输入(即doc.getBlob().getBytes()
将不起作用),因此基本限制可能是(缺乏)对生成的Blob
数据中丰富格式信息的支持。考虑到这一点,我尝试了几种方法从“小字体”文件中获取“格式化的”Blob
数据:
via:Drive.Files.export(lpFile,lpFile.id,doc.getAs(),选项)代码>
对于看似合理但有错误的类型,它将失败:
MimeType.GOOGLE\u DOCS
:很抱歉,发生了服务器错误。请稍等,然后重试。
MimeType.MICROSOFT\u WORD
:不支持从application/vnd.google apps.document
转换为application/vnd.openxmlformats of cedocument.wordprocessingml.document
这些错误是有道理的,因为内部Google Docs MimeType是不可导出的(您不能“下载为”此文件类型,因为数据是保留的,但Google希望保留它),并且的文档表明文档服务只支持PDF导出。实际上,尝试使用getAs(mimeType)
从doc.getBlob()
强制执行Blob
失败,错误如下:
不支持从application/pdf
转换为application/vnd.openxmlformats of icedocument.wordprocessingml.document
使用DriveApp
获取Blob
,而不是文档服务:
Drive.Files.update(lpFile,lpFile.id,DriveApp.getFileById(smallPrintId.getBlob(),options)代码>
这与doc.getBlob()
具有相同的问题,并且可能使用相同的内部方法
使用DriveApp#getAs
与Document#getAs
考虑到本机应用程序脚本实现的局限性,我随后使用高级服务获取Blob
数据。这有点棘手,因为返回的文件
资源实际上不是文件,而是关于文件的元数据。使用RESTAPI获取Blob
需要将文件导出到所需的MimeType
。我们从上面了解到,PDF格式的Blob
无法正确导入,因为这是上述尝试使用的格式。我们还知道Google文档格式不可导出,所以只剩下MS Word的.docx
var blob = getBlobViaURL_(smallPrintId, MimeType.MICROSOFT_WORD);
Drive.Files.update(lpFile, lpFile.id, blob, options);
其中,getBlobViaURL\uu
为()驱动器.Files.export()
Apps脚本方法实现了中的解决方法
此方法成功地用“小字体”文件中的确切内容更新了现有的“大字体”文件——至少对于我的测试文档是这样。考虑到它涉及到下载内容,而不是使用导出方法可用的内部、已经存在的数据,因此对于较大的文件,它可能会失败
测试脚本:
function copyContentFromAtoB() {
var smallPrintId = "some id";
var largePrintId = "some other id";
// You must first enable the Drive "Advanced Service" before this will work.
// Get the file metadata of the to-be-updated file.
var lpFile = Drive.Files.get(largePrintId);
// View available options on the relevant Drive REST API pages.
var options = {
updateViewedDate: false,
};
// Ideally this would use Drive.Files.export, but there is a bug in the Apps Script
// client library's implementation: https://issuetracker.google.com/issues/36765129
var blob = getBlobViaURL_(smallPrintId, MimeType.MICROSOFT_WORD);
// Replace the contents of the large print version with that of the small print version.
Drive.Files.update(lpFile, lpFile.id, blob, options);
}
// Below function derived from https://stackoverflow.com/a/42925916/9337071
function getBlobViaURL_(id, mimeType) {
var url = "https://www.googleapis.com/drive/v2/files/"+id+"/export?mimeType="+ mimeType;
var resp = UrlFetchApp.fetch(url, {
headers: { Authorization: 'Bearer ' + ScriptApp.getOAuthToken()}
});
return resp.getBlob();
}
您是否使用过驱动器“高级服务”(也称为驱动器RESTAPI)?它提供了对文件属性的更多控制,例如设置上载操作的id目标,或给定文件的字节/blob内容。我自己也没有尝试过,我会给出一个答案。我不确定如何从脚本调用RESTAPI,但我会检查它。非常感谢。在高级服务对话框中有一个客户端库。它不是po