有没有办法保存 Google 文档,使其具有与现有文档相同的唯一 ID?



我需要创建一个具有特定ID的Google Doc的副本 - 不是像MyDocument这样的"友好"名称,而是使其在GoogleSphere中独一无二的名称 - 像1x_tfTiA9-b5UwAf3k2fg6y6hyZSYQIvhSNn-saaDs4c这样的名称。

以下是我想这样做的场景:

我有一个时事通讯,它是谷歌文档的形式。 新闻稿通过将文档嵌入网页中的<iframe>元素在网站上发布。 同样以同样的方式发布的是时事通讯的"大字体"版本,除了默认字体大小为 24pt 而不是 11pt 之外,这是相同的。

我正在尝试自动化大型打印版本的生产,但以这样一种方式,大型打印文档的唯一 ID 不会更改,以便它的嵌入式<iframe>仍然有效。

我过去曾尝试过使用 Google Apps 脚本例程来创建文档的深层副本,但深度复制功能不能很好地处理图像和表格,因此我永远无法获得完整的副本。 如果我可以实现一个"另存为"函数,其中操作数是现有的唯一 ID,我认为这将做我想要的。

有人知道我该怎么做吗?

我深入研究了这一点,尝试以多种方式设置文件的"大打印"版本的 id:

  1. 通过copy()var copiedFile = Drive.Files.copy(lpFile, spFile.id, options);
    产生错误:

    复制请求当前不支持生成的 ID

  2. 通过insert()var newFile = Drive.Files.insert(lpFile, doc.getBlob(), options);
    产生错误:

    Google 文档格式不支持生成的 ID

  3. viaupdate()Drive.Files.update(lpFile, lpFile.id, doc.getBlob(), options);
    此方法成功地从小打印文件更新"大打印"文件。但是,此特定行使用Document#getBlob()方法,该方法存在格式和Document丰富内容的问题。特别是,正如您提到的,不会保留其中的图像和表格(其中包括对字体的更改等(。比较前置和后

似乎 - 如果可以找到从文档中导出格式化字节内容的适当方法 -update()方法最有希望。请注意,应用程序脚本客户端库中的update()方法需要Blob输入(即doc.getBlob().getBytes()将不起作用(,因此根本限制可能是(缺乏(对生成的Blob数据中丰富格式信息的支持。考虑到这一点,我尝试了几种从"小字体"文件中获取"格式化"Blob数据的方法:

  1. 通过Document#getAs(mimetype)Drive.Files.export(lpFile, lpFile.id, doc.getAs(<type>), options);
    对于看似合理的类型,错误失败:

    MimeType.GOOGLE_DOCS:很抱歉,发生了服务器错误。请稍等片刻,然后重试。
    MimeType.MICROSOFT_WORD:不支持从application/vnd.google-apps.document转换为application/vnd.openxmlformats-officedocument.wordprocessingml.document

这些错误确实是有道理的,因为内部Google Docs MimeType不可导出(您不能"下载为"此文件类型,因为数据是保留的,但Google希望保留它(,并且Document#getAs(mimeType)的文档表明文档服务仅支持PDF导出。事实上,尝试用getAs(mimeType)强制Blobdoc.getBlob()失败,并出现以下错误:

不支持从application/pdf转换为application/vnd.openxmlformats-officedocument.wordprocessingml.document

  1. 使用DriveApp获取Blob,而不是文档服务:
    Drive.Files.update(lpFile, lpFile.id, DriveApp.getFileById(smallPrintId).getBlob(), options);
    这与doc.getBlob()具有相同的问题,并且可能使用相同的内部方法。

  2. 使用DriveApp#getAs具有与Document#getAs相同的错误


考虑到本机应用程序脚本实现的限制,然后我使用高级服务来获取Blob数据。这有点棘手,因为返回File资源实际上不是文件,而是有关文件的元数据。使用 REST API 获取Blob需要将文件导出到所需的MimeType。我们从上面知道,PDF 格式的Blob无法正确导入,因为这是上述尝试使用的格式。我们也知道谷歌文档格式是不可导出的,所以唯一剩下的就是 MS Word的.docx.

var blob = getBlobViaURL_(smallPrintId, MimeType.MICROSOFT_WORD);
Drive.Files.update(lpFile, lpFile.id, blob, options);

其中getBlobViaURL_为(仍然损坏的(Drive.Files.export()应用程序脚本方法实现此 SO 问题的解决方法。

此方法使用"小打印"文件中的确切内容成功更新了现有的"大打印"文件- 至少对于我的测试文档而言。鉴于它涉及下载内容,而不是使用导出方法可用的内部现有数据,因此对于较大的文件,它可能会失败。

测试脚本:

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();
}

最新更新