I would like to export a native Google spreadsheet/document/drawing/presentation file to another format, in that same folder, using Google Apps Script. I have enabled Advanced Drive Service [1], and looked at the instructions to Open and Convert Google Docs in your app [2].
Was hoping I could use Export [3] to get a File [4] which I could then save/rename using Insert [5].
Trying to achieve something like:
var file = {fileId: "1yDe...lD2U",
folderId: "0B_...hZ1k",
mimetype:"application/vnd.google-apps.document",
targetMimetype:"application/pdf",
targetName:"my converted document"}
var newFile = Drive.Files.export(file.fileId, file.targetMimetype)
// results in error message:
// "Export requires alt=media to download the exported content."
// I am sure the above is incomplete, but unsure how to actually
// save the exported file, in the correct location, with correct filename
Update: when adding alt=media to the call (var newFile = Drive.Files.export(file.fileId, file.targetMimetype, {alt: "media"})), then the script exits with error code 200 and shows the PDF content in the error message. Similar to
issue 6573
[6].
Update: this may not have been clear enough, I want to convert from/to all of the formats listed in the Advanced Drive [7] page, not just to PDF. And the DriveApp getAs [8] documentation states that DriveApp can convert mostly to PDF and images. Hence the focus on using Advanced Drive instead of DriveApp.
ACCEPTED]
As a workaround I now use the OAuth2 library and the direct Drive API.
// ---------------------------------------------------------------------------------------------------
function testConvert() {
var file = {
id: "1cpAZp...I7ejZW1idk", // Google Sheet
folderId: "0B_...Z1k", // test folder
}
convert(file, "pdf", "application/pdf");
convert(file, "csv", "text/csv");
convert(file, "xlsx", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
}
// ---------------------------------------------------------------------------------------------------
function convert(file, extension, targetMimeType) {
var exportDetails = {
targetMimeType: targetMimeType || "application/pdf",
extension: extension || "pdf",
postfix: "CONVERTED_FROM_GOOGLE_DOC",
}
// http://stackoverflow.com/questions/42887569/using-google-apps-script-how-to-convert-export-a-drive-file
// https://code.google.com/p/google-apps-script-issues/issues/detail?id=6573
// var blob = Drive.Files.export(file.id, exportDetails.targetMimeType, {alt: "media"})
/*
results in error 200 + content of converted file
documentation https://developers.google.com/drive/v2/reference/files/export
1) does not mention the {alt:"media"} (and without it the error is: "export requires alt=media to download the exported content")
2) states the output is a Files resource (not a blob)
*/
// using alternative: OAuth2 + public API
// https://github.com/googlesamples/apps-script-oauth2
var driveService = getDriveService();
if (!driveService.hasAccess()) {
showSidebar();
return;
}
var accessToken = driveService.getAccessToken();
var url = "https://www.googleapis.com/drive/v2/files/"+file.id+"/export?mimeType="+ exportDetails.targetMimeType
var blob = UrlFetchApp.fetch(url, {
headers: {
Authorization: 'Bearer ' + driveService.getAccessToken()
}
});
var resource = {
title: DriveApp.getFileById(file.id).getName() +" "+ exportDetails.postfix +"."+ exportDetails.extension,
description: "This is a converted document",
mimeType: exportDetails.targetMimeType,
parents: [{
"kind": "drive#parentReference",
"id": file.folderId,
//"selfLink": string,
//"parentLink": string,
"isRoot": false
}],
}
try {
var convertedFile = Drive.Files.insert(resource, blob);
Logger.log('ID: %s, File size (bytes): %s', convertedFile.id, convertedFile.fileSize);
} catch(e) {
Logger.log(e)
}
}
Try to tweak this code [1] from Armit Agarwal. The important bits to exporting your drive file to PDF is this part of code:
var blob = DriveApp.getFileById(ss.getId()).getAs("application/pdf");
blob.setName(ss.getName() + ".pdf");
Then you can send it to your email by attaching the pdf file:
// If allowed to send emails, send the email with the PDF attachment
if (MailApp.getRemainingDailyQuota() > 0)
GmailApp.sendEmail(email, subject, body, {
htmlBody: body,
attachments:[blob]
});
Check the guide for additional reference.
[1] https://ctrlq.org/code/19869-email-google-spreadsheets-pdfHere is the proper solution from https://issuetracker.google.com/issues/36765129#comment8, by a Google person.
Files.export() was recently added to the Drive v2 API, but an alternative is to use the older File.exportLinks field instead. Here's an example:
function convertToDocx(documentId) {
var file = Drive.Files.get(documentId);
var url = file.exportLinks['application/vnd.openxmlformats-officedocument.wordprocessingml.document'];
var oauthToken = ScriptApp.getOAuthToken();
var response = UrlFetchApp.fetch(url, {
headers: {
'Authorization': 'Bearer ' + oauthToken
}
});
return response.getBlob();
}
You're very close. Just use the pdf content as one of the parts of a multipart insert/post.
Here is my version that I got to work after trying numerous examples:
function convertToDocx(newdocumentId,folder) {
var fileInstance = DriveApp.getFileById(newdocumentId);
var fileName = fileInstance.getName();
var blob = fileInstance.getBlob();
var resource = {
title: fileName + '.docx',
mimeType: MimeType.MICROSOFT_WORD,
parents: [
{
id: folder
}],
};
Drive.Files.insert(resource, blob,{ convert: true, supportsAllDrives: true });
}
function exportFile() {
var exportFormat = 'docx';
var docUrl = <Your doc url>;
var exportUrl = docUrl.replace(/^(.*)\/.*/,'$1/export?format=' + exportFormat);
var parameters = {
method: 'GET',
headers: { Authorization: 'Bearer ' + ScriptApp.getOAuthToken() }
};
var blob = UrlFetchApp.fetch(exportUrl, parameters).getBlob(); //.setName('exportName' + '.' + exportFormat);
DriveApp.createFile(blob);
}
This doesn't require neither API nor even advanced service
For Slides to export separate slide as image I needed to share the doc for viewing. For Docs works like this.
The name of the downloaded blob is just export+format, so you'll need to rename the blob probably first