google script import csv from ftp o google drive - csv

i'm using a script to import a csv from a link but there is a way to adapt it for import from an ftp link or google drive file?
thank's
this is my script
function myFunction3() {
// 1. Set the required columns as the column number.
const requiredColumns = [1, 5, 20]; // Please set the required columns. These values are from your question.
// 2. Retrieve CSV data from an URL.
const url = "https://www.stanem.it/csv/InnovaCSV.csv";
const res = UrlFetchApp.fetch(url);
// 3. Convert CSV data to Spreadsheet.
const id = Drive.Files.insert({mimeType: MimeType.GOOGLE_SHEETS, title: "tempSpreadsheet"}, res.getBlob()).id;
// 4. Delete the columns except for the required columns.
const ss = SpreadsheetApp.openById(id);
const sheet = ss.getSheets()[0];
const maxColumn = sheet.getMaxColumns();
const requests = [];
for (let i = 1; i <= maxColumn; i++) {
if (!requiredColumns.includes(i)) {
requests.push({deleteDimension: {range: {sheetId: sheet.getSheetId(), dimension: "COLUMNS", startIndex: i - 1, endIndex: i}}});
}
}
Sheets.Spreadsheets.batchUpdate({requests: requests.reverse()}, id);
// 5. Copy the values of modified CSV data to a sheet in the active Spreadsheet.
const destinationSheetName = "Sheet1"; // Please set the destilnation sheet name in the active Spreadsheet.
const dstss = SpreadsheetApp.getActiveSpreadsheet();
const values = Sheets.Spreadsheets.Values.get(id, sheet.getSheetName()).values;
Sheets.Spreadsheets.Values.update({values: values}, dstss.getId(), destinationSheetName, {valueInputOption: "USER_ENTERED"});
// 6. Remove the temporat Spreadsheet.
DriveApp.getFileById(id).setTrashed(true);
}

Issue and workaround:
Unfortunately, in the current stage, the file cannot be retrieved from FTP using UrlFetchApp. So in your situation, how about retrieving the file from Google Drive? When the CSV file is retrieved from Google Drive, the modified script is as follows.
Modified script:
Please modify your script as follows. In this modified script, it supposes that the CSV file is put in your Google Drive.
From:
// 2. Retrieve CSV data from an URL.
const url = "https://www.stanem.it/csv/InnovaCSV.csv";
const res = UrlFetchApp.fetch(url);
// 3. Convert CSV data to Spreadsheet.
const id = Drive.Files.insert({mimeType: MimeType.GOOGLE_SHEETS, title: "tempSpreadsheet"}, res.getBlob()).id;
To:
// 3. Convert CSV data to Spreadsheet.
const fileId = "### fileId of CSV file on Google Drive ###"; // Please set the file ID of CSV file.
const id = Drive.Files.copy({mimeType: MimeType.GOOGLE_SHEETS, title: "tempSpreadsheet"}, fileId).id;
In this case, the CSV file can be converted with Drive.Files.copy.
Reference:
Files: copy

Related

Appscript - Multiple excel files conversion to gsheets and updating data without creating a new gsheet

sorry for bad english.
I have a folder with multiple excel files that I need in Gsheets format. I also need to update the data (converting the same file again and again), but the output must remain the same. (the GSHEET id for example).
I actually have this code but this works for 1 xlsx file.
function importData() {
var xlsxName = "QM12.XLSX"; //Change source file name accordingly
var convertID = convert(xlsxName).toString();
var xLSX = SpreadsheetApp.openById(convertID).getSheetByName("Sheet1"); // SaĆ­da
var ss = SpreadsheetApp.openById("15GvvEYH8zuHI6cmhNxHqBWywrqQU32t6kaAbAJcclBk").getSheetByName("QM12 CGH"); // entrada
var lastColumn = xLSX.getLastColumn();
var lastRow = xLSX.getLastRow();
ss.getRange(1, 1, lastRow, lastColumn).setValues(xLSX.getDataRange().getValues()); //Sets values from converted xlsx data to output sheet
//DriveApp.getFileById(convertID).setTrashed(true); //deletes temporary file
Drive.Files.remove(convertID)
}
function convert(xlsxName) {
var files = DriveApp.getFilesByName("xlsxName");
var excelFile = (files.hasNext()) ? files.next() : null;
var blob = excelFile.getBlob();
var config = {
title: "[Converted File] " + excelFile.getName(), //sets the title of the converted file
parents: [{ id: excelFile.getParents().next().getId() }],
mimeType: MimeType.GOOGLE_SHEETS
};
var spreadsheet = Drive.Files.insert(config, blob);
return (spreadsheet.id); //Returns the ID of the converted file
}
I would like to use this for multiple xlsx.
Basically I need to:
-> FolderA with xlsx files. FolderB as the destination for the gsheets converted files.
-> If there is no gsheet with the same name as the xlsx file, it should create a new gsheet but if there it is a gsheet with the same name, just update the data on it.
I've been searching but couldn't find anything close to this.
Anyway, thank you in advance.

google drive file link automatically change format in spreadsheet

I am implementing some download and upload file functionality in google drive through google app-script storing the drive link in google sheet. upload works fine but after some time the link is turn into some kind of hyperlink as like below
so that's why I am no longer able to get the link simply writting .getDisplayValue()
const ss = SpreadSheetApp.getActive().getActiveSheet() let url = ss.getRange().getDisplayValue()
Any Suggestion ...?
I tried Adding .getRichTextValue().getLinkUrl() But It also does not worked as It is not a HyperLink
Issue and workaround:
From your sample image, in your situation, the link of the file is changed to the smart chip. In the current stage, unfortunately, there are no methods for managing the smart chips on a Spreadsheet. So, in this case, it is required to use a workaround. The workaround is as follows.
Convert Google Spreadsheet to XLSX data.
By this, the file links of the smart chip are converted to simple strings and hyperlinks.
Convert XLSX data to Google Spreadsheet.
Retrieve the hyperlinks from the cells.
This method is from How to get in Apps Script the value of a dropdown in a Google Doc? and https://tanaikech.github.io/2022/10/27/retrieving-values-of-calendar-events-of-smart-chips-on-google-document-using-google-apps-script/ .
When this flow is reflected in a sample script, how about the following sample script?
Sample script:
Please copy and paste the following script to the script editor of Google Spreadsheet and set range that you want to retrieve the hyperlinks as A1Notation. In this sample, Drive API is used. So, please enable Drive API at Advanced Google services.
function myFunction() {
const range = "Sheet1!A1:A10"; // Please set the range you want to retrieve the hyperlinks.
const ss = SpreadsheetApp.getActiveSpreadsheet();
const url = "https://docs.google.com/spreadsheets/export?exportFormat=xlsx&id=" + ss.getId();
const blob = UrlFetchApp.fetch(url, { headers: { authorization: "Bearer " + ScriptApp.getOAuthToken() } }).getBlob();
const tempId = Drive.Files.insert({ mimeType: MimeType.GOOGLE_SHEETS, title: "temp" }, blob).id;
const tempFile = DriveApp.getFileById(tempId);
const tempSS = SpreadsheetApp.open(tempFile);
const res = tempSS.getRange(range).getRichTextValues().map((r, i) => r.map((c, j) => ({ value: c.getText(), url: c.getLinkUrl() || "", range: { row: i + 1, column: j + 1 } })));
tempFile.setTrashed(true);
console.log(res);
}
Testing:
When this script is run, the following result is obtained.
[
[{"value":"sample value","url":"https://drive.google.com/file/d/###/view?usp=share_link","range":{"row":1,"column":1}}],
,
,
,
]
Note:
As another approach, in your showing sample image, if you want to convert the file links of the smart chip to the normal value with the hyperlink, how about the following sample script? In this sample, range is overwritten by the normal values with the hyperlinks obtained by converting from XLSX data.
function myFunction2() {
const range = "Sheet1!A1:A10"; // Please set the range you want to retrieve the hyperlinks.
const ss = SpreadsheetApp.getActiveSpreadsheet();
const url = "https://docs.google.com/spreadsheets/export?exportFormat=xlsx&id=" + ss.getId();
const blob = UrlFetchApp.fetch(url, { headers: { authorization: "Bearer " + ScriptApp.getOAuthToken() } }).getBlob();
const tempId = Drive.Files.insert({ mimeType: MimeType.GOOGLE_SHEETS, title: "temp" }, blob).id;
const tempFile = DriveApp.getFileById(tempId);
const tempSS = SpreadsheetApp.open(tempFile);
const r = tempSS.getRange(range);
const tempSheet = r.getSheet().copyTo(ss);
tempSheet.getRange(r.getA1Notation()).copyTo(ss.getRange(range));
ss.deleteSheet(tempSheet);
tempFile.setTrashed(true);
}
References:
Retrieving Values of Calendar Events of Smart Chips on Google Document using Google Apps Script (Author: me)
Related thread
How to get in Apps Script the value of a dropdown in a Google Doc?

Saving a Google Sheet as epub

I have a Google Sheet with content in say Col 1. One sentence in each row. I am looking for a script which can save the Col 1 as 'epub' with each sentence (in row) as a new page.
I believe your current situation and your goal as follows.
In your Spreadsheet, there are the sentences in each row of the column "A".
You want to retrieve a value from a cell of column "A" and convert it as a file of EPUB on your Google Drive.
You want to achieve this using Google Apps Script.
In this case, I would like to propose the following flow.
Retrieve the values from the column "A" of the Spreadsheet.
Create Google Document as the temporal file.
Copy the values to Google Document.
Export Google Document as EPUB of application/epub+zip and save it as a file on Google Drive.
Remove the temporal file.
When above flow is reflected to the script, it becomes as follows.
Sample script:
Please copy and paste the following script to the script editor of Google Spreadsheet you want to use. And, please run myFunction. By this, the values are retrieved from the cells "A1:A" and create EPUB files using the values of each row.
function myFunction() {
const sheetName = "Sheet1"; // Please set the sheet name.
const folderId = "root"; // Please set the folder ID you want to export the EPUB files. In the case of "root", the files are created to the root folder.
// 1. Retrieve the values from the column "A" of the Spreadsheet.
const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(sheetName);
const startRow = 1;
const endRow = sheet.getLastRow();
const values = sheet.getRange(`A${startRow}:A${endRow}`).getDisplayValues();
// 2. Create Google Document as the temporal file.
const tempDoc = DocumentApp.create("temp");
const id = tempDoc.getId();
const url = "https://docs.google.com/feeds/download/documents/export/Export?exportFormat=epub&id=" + id;
const params = {headers: {authorization: `Bearer ${ScriptApp.getOAuthToken()}`}};
const folder = DriveApp.getFolderById(folderId || "root");
const ids = values.map(([a], i) => {
// 3. Copy the values to Google Document.
const filename = `rowNumber${i + 1}`;
const doc = DocumentApp.openById(id).setName(filename);
doc.getBody().clear().appendParagraph(a);
doc.saveAndClose();
// 4. Export Google Document as EPUB of `application/epub+zip` and save it as a file on Google Drive.
const blob = UrlFetchApp.fetch(url, params).getBlob().setName(`${filename}.epub`);
return folder.createFile(blob).getId();
});
console.log(ids); // Here, you can see the file IDs of the created EPUB files at the log.
// 5. Remove the temporal file.
DriveApp.getFileById(id).setTrashed(true);
}
In this sample script, the filename is rowNumber${i + 1}. So, the created filename is like rowNumber1.epub, rowNumber2.epub. If you want to change this, please modify above script.
The endpoint of const url = "https://docs.google.com/feeds/download/documents/export/Export?exportFormat=epub&id=" + id; is from exportLinks of the method of "Files: get" of Drive API. Ref
Note:
In this case, when a lot of rows are existing in your Spreadsheet, the process time might be over the maximum execution time of 6 minutes. Please be careful this. If the process time is over the maximum execution time, please modify the values of startRow and endRow.
If an error related to Drive API occurs, please enable Drive API at Advanced Google servicves.
If you want to convert the values of the column "A" as one EPUB file, you can also use the following script.
function myFunction2() {
const sheetName = "Sheet1";
const folderId = "root"; // Please set the folder ID you want to export the EPUB files. In the case of "root", the files are created to the root folder.
const filename = `sampleFile`; // Please set the output filename.
// 1. Retrieve the values from the column "A" of the Spreadsheet.
const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(sheetName);
const startRow = 1;
const endRow = sheet.getLastRow();
const values = sheet.getRange(`A${startRow}:A${endRow}`).getDisplayValues();
// 2. Create Google Document as the temporal file.
const tempDoc = DocumentApp.create(filename);
// 3. Copy the values to Google Document.
tempDoc.getBody().clear().appendParagraph(values.flat().join("\n"));
tempDoc.saveAndClose();
const id = tempDoc.getId();
// 4. Export Google Document as EPUB of `application/epub+zip` and save it as a file on Google Drive.
const url = "https://docs.google.com/feeds/download/documents/export/Export?exportFormat=epub&id=" + id;
const params = {headers: {authorization: `Bearer ${ScriptApp.getOAuthToken()}`}};
const folder = DriveApp.getFolderById(folderId || "root");
const blob = UrlFetchApp.fetch(url, params).getBlob().setName(`${filename}.epub`);
const createdFileId = folder.createFile(blob).getId();
console.log(createdFileId); // Here, you can see the file ID of the created EPUB file at the log.
// 5. Remove the temporal file.
DriveApp.getFileById(id).setTrashed(true);
}
References:
Spreadsheet Service
Class UrlFetchApp
Drive Service
You need to enable Advanced Drive API
function makeEPUB() {
const ss = SpreadsheetApp.getActive();
const sh = ss.getSheetByName('Sheet1');
const rg = sh.getRange(1,1,sh.getLastRow(),1);
const vs = rg.getDisplayValues().flat();//get rows
const document = DocumentApp.create('mydoc');//creat doc
let body = document.getBody();
vs.forEach(s =>{body.appendParagraph(s);body.appendPageBreak();});//append sentences and page breaks
document.saveAndClose();
let exportLink = Drive.Files.get(document.getId()).exportLinks["application/epub+zip"];
let response = UrlFetchApp.fetch(exportLink, {headers: {Authorization: "Bearer " + ScriptApp.getOAuthToken()}});
let file = DriveApp.createFile(response.getBlob());
file.setName(document.getName() + ".epub");
}
Mostly Copied from Amit Agarwal
Don't know if it works. Have no way that I know of to test it.

How to get the excel data from a url into google sheets using google apps script?

Follow up question to this question - How to fix invalid url error using UrlfetchApp?
This is the url to download the excel data from :
https://corvo-reports.s3.amazonaws.com/TRESAH/2020-08-16/45d32ff8-bccd-4c16-8916-6c19c28f2f3c%402020-08-16%2017%3A30%3A00.0/Sponsored%20Products%20Search%20term%20report%20-%20Scotch%20Brite.xlsx?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Date=20200816T174421Z&X-Amz-SignedHeaders=host&X-Amz-Expires=604799&X-Amz-Credential=AKIAY2R3XYZC46Q4PK5E%2F20200816%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Signature=726ca9b98cd766966b756bc708b780377ff62e5bbfec8c09b97294bfb0cd63f7
This is a report that comes in on a schedule and I need to take this data and put it in a google sheet. It's a large report so I need to clear all existing data on the sheet and replace it with the new data. I've been struggling with this and could use some help.
This is the code I have right now:
// Globals
const DataFolderId = 'XXXXX'
const label = 'YYYYY'
/*
* Download the excel file and put it in a google sheet
*
* #return : Hopefully, it adds the data to the google sheet
*/
function excelToSheets() {
// Get the link to the excel file
const url = getDownloadLink(label)
const excelFile = UrlFetchApp.fetch(url).getBlob()
const filename = 'Report: ' + Utilities.formatDate(new Date(), "IST", "yyyy-MM-dd")
// Download the file to google drive
const fileInfo = {
title: filename,
mimeType: "MICROSOFT_EXCEL",
"parents": [{'id': DataFolderId}],
}
// Currently, this adds a zip file to google drive, instead of an excel/google sheet file
const file = Drive.Files.insert(fileInfo, excelFile, {convert: true})
// Assign the id of the downloaded file to a variable
const id = file.id
// Put data in a spreadsheet - this does not work
spreadsheet(id)
}
/*
* Helper function to put data in the google sheet
*/
function spreadsheet (id) {
const source = SpreadsheetApp.openById(id)
const destination = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('data')
destination.clearContents()
source.copyTo(destination)
}
/*
* Get the download link from the gmail label
*
* #return : The link from the most recent email
*/
function getDownloadLink (label) {
const lookupLabel = GmailApp.getUserLabelByName(label)
const thread = lookupLabel.getThreads()[0]
const message = thread.getMessages()[0]
const data = message.getPlainBody()
const regExp = new RegExp('[\n\r].*Download:\\s*([^\n\r]*)')
const link = regExp.exec(data)[1].trim()
return link
}
Currently, the excelToSheets() function takes the excel file from the link and adds a zip file in google drive. I'm not sure what I'm doing wrong here - I've just been trying to follow a bunch of tutorials on the topic online.
Your help would be greatly appreciated!
When you fetch a blob from a download link it might not contain the correct mimeType information
Workaround
Perform the request in two steps
step save the file as Excel on your Drive
Convert the Excel file to Google Sheets
Sample
function excelToSheets() {
const url = getDownloadLink(label);
const excelFile = UrlFetchApp.fetch(url).getBlob();
const filename = 'Report: ' + Utilities.formatDate(new Date(), "IST", "yyyy-MM-dd")
const fileInfo = {
title: filename,
mimeType: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
parents: [{id: DataFolderId}],
}
const file = Drive.Files.insert(fileInfo, excelFile)
const id = file.id;
const excelFile2 = DriveApp.getFileById(id).getBlob();
const fileInfo2 = {
title: filename,
mimeType: MimeType.GOOGLE_SHEETS,
parents: [{id: DataFolderId}],
}
const file2 = Drive.Files.insert(fileInfo2, excelFile2);
const id2 = file2.id;
spreadsheet(id2)
}

Google Apps Script how to export specific sheet as csv format

In MIT Inventor II, I use web component to get SpreadsheetID and SheetID through doGet() of google apps script. After I get the information I use another web component to set url as below to get csv-formatted file from specific sheet. My question is how to make GAS to get SpreadsheetID & SheetID and then export csv file at one time, so that I don't have to use 2 web components in Inventor side?
GAS codes is as below. This is to "return" spreadsheetID and sheetID.
function doGet(e) {
filename = e.parameter.account;
fileList = DriveApp.getFilesByName(filename);
while (fileList.hasNext()) {
var fileID = fileList.next().getId()
}
var file = SpreadsheetApp.openById(fileID) ;
sheet = file.getSheetByName("Message").activate()
var messageID = sheet.getSheetId();
return ContentService.createTextOutput([fileID,messageID]);
After I got SpreadsheetID & SheetID, I have to set 2nd web component from Inventor side to get csv file, see below.
https://docs.google.com/spreadsheets/d/xxxxSpreadsheetIDxxxx/edit#gid=sheetID
Here is how you can create a csv file of a selected sheet in google drive:
function sheetToCsv()
{
var ssID = SpreadsheetApp.getActiveSpreadsheet().getId();
var sheet_Name = "Sheet1"
var requestData = {"method": "GET", "headers":{"Authorization":"Bearer "+ScriptApp.getOAuthToken()}};
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(sheet_Name)
var sheetNameId = sheet.getSheetId().toString();
params= ssID+"/export?gid="+sheetNameId +"&format=csv"
var url = "https://docs.google.com/spreadsheets/d/"+ params
var result = UrlFetchApp.fetch(url, requestData);
var resource = {
title: sheet_Name+".csv",
mimeType: "application/vnd.csv"
}
var fileJson = Drive.Files.insert(resource,result)
}
The code creates a csv file that has the content of Sheet1.
In order to run the aforementioned function you need to activate the Advanced Drive Service.
Explanation:
Go to Resources => Advanced Google Services => activate Drive API
Another option is to create the csv file to a particular folder, then you need to replace the resource part of the code with this:
var folder_id ='id';
var resource = {
title: sheet_Name+".csv",
mimeType: "application/vnd.csv",
parents: [{ id: folder_id }]
}
My application was how to save a tab of a Google sheets spreadsheet to a CSV file in a shared drive. Doing it to the default "My Drive" was relatively easy based on Marios' answer in this post, but I struggled with this for a shared drive while until I came across ziganotschka's example which solved my problem.
Code for my simple App Script is:
function sheetToCsv()
{
var ssID = SpreadsheetApp.getActiveSpreadsheet().getId();
var sheet_Name = "[Your sheet name goes here]";
var requestData = {"method": "GET", "headers":{"Authorization":"Bearer "+ScriptApp.getOAuthToken()}};
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(sheet_Name);
var sheetNameId = sheet.getSheetId().toString();
params= ssID+"/export?gid="+sheetNameId +"&format=csv";
var url = "https://docs.google.com/spreadsheets/d/"+ params;
var result = UrlFetchApp.fetch(url, requestData);
var resource = {
title: sheet_Name+".csv",
mimeType: "MimeType.CSV",
parents:[{
"id": "[Your Shared Drive Folder ID goes here]"
}]
}
var optionalArgs={supportsAllDrives: true};
var fileJson = Drive.Files.insert(resource, result, optionalArgs);
}
I added a timestamp to the file name and a trigger to cause the script to execute daily via a timer.