How to update file contents from gdoc to docx - google-apps-script

I am trying to create an Apps Script that will auto-convert all gdoc files to docx files (and all gsheet files to xlsx files). Some parts of the puzzle are addressed here: Batch convert Google Docs files to Microsoft Word, however this creates a new file. I need to keep the URL/ID of the original file. I tried using "setContent" on the File API but that doesn't seem to handle blobs. So thats why I resorted to the advanced Drive API. However, I can't seem to get it to work properly. The filename is replaced, the contents are replaced, but the file stays Google Doc, even though I supply a Mime Type. Any ideas?
This is my code:
function convertGoogleDocsToMicrosoftWord() {
var folderId = "MY_FOLDER_ID"; // Note, eventually I would like to get this from the trigger event somehow so I would welcome ideas on this, too
var files = DriveApp.getFolderById(srcfolderId).getFilesByType(MimeType.GOOGLE_DOCS);
while (files.hasNext()) {
var file = files.next();
var contents = UrlFetchApp.fetch(
"https://docs.google.com/document/d/" + file.getId() + "/export?format=docx",
{
"headers": {Authorization: 'Bearer ' + ScriptApp.getOAuthToken()},
"muteHttpExceptions": true
}
).getBlob();
Drive.Files.update({
mimeType: MimeType.MICROSOFT_WORD,
title: file.getName() + '.docx'
}, file.getId(), contents);
}
}
Some further questions:
assuming I can make this to work, can it update while the file is open?
I would like to be able to launch this on trigger events... however standalone scripts can't seem to be able to get a ref to the current folder they are executed in and then recourse. Is this possible?

Related

Exception: Blob object must have non-null data for this operation. (line 19)

Hi I'm trying to attach multiple Google Doc files from a folder to send to an Email. However, the above exception arises.
The code is as follows
function email() {
// Get attachments folder
var attachementFolderId = "xyz";
Logger.log("Attachement Folder ID: " + attachementFolderId)
var getAttachementFolder = DriveApp.getFolderById(attachementFolderId);
// Get all files from the folder
var files = DriveApp.getFolderById(attachementFolderId).getFiles();
//Get All attachments
var attachements = [];
while (files.hasNext()) {
var file = files.next();
attachements.push(file.getAs(MimeType.GOOGLE_DOCS));
}
MailApp.sendEmail({
to: email,
subject: subject,
attachments: attachements
})
}
This code works fine if the file is either a pdf or a Microsoft Word doc but causes an issue for a Google Doc.
Modification points:
When the official document of getAs(contentType)
) is seen, it says as follows.
The MIME type to convert to. For most blobs, 'application/pdf' is the only valid option. For images in BMP, GIF, JPEG, or PNG format, any of 'image/bmp', 'image/gif', 'image/jpeg', or 'image/png' are also valid.
In this case, unfortunately, MimeType.GOOGLE_DOCS cannot be used for this.
When you want to retrieve the blob from Google Document. It is required to convert it to other mimeType.
When you want to convert it to PDF format, please modify file.getAs(MimeType.GOOGLE_DOCS) to file.getBlob().
When you want to convert it to DOCX format, I think that this thread might be useful.
References:
getAs(contentType)
Related question
Convert Google Doc to Docx using Google Script

Saving charts as images when converting xls to Google Sheets - Google Script

I have a standard script from the Internet which converts xls to Google Sheets. The charts in the output file got converted to images which is a good thing, I needed charts to be saved as images as the original xls have specific formatting I would like to preserve but the problem is that they look awful - the color shaded, the font dropped to a very small size, the legend floats somewhere. Ultimately I need to have these images to be saved in Google Slides. So, what I was thinking is to find a way (1) to save images from xls and saves directly in Google slides or (2) to save images from xls to Google Sheets but somehow preserve the original formatting and then, run another code that saves the images to the target Slides. Interestingly, I have not found any mention of people complaining of the loss of the chart formatting.
function convertExceltoGoogleSpreadsheet2(fileName) {
try {
fileName = fileName || "name";
var excelFile = DriveApp.getFilesByName(fileName).next();
var fileId = excelFile.getId();
var folderId = Drive.Files.get(fileId).parents[0].id;
var blob = excelFile.getBlob();
var resource = {
title: excelFile.getName().replace(/.xlsx?/, ""),
key: fileId,
parents: [{id: 'id'}]
};
Drive.Files.insert(resource, blob, {
convert: true
});
} catch (f) {
Logger.log(f.toString());
}
}

Batch convert jpg to Google Docs

I have a folder of jpgs in Google Drive that I would like to convert to Google Docs. Now I can select each one manually and in the context menu "Open in Google Docs" This creates a new document with the image at the top of the page and OCR text below. I just want to do this with all my images.
There is a script here which converts gdoc to docx which I ought to be able to adapt for my case but I don't seem to be able to get it to work.
Here is my adapted script:
function convertJPGtoGoogleDocs() {
var srcfolderId = "~~~~~~~~~Sv4qZuPdJgvEq1A~~~~~~~~~"; // <--- Please input folder ID.
var dstfolderId = srcfolderId; // <--- If you want to change the destination folder, please modify this.
var files = DriveApp.getFolderById(srcfolderId).getFilesByType(MimeType.JPG);
while (files.hasNext()) {
var file = files.next();
DriveApp.getFolderById(dstfolderId).createFile(
UrlFetchApp.fetch(
"https://docs.google.com/document/d/" + file.getId() + "/export?format=gdoc",
{
"headers" : {Authorization: 'Bearer ' + ScriptApp.getOAuthToken()},
"muteHttpExceptions" : true
}
).getBlob().setName(file.getName() + ".docx")
);
}
}
Can anyone help?
Thanks.
You want to convert Jpeg files in a folder as Google Document.
When the Jpeg file is converted to Google Document, you want to use OCR.
If my understanding is correct, how about this modification?
Modification points:
In the script you modified, MimeType.JPG returns undefined. So the script in while is not run.
Please use MimeType.JPEG.
The script of this answer is used for exporting Google Document as Microsoft Word. Unfortunately, that script cannot be directly used for converting Jpeg file to Google Document.
If you want to modify the script of this answer, how about modifying as follows?
When you use this script, please enable Drive API at Advanced Google Services. By this, the API is automatically enabled at API console. The specification of Google Apps Script Project was Changed at April 8, 2019.
Modified script:
function convertJPGtoGoogleDocs() {
var srcfolderId = "~~~~~~~~~Sv4qZuPdJgvEq1A~~~~~~~~~"; // <--- Please input folder ID.
var dstfolderId = srcfolderId; // <--- If you want to change the destination folder, please modify this.
var files = DriveApp.getFolderById(srcfolderId).getFilesByType(MimeType.JPEG); // Modified
while (files.hasNext()) {
var file = files.next();
Drive.Files.insert({title: file.getName(), parents: [{id: dstfolderId}]}, file.getBlob(), {ocr: true}); // Modified
}
}
Note:
If there are a lot of files in the source folder, there is a possibility that the limitation of script runtime (6 min / execution) exceeds.
References:
Enum MimeType
Drive.Files.insert
If I misunderstand your question, please tell me. I would like to modify it.

How to Attach a Google Spreadsheet to an Email

I am trying to attach an already created spreadsheet and email it. I have found out that, if I try
opts.fileIds.forEach(function(fileId) {
console.log('fileId ' + fileId);
var file = DriveApp.getFileById(fileId);
var blob = file.getAs(file.getMimeType());
console.log('blob length' + blob.getDataAsString().length);
console.log('file retrieved size ' + file.getSize());
console.log('file mime type ' + file.getMimeType());
attachmentList.push(blob);
});
I do not get a blob object, file.getAs returns a null however, file.getBlob works fine but turns it into a pdf which is not what I want. Is there any way to attach this a spreadsheet?
The attachments option for MailApp requires an array of BlobSource objects. If you take a look at the link you can see that Google Files can just be attached without additional work. This includes Spreadsheets, Documents, PDFs, and more.
Try just passing back a reference to the file!
opts.fileIds.forEach(function(fileId) {
console.log('fileId ' + fileId);
var file = DriveApp.getFileById(fileId);
//logging
attachmentList.push(file);
});
Edit: The reason for this behaviour by MailApp, I think is because MIMEType and getAs() ContentType are different. Take a look at what the Google Scripts site says about https://developers.google.com/apps-script/reference/base/blob#getAs(String):
For most blobs, 'application/pdf' is the only valid option.
Can someone confirm this?

Can I overwrite the contents of an Excel file (exported from Google Sheets) saved on Google Drive with apps script

I use Google Apps script to export a Google Sheet as an Excel file to Google Drive. The Excel file then syncs with 6 others users to their local machines via the Google Drive Desktop app. Each time the Google Sheet is exported it creates a new file rather than replacing the old one albeit with the same filename and deletes the original version. This would be fine except that when it then syncs, with Google Drive Desktop, Windows deletes the original version and sends it to the recycle bin.
The file is created every 15 minutes and is 3mb in size so after a few weeks the recycle bins are full of Gigabytes of data.
Is it possible to update the contents of a file rather than create a new file?
Here's what I use at the moment:
var blob = exportAsExcel(spreadsheetId)
var file = DriveApp.createFile(blob).setName(excelFileName);
fileId = file.getId();
file.makeCopy(destinationFolder);
Drive.Files.remove(fileId);
}
function exportAsExcel(spreadsheetId) {
var file = Drive.Files.get(spreadsheetId);
var url = file.exportLinks['application/vnd.openxmlformatsofficedocument.spreadsheetml.sheet'];
var token = ScriptApp.getOAuthToken();
var response = UrlFetchApp.fetch(url, {
headers: {
'Authorization': 'Bearer ' + token
}
});
return response.getBlob();
}
You can overwrite a file using Drive API. The detail information is https://developers.google.com/drive/v3/reference/files/update.
I prepared a method to overwrite a spreadsheet to existing excel file. This method uses your method exportAsExcel(). At first, please confirm whether Drive API is enabled at Google API console and Advanced Google services.
src_sheetId and dst_fileId are spreadsheet ID and existing excel file that you want to overwrite, respectively. By running overWrite(), the existing excel file is overwritten. So the file name and file ID of excel file are not changed.
Script :
function overWrite(src_sheetId, dst_fileId) {
UrlFetchApp.fetch(
"https://www.googleapis.com/upload/drive/v3/files/" + dst_fileId + "?uploadType=multipart",
{
method: "PATCH",
headers: {Authorization: "Bearer " + ScriptApp.getOAuthToken()},
contentType: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
payload: exportAsExcel(src_sheetId).getBytes()
}
);
}
By the way, does exportAsExcel() of your script work fine? When I use it, an error occurs. I removed the error by modification below.
From :
var url = file.exportLinks['application/vnd.openxmlformatsofficedocument.spreadsheetml.sheet'];
To :
var url = file.exportLinks['application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'];
If I misunderstand your question, I'm sorry.