Я углубился в это, пытаясь установить идентификатор версии «большого шрифта» файла различными способами:
через copy()
: var copiedFile = Drive.Files.copy(lpFile, spFile.id, options);
что приводит к ошибке:
Сгенерированные идентификаторы в настоящее время не поддерживаются для запросов на копирование
через insert()
: var newFile = Drive.Files.insert(lpFile, doc.getBlob(), options);
что приводит к ошибке:
Сгенерированные идентификаторы не поддерживаются для форматов Документов Google
через update()
: Drive.Files.update(lpFile, lpFile.id, doc.getBlob(), options);
Этот метод успешно обновляет файл «small print» из файла small print. Эта конкретная строка, однако, использует метод Document#getBlob()
, который имеет проблемы с форматированием и расширенным содержимым из Document
. В частности, как вы упоминаете, изображения и таблицы не сохраняются (среди прочего, например, изменения шрифта и т. Д.). Сравните pre с post
Похоже, что - если будет найден подходящий метод экспорта отформатированного байтового содержимого из документа - метод update()
наиболее перспективен. Обратите внимание, что метод update()
в клиентской библиотеке Apps Script требует ввода Blob
(т. Е. doc.getBlob().getBytes()
не будет работать), поэтому фундаментальным ограничением может быть (отсутствие) поддержки информации расширенного формата в создаваемом Blob
данные. Имея это в виду, я попробовал несколько способов получения «отформатированных» Blob
данных из файла «small print»:
- через
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
не поддерживается.
Эти ошибки имеют смысл, поскольку внутренний MimeType Документов Google не экспортируется (вы не можете «загрузить как» этот тип файла, поскольку данные сохраняются, однако Google хочет их сохранить), а также документацию для Document#getAs(mimeType)
означает, что служба документов поддерживает только экспорт PDF. Действительно, попытка заставить Blob
из doc.getBlob()
с помощью getAs(mimeType)
не удалась с ошибкой:
Преобразование из application/pdf
в application/vnd.openxmlformats-officedocument.wordprocessingml.document
не поддерживается.
с использованием DriveApp
для получения Blob
вместо службы документов:
Drive.Files.update(lpFile, lpFile.id, DriveApp.getFileById(smallPrintId).getBlob(), options);
Это имеет те же проблемы, что и doc.getBlob()
, и, вероятно, использует те же внутренние методы.
при использовании DriveApp#getAs
имеет те же ошибки, что и Document#getAs
Учитывая ограничения собственных реализаций Apps Script, я затем использовал расширенный сервис для получения данных Blob
. Это немного сложнее, поскольку возвращаемый ресурс File
на самом деле не файл, а метаданные о файле. Для получения Blob
с помощью REST API необходимо экспортировать файл в желаемый MimeType
. Из вышесказанного мы знаем, что формат Blob
в формате PDF не может быть импортирован должным образом, поскольку этот формат использовался вышеупомянутыми попытками. Мы также знаем, что формат Google Docs не экспортируется, поэтому в MS Word осталось только .docx
.
var blob = getBlobViaURL_(smallPrintId, MimeType.MICROSOFT_WORD);
Drive.Files.update(lpFile, lpFile.id, blob, options);
, где getBlobViaURL_
реализует обходной путь от этого SO вопроса для ( все еще неработающего ) Drive.Files.export()
метода скрипта приложения.
Этот метод успешно обновляет существующий файл "small print" с точным содержимым из файла "small print" - по крайней мере для моего тестового документа. Учитывая, что он предполагает загрузку контента вместо использования внутренних, уже имеющихся данных, доступных для методов экспорта, он, скорее всего, не сможет работать с файлами большего размера.
Скрипт тестирования:
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();
}