How to convert specific Google Spreadsheet to Excel? - excel

Dear 'Google APPS Script' Experts,
I need a script to convert a specific Google Spreadsheet and overwrite an Excel file (.xlsx) within Drive (same drive folder). I have a script to do this the other way around. I tried to change the script to make it work and searched on the internet to find a script but the ones I found did not work. I have no programming knowledge in this area so hope someone can help me with this.
The script to do this the other way around, many thanks to the script expert who shared this, looks like....
function convertExceltoGoogleSpreadsheet(fileName) {
var dstFileId = '1dL8MbCKdoWFcV8............etc';
fileName = fileName || 'Conversie_Test.xlsx'; // excel_file_name.xlsx = name of specific Excel file
var excelFile = DriveApp.getFilesByName('Conversie_Test.xlsx').next();
var fileId = excelFile.getId();
var srcFileId = fileId; // file Id of Excel file
Drive.Files.update({}, dstFileId, DriveApp.getFileById(srcFileId))
}
Hope someone can help me out on this.
Best regards,
Marco

Answer:
You can use the export method of Drive to export a Sheet as an Excel file and insert it into Drive using the Advanced Drive Service.
Prerequisites:
Make sure you have enabled the Advanced Drive service by going to Resources > Advanced Google Services, scrolling down to Drive API and while making sure that v2 is selected in the dropdown, clicking the slider on the right hand-side so that instead of 'off' it turns green and switches to 'on'.
Code:
function convertSheetToXlsx() {
var ssID = "<your-spreadsheet-id>";
var url = "https://docs.google.com/feeds/download/spreadsheets/Export?key=";
var exportMethod = "&exportFormat=xlsx";
var parameters = {
method: "get",
headers: {
"Authorization": "Bearer " + ScriptApp.getOAuthToken()
},
muteHttpExceptions: true
};
var fileAsBlob = UrlFetchApp.fetch(url + ssID + exportMethod, parameters).getBlob();
fileAsBlob.setName(SpreadsheetApp.openById(ssID).getName() + ".xlsx");
var fileData = {
title: SpreadsheetApp.openById(ssID).getName() + ".xlsx",
mimeType: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
};
Drive.Files.insert(fileData, fileAsBlob);
}
References:
Google Sheets API Documentation
Advanced Drive Service

Related

How do I copy data from an xlsx file in my google drive to a google sheet?

I have an excel file (.xlsx) saved on my google drive. I want to copy the data from there into a tab in a google sheet file i have already created. I have the following code that runs. But I don't know exactly how to specify the Google Sheet (and tab) to paste the excel data in?
``
function run() {
try {
fileName = fileName || "G:\Shared drives\ExchangeData\DailyVolumes.xlsx";
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
};
Drive.Files.insert(resource, blob, {
convert: true
});
} catch (f) {
Logger.log(f.toString());
}
}
You want to copy the values of ".xlsx" file to the existing Google Spreadsheet.
There is the ".xlsx" file in your Google Drive.
You want to achieve this using Google Apps Script.
If my understanding is correct, how about this answer? Please think of this as just one of several possible answers.
Modification points:
In order to retrieve the values from the Google Spreadsheet converted from the ".xlsx" file, it uses the file ID returned from Drive.Files.insert().
In your script, it is required to declare the destination Google Spreadsheet which copies the values from the ".xlsx" file and to use it.
Modified script:
When your script is modified, please modify as follows. Before you run the script, please set the variables of destSpreadsheetId and destSheetName.
From:
fileName = fileName || "G:\Shared drives\ExchangeData\DailyVolumes.xlsx";
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
};
Drive.Files.insert(resource, blob, {
convert: true
});
To:
var destSpreadsheetId = "###"; // Added
var destSheetName = "###"; // Added
fileName = fileName || "G:\Shared drives\ExchangeData\DailyVolumes.xlsx";
var excelFile = DriveApp.getFilesByName(fileName).next();
var fileId = excelFile.getId();
// var folderId = Drive.Files.get(fileId).parents[0].id; // This is not used in your script.
var blob = excelFile.getBlob();
var resource = {title: excelFile.getName().replace(/.xlsx?/, "")}; // Modified
var sourceSpreadsheet = Drive.Files.insert(resource, blob, {convert: true}); // Modified
// Also I added below script.
var sourceSheet = SpreadsheetApp.openById(sourceSpreadsheet.id).getSheets()[0];
var destSheet = SpreadsheetApp.openById(destSpreadsheetId).getSheetByName(destSheetName);
var values = sourceSheet.getDataRange().getValues();
destSheet.getRange(destSheet.getLastRow() + 1, 1, values.length, values[0].length).setValues(values);
Note:
In your question, I'm not sure whether the ".xlsx" file has several sheets and the range you want to put the values. So in this modification, as a sample, the values of the 1st tab in the converted Spreadsheet are copied to the last row in the destination Spreadsheet.
In this modified script, it supposes that you have already enabled Drive API at Advanced Google services.
References:
Files: insert
openById(id)
getSheets()
getDataRange()
getValues()
setValues(values)
If I misunderstood your question and this was not the direction you want, I apologize.

Transfer data in Excel attachment, in Outlook or Gmail, to Google sheet

I daily receive an email in Outlook with an Excel sheet attached.
I am working with dashboard/templates in Google data studio, and Google sheets. To make this work smoothly, I need to transfer the data from the Excel sheet to my Google sheet automatically. Is this possible?
My first thought was to send the attached Excel sheets to my gmail instead, because from here I could write a script that gets the data from the gmail. This was more complicated than I thought.
Maybe a VBA code to transfer the attached Excel file to google-drive, and then from there I could update my Google sheet? Is this possible?
Note: I am not experienced enough to write VBA/APP script from scratch.
Q: The OP asks: is it possible to transfer an Excel spreadsheet, received as an Outlook attachment, to google-drive, and then update it to a Google Sheet format?
A: Yes.
Q: What are the discrete steps required to satisfy the OP's objective?
A:
1 - Write a macro in Outlook to automatically forward the email and Excel attachment to the OP's GMail account; specifically to the account used to log into Google Sheets. For the purposes of this answer this aspect, though fairly straightforward, this is treated as off topic.
2 - Create a folder (or folder/subfolder) in Google Drive where the Excel spreadsheet can be saved. This could be done manually or by script. "Manually" is easier, "by script" is more fun and offers more flexibility.
3 - Run a Google script to access the OP's Gmail account, identify Excel attachments (say, files ending with 'xls', 'xlsx', 'xlsm' - other variations can be added), and save the Excel file to the Google Drive folder. Attach a "label" to each relevant email so that only new unprocessed messages are processed.
4 - Run a Google script to access the Google Drive folder/subfolder and convert the Excel spreadsheet to a Google Sheet.
As noted in comments, this topic has been raised, in one form or another, many times before: Is there any google API which could save gmail message attachments to google drive? and Convert all xls files available in a folder into “Google Doc Spreadsheets”? are two good examples. Google search will reveal many other topics - on StackOverflow and other sources.
However Google services (Docs, scripts, APIs, etc) are being constantly enhanced. One of the by-products of this development is that some methods are discontinued and this can render a previously correct answer to become out-of-date.
Unfortunately this is the case with the excellent GmailToDrive() function supplied in the Jan 2018 answer to Is there any google API which could save gmail message attachments to google drive?. Google Advanced Drive Service and Drive API changed during 2018 and that excellent answer now falls at the last hurdle.
The following code is supplied in order to provide an update to February 2019.
The basis of this answer is the GmailToDrive() function provided by Mr.Rebot, but modified for Excel files.
Trigger
The code should be set as a time-driven, Installable Trigger. The frequency will vary from case to case. The OP can make their own assessment. There are other sources that are available to explain this.
Drive API
The OP must activate the Drive API (Advanced Services as well as the Google Cloud Platform API Dashboard). For the sake of clarity, a brief outline of the steps is at the end of this answer.
Code
// GLOBALS
// Array of file extension which you would like to extract to Drive
var fileTypesToExtract = ['xls', 'xlsx', 'xlsm'];
//Name of the folders in google drive in which files will be put
var homeFolder = "009-StackExchange"; // a folder branching from the root
var ExcelFolderName = "010-GmailToDrive"; // sub folder of "homeFolder"
//Name of the label which will be applied after processing the mail message
var emaillabelName = 'GmailToDrive';
function so54755021()
// an adaptation of function GmailToDrive()
{
//build query to search emails
var query = '';
// loop through the filestoextract and add to query
for (var i in fileTypesToExtract) {
query += (query == '' ? ('filename:' + fileTypesToExtract[i]) : (' OR filename:' + fileTypesToExtract[i]));
}
//Logger.log("DEBUG: #01 the query is: " + query); //DEBUG
query = 'in:inbox has:nouserlabels ' + query;
//Logger.log("DEBUG: #02 the query is: " + query); //DEBUG
var threads = GmailApp.search(query);
//Logger.log("DEBUG: threads = " + threads + "; threads length = " + threads.length); //DEBUG
var label = getGmailLabel_(emaillabelName);
//Logger.log("DEBUG: label = " + label); //DEBUG (GmailToDrive)
var parentFolder;
if (threads.length > 0) {
//Logger.log("DEBUG: threads length is more than zero");//DEBUG
//Logger.log("DEBUG: folder name = " + folderName); //DEBUG
//parentFolder = getFolder_(folderName); // subroutine
// build sub-folder if necessary
createDriveFolder(homeFolder, ExcelFolderName);
parentFolder = homeFolder;
}
for (var i in threads) {
var mesgs = threads[i].getMessages();
for (var j in mesgs) {
//get attachments
var attachments = mesgs[j].getAttachments();
for (var k in attachments) {
var attachment = attachments[k];
//Logger.log("DEBUG: attachment: " + attachment);//DEBUG
var isExcelType = checkIfExcel_(attachment);
//Logger.log("DEBUG: isExceltype = " + isExcelType);//DEBUG
if (!isExcelType) continue;
// Copy the Blob
var attachmentBlob = attachment.copyBlob();
//Logger.log("DEBUG: attachmentblob = " + attachmentBlob);//DEBUG
var ExcelFolderObject = DriveApp.getFoldersByName(ExcelFolderName).next();
//Create the Excel file in Google Drive
var file = ExcelFolderObject.createFile(attachmentBlob);
// get the file name and ID
var fileid = file.getId();
var filename = file.getName();
// Logger.log("DEBUG: file = " + file + ", and ID = " + fileid + ", and file name: " + filename);//DEBUG
var fileType = file.getMimeType()
// Logger.log("DEBUG: the MIME type is " + fileType);//DEBUG
// copy the Blob again in preparation for conversion
var xBlob = file.getBlob();
// get the folder ID to copy the file
var folderId = DriveApp.getFoldersByName(ExcelFolderName).next().getId();
// set parameters for the new file
var newFile = {
title: filename + '_converted',
key: fileid,
parents: [{
"id": folderId
}]
}
// convert the file
var convfile = Drive.Files.insert(newFile, xBlob, {
convert: true
});
// Logger.log("DEBUG: the converted file is " + convfile);//DEBUG
}
}
// Add the label to the Gmail item
threads[i].addLabel(label);
}
}
// If necessary, create the label in GMail
function getGmailLabel_(name) {
var label = GmailApp.getUserLabelByName(name);
if (label == null) {
label = GmailApp.createLabel(name);
}
return label;
}
function createDriveFolder(baseFolder, folderName) {
var baseFolderObject = DriveApp.getFoldersByName(baseFolder).next();
//Logger.log("DEBUG: basefolderobject = " + baseFolderObject);//DEBUG
var folders = DriveApp.getFoldersByName(baseFolder).next().getFolders();
//Logger.log("DEBUG: folders: "+folders);//DEBUG
// set variable to detect a match
var foldermatch = 0;
//Loop through folders
while (folders.hasNext()) {
var folder = folders.next();
//Logger.log(DEBUG: folder.getName());//DEBUG
// If the folder name matches
if (folder.getName() == folderName) {
// update the match variable
foldermatch = 1;
// Logger.log("DEBUG: there's a match/folder exists: " + folder.getName());//DEBUG
}
}
// Do something is there is a match
if (foldermatch != 0) {
//Logger.log("DEBUG: There was a match so do NOTHING");//DEBUG
} else {
// Logger.log("DEBUG: There was no match so create the folder"); //DEBUG
baseFolderObject.createFolder(folderName);
}
// The folder already existed, or it has been created. Either way, our work is done.
return;
}
// this function will check for filextension type.
// and return boolean
function checkIfExcel_(attachment) {
var fileName = attachment.getName();
var temp = fileName.split('.');
var fileExtension = temp[temp.length - 1].toLowerCase();
if (fileTypesToExtract.indexOf(fileExtension) != -1) return true;
else return false;
}
Enable the Drive Api
1 - From the Script Editor, select Resources > Advanced Google Services; select Drive API and slide the switch to On.
2 - Click the link to the "Google Cloud Platform API Dashboard"
3 - The Google Cloud Platform - APIs and Services screen opens in a new window.
Click the link to Enable APIs and Services
4 - Search for "drive", and then click the option for Drive API.
5 - Click the "Enable" button for the Drive API
6 - The system will display the Drive API details; note the Drive API is enabled. Then just close this window.
7 - Click OK on the "Advances Google Services" screen (which has remained open all this time).
You're ready to run the script.

Uploading a file from Autodesk A360 to bucket in NodeJS

I am using the Forge data management API to access my A360 files and aim to translate them into the SVF format so that I can view them in my viewer. So far I have been able to reach the desired item using the ForgeDataManagement.ItemsApi, but I don't know what to do with the item to upload it to the bucket in my application.
From the documentation it seems like uploadObject is the way to go (https://github.com/Autodesk-Forge/forge.oss-js/blob/master/docs/ObjectsApi.md#uploadObject), but I don't know exactly how to make this function work.
var dmClient = ForgeDataManagement.ApiClient.instance;
var dmOAuth = dmClient.authentications ['oauth2_access_code'];
dmOAuth.accessToken = tokenSession.getTokenInternal();
var itemsApi = new ForgeDataManagement.ItemsApi();
fileLocation = decodeURIComponent(fileLocation);
var params = fileLocation.split('/');
var projectId = params[params.length - 3];
var resourceId = params[params.length - 1];
itemsApi.getItemVersions(projectId, resourceId)
.then (function(itemVersions) {
if (itemVersions == null || itemVersions.data.length == 0) return;
// Use the latest version of the item (file).
var item = itemVersions.data[0];
var contentLength = item.attributes.storageSize;
var body = new ForgeOSS.InputStream();
// var body = item; // Using the item directly does not seem to work.
// var stream = fs.createReadStream(...) // Should I create a stream object lik suggested in the documention?
objectsAPI.uploadObject(ossBucketKey, ossObjectName, contentLength, body, {}, function(err, data, response) {
if (err) {
console.error(err);
} else {
console.log('API called successfully. Returned data: ' + data);
//To be continued...
}
I hope someone can help me out!
My current data:
ossObjectName = "https://developer.api.autodesk.com/data/v1/projects/"myProject"/items/urn:"myFile".dwfx";
ossBucketKey = "some random string based on my username and id";
Regards,
torjuss
When using the DataManagement API, you can either work with
2 legged oAuth (client_credentials) and access OSS' buckets and objects,
or 3 legged (authorization_code) and access a user' Hubs, Projects, Folders, Items, and Revisions
When using 3 legged, you do access someones content on A360, or BIM360 and these files are automatically translated by the system, so you do not need to translate them again, not to transfer them on a 2 legged application bucket. The only thing you need to do it is get the manifest of the Item or its revision and use the URN to see it in the viewer.
Checkout an example here: https://developer.autodesk.com/en/docs/data/v2/reference/http/projects-project_id-versions-version_id-GET/
you'll see something like
Examples: Successful Retrieval of a Specific Version (200)
curl -X GET -H "Authorization: Bearer kEnG562yz5bhE9igXf2YTcZ2bu0z" "https://developer.api.autodesk.com/data/v1/projects/a.45637/items/urn%3Aadsk.wipprod%3Adm.lineage%3AhC6k4hndRWaeIVhIjvHu8w"
{
"data": {
"relationships": {
"derivatives": {
"meta": {
"link": {
"href": "/modelderivative/v2/designdata/dXJuOmFkc2sud2lwcWE6ZnMuZmlsZTp2Zi50X3hodWwwYVFkbWhhN2FBaVBuXzlnP3ZlcnNpb249MQ/manifest"
}
},
Now, to answer teh other question about upload, I got an example available here:
https://github.com/Autodesk-Forge/forge.commandline-nodejs/blob/master/forge-cb.js#L295. I copied the relevant code here for everyone to see how to use it:
fs.stat (file, function (err, stats) {
var size =stats.size ;
var readStream =fs.createReadStream (file) ;
ossObjects.uploadObject (bucketKey, fileKey, size, readStream, {}, function (error, data, response) {
...
}) ;
}) ;
Just remember that ossObjects is for 2 legged, where as Items, Versions are 3 legged.
We figured out how to get things working after some support from Adam Nagy. To put it simple we had to do everything by use of 3 legged OAuth since all operations involves a document from an A360 account. This includes accessing and showing the file structure, translating a document to SVF, starting the viewer and loading the document into the viewer.
Also, we were targeting the wrong id when trying to translate the document. This post shows how easily it can be done now, thanks to Adam for the info!

Export Google sheet as xlsx to company network drive

This function is triggered when the sheet is changed.
function exportAsxlsx() {
var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
var spreadsheetId = spreadsheet.getId()
var file = Drive.Files.get(spreadsheetId);
var url = file.exportLinks[MimeType.MICROSOFT_EXCEL];
var token = ScriptApp.getOAuthToken();
var response = UrlFetchApp.fetch(url, {
headers: {
'Authorization': 'Bearer ' + token
}
});
var blobs = response.getBlob();
var folder = DriveApp.getFoldersByName('\\GBC1234.fs1.util.xxint.com\Shared\Projects\Test_Google2Excel');
if(folder.hasNext()) {
var existingPlan1 = DriveApp.getFilesByName('TestGoogle2Excel.xlsx');
if(existingPlan1.hasNext()){
var existingPlan2 = existingPlan1.next();
var existingPlanID = existingPlan2.getId();
Drive.Files.remove(existingPlanID);
}
} else {
folder = DriveApp.createFolder('\\GBC1234.fs1.util.xxint.com\Shared\Projects\Test_Google2Excel');
}
folder = DriveApp.getFoldersByName('\\GBC1234.fs1.util.xxint.com\Shared\Projects\Test_Google2Excel').next();
folder.createFile(blobs).setName('TestGoogle2Excel.xlsx')
}
What happens is that it makes the directory "\GBC1234.fs1.util.xxint.com\Shared\Projects\Test_Google2Excel" in Google drive then saves the file there.
How can I get it to save to our company drive?
You will need to have a locally hosted 'client' which downloads said file from the known drive location to the network.
Once you start thinking about this the client could interact with a number of points on the workflow you describe.
I.e.
1. As described, polls google drive to see if output xlsx is created and download. Drive API
2. Poll the sheet in drive itself and also then trigger the apps script to perform conversion. Apps Script Execution API
3. Skip those altogether and interact with the sheet directly. Sheets API
In each case you'll want to cache a checksum of the original sheet data to only act if things have changed. (There are a number of ways to do this)

SharePoint 2010: how to upload a file to a doc lib using javascript

I see this article explaining how to upload a file using client API's from a fully trusted app.
How to implement such functionality but from javascript?
For example, I have this code in which I have both the local path of the file and the SharePoint doc lib, how do I complete it?
Thanks!
PS: I'm guessing there must be some fully trusted component involved in the client in order to achieve this, otherwise would be a javascript security hole, but which one would be the right one to use in this case against SharePoint?
<script type="text/javascript">
var list;
var filePath;
function ShowUploadDialog() {
// get file path user chooses through a dialog
var fileDialog = document.getElementById("fileDialog");
fileDialog.click();
filePath = fileDialog.value;
// get list
var context = new SP.ClientContext.get_current();
var site = context.get_site();
var web = site.get_rootWeb();
this.collList = web.get_lists();
list = collList.getByTitle("My doc library");
context.load(list);
context.executeQueryAsync(Succeeded, Failed);
}
function Succeeded(sender, args) {
// I HAVE HERE THE list AND THE filePath, HOW CAN UPLOAD THE FILE TO THE LIST?
}
function Failed(sender, args) {
alert('request failed ' + args.get_message() + '\n' + args.get_stackTrace());
}
</script>
UploadCtl solves this.

Resources