Export a single Google Sheet to CSV File - google-apps-script

I have a sheet named "IMS Import" and I am trying to export the range A3:E to a CSV file by a Google Apps script which will be triggered by a button. The length of the range to be exported changes from week to week so I only want to capture the last populated row. I have the following script but I get a Google error "403. That’s an error. We're sorry, but you do not have access to this page. That’s all we know.":
function onOpen() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var csvMenuEntries = [{name: "Download IMS Import File", functionName: "saveAsCSV"}];
ss.addMenu("Creating a Timetable", csvMenuEntries);
};
function saveAsCSV() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName('IMS Import');
// create a folder from the name of the spreadsheet
var folder = DriveApp.createFolder(ss.getName().toLowerCase().replace(/ /g,'_') + '_csv_' + new Date().getTime());
// append ".csv" extension to the sheet name
fileName = sheet.getName() + ".csv";
// convert all available sheet data to csv format
var csvFile = convertRangeToCsvFile_(fileName, sheet);
// create a file in the Docs List with the given name and the csv data
var file = folder.createFile(fileName, csvFile);
//File downlaod
var downloadURL = file.getDownloadUrl().slice(0, -8);
showurl(downloadURL);
}
function showurl(downloadURL) {
//Change what the download button says here
var link = HtmlService.createHtmlOutput('Click here to download');
SpreadsheetApp.getUi().showModalDialog(link, 'Your CSV file is ready!');
}
function convertRangeToCsvFile_(csvFileName, sheet) {
// get available data range in the spreadsheet
var activeRange = sheet.getDataRange();
try {
var data = activeRange.getValues();
var csvFile = undefined;
// loop through the data in the range and build a string with the csv data
if (data.length > 1) {
var csv = "";
for (var row = 2; row < data.length; row++) {
for (var col = 0; col < data[row].length; col++) {
if (data[row][col].toString().indexOf(",") != -1) {
data[row][col] = "\"" + data[row][col] + "\"";
}
}
// join each row's columns
// add a carriage return to end of each row, except for the last one
if (row < data.length-1) {
csv += data[row].join(",") + "\r\n";
}
else {
csv += data[row];
}
}
csvFile = csv;
}
return csvFile;
}
catch(err) {
Logger.log(err);
Browser.msgBox(err);
}
}
I get the error at this point in the script:
SpreadsheetApp.getUi().showModalDialog(link, 'Your CSV file is ready!');
I am hoping someone can help me to get a functioning script so that it creates a CSV from A3 to the last populated row.

If you only want the last row of the range change this
var activeRange = sheet.getDataRange();
to this:
var activeRange = sheet.getRange(sheet.getLastRow(),1,1,sheet.getLastColumn());
As far as page access goes I can't be sure. Perhaps you're logged into to two different accounts.

Related

Google Script CSV Downloader Project - How to specify Folder

I have been working on creating a script to allow employees in our shipping department to operate more efficiently. We use a barcode scanner to generate a CSV file - we use the following script to specify cells for the CSV; I'm looking to improve this so that the file is saved in a specific folder for easy sharing.
function onOpen() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var searchMenuEntries = [ {name: "Search in all files", functionName: "search"}];
var csvMenuEntries = [{name: "Save as CSV file", functionName: "saveAsCSV"},
{name: "Load from CSV file", functionName: "importFromCSV"}];
ss.addMenu("Search Google Drive", searchMenuEntries);
ss.addMenu("CSV", csvMenuEntries);
}
function saveAsCSV() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName('Primary Time');
// append ".csv" extension to the sheet name
// Prompts the user for the file name
var fileName = Browser.inputBox("Save CSV file as (e.g. myCSVFile):");
// Check that the file name entered wasn't empty
if (fileName.length !== 0) {
// Add the ".csv" extension to the file name
fileName = fileName + ".csv";
// Convert the range data to CSV format
var csvFile = convertRangeToCsvFile_(fileName);
// Create a file in Drive with the given name, the CSV data and MimeType (file type)
DriveApp.createFile(fileName, csvFile, MimeType.CSV);
else {
Browser.msgBox("Error: Please enter a CSV file name.");
}
}
function convertRangeToCsvFile_(csvFileName) {
// Get the selected range in the spreadsheet
var ws = SpreadsheetApp.getActiveSpreadsheet().getActiveSelection();
try {
var data = ws.getValues();
var csvFile = undefined;
// Loop through the data in the range and build a string with the CSV data
if (data.length > 1) {
var csv = "";
for (var row = 0; row < data.length; row++) {
for (var col = 0; col < data[row].length; col++) {
if (data[row][col].toString().indexOf(",") != -1) {
data[row][col] = "\"" + data[row][col] + "\"";
}
}
// Join each row's columns
// Add a carriage return to end of each row, except for the last one
if (row < data.length-1) {
csv += data[row].join(",") + "\r\n";
}
else {
csv += data[row];
}
}
csvFile = csv;
}
return csvFile;
}
catch(err) {
Logger.log(err);
Browser.msgBox(err);
}
}
I have 2 options for you:
Use File.moveTo(destination) to move your newly created file to your target folder.
Sample code:
function option1(){
var targetFolderId ='1QHe2zCebXBZxiplAfVZpO1dhxxxx';
var csvFile = "Sample Content";
var folder = DriveApp.getFolderById(targetFolderId);
var file = DriveApp.createFile("SampleFile1.csv", csvFile, MimeType.CSV);
file.moveTo(folder);
}
Use Advanced Drive Service to create a file within a specific parent folder
Sample Code:
function option2(){
var targetFolderId ='1QHe2zCebXBZxiplAfVZpO1dhxxxx';
var content = "Sample Content";
var resource = {
title: "SampleFile2.csv",
mimeType: "text/csv",
parents: [{id:targetFolderId}]
}
var blob = Utilities.newBlob(content,"text/csv");
var file = Drive.Files.insert(resource,blob);
Logger.log(file);
}
Output:

Modify Code - Convert File To CSV. Google Apps Script / Google sheets

The below code does as intended - except it ONLY copies the first 3 columns - and I need it to copy all the Data on the spreadsheet.I thought when the code says sheet.getDataRange(); that means all data but not in this case. Could I get a brief explanation of the issue rather than just the answer - love to know why 3 columns only are being selected.
function STCSV() {
var ss = SpreadsheetApp.openById("");
var sheets = ss.getSheets();
var sheet = sheets[3];
var formattedDate = Utilities.formatDate(new Date(), "GMT+10", "dd-MM-yyyy' '");
// append ".csv" extension to the sheet name
fileName = formattedDate + SpreadsheetApp.getActiveSpreadsheet().getName() + " ST CSV IMPORT " +
".csv";
var folder = DriveApp.getFolderById("");
// convert all available sheet data to csv format
var csvFile = convertRangeToCsvFile_(fileName, sheet);
// create a file in the Docs List with the given name and the csv data
var file = folder.createFile(fileName, csvFile);
}
function convertRangeToCsvFile_(csvFileName, sheet) {
// get available data range in the spreadsheet
var activeRange = sheet.getDataRange();
var data = activeRange.getValues();
var csvFile = undefined;
// loop through the data in the range and build a string with the csv data
if (data.length > 1) {
var csv = "";
for (var row = 0; row < data.length; row++) {
for (var col = 0; col < data[row].length; col++) {
if (data[row][col].toString().indexOf(",") != -1) {
data[row][col] = "\"" + data[row][col] + "\"";
}
}
// join each row's columns
// add a carriage return to end of each row, except for the last one
if (row < data.length-1) {
csv += data[row].join(",") + "\r\n";
}
else {
csv += data[row];
}
}
csvFile = csv;
}
return csvFile;
}
Appreciate any help. Thanks
The getDataRange() method returns a range corresponding to the dimensions in which data is present; therefore, the sheet.getDataRange() does return all the data from the sheet.
The reason only 3 columns are selected is because your sheet actually has only 3 columns.
Reference
Sheet Class Apps Script - getDataRange().

How to export google sheet as CSV by selected columns

I have a Google sheet want to export as CSV file. But there are 2 columns in the sheet I don't want to export.
For example, in the picturecolumn, I don't want to export column "N" and "P"
Here are the Apps Script code I wrote for export
function menu() {
var ui = SpreadsheetApp.getUi();
var menu = ui.createMenu('Menu');
var item = menu.addItem('PICC', 'picc');
var item2 = menu.addItem('Export to CSV', 'csv');
item.addToUi();
item2.addToUi()
};
function onOpen() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var csvMenuEntries = [{name: "Download Primary Time File", functionName: "saveAsCSV"}];
//ss.addMenu("Creating a Timetable", csvMenuEntries);
var ui = SpreadsheetApp.getUi();
var menu = ui.createMenu('Menu');
var item = menu.addItem('PICC', 'picc');
var item2 = menu.addItem('Export to CSV', 'csv');
item.addToUi();
item2.addToUi()
};
function saveAsCSV() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName("sheet1");
// create a folder from the name of the spreadsheet
var folder = DriveApp.createFolder(ss.getName().toLowerCase().replace(/ /g,'_') + '_csv_' + new Date().getTime());
// append ".csv" extension to the sheet name
fileName = sheet.getName() + ".csv";
// convert all available sheet data to csv format
var csvFile = convertRangeToCsvFile_(fileName, sheet);
// create a file in the Docs List with the given name and the csv data
var file = folder.createFile(fileName, csvFile);
//File downlaod
var downloadURL = file.getDownloadUrl().slice(0, -8);
showurl(downloadURL);
}
function showurl(downloadURL) {
var app = UiApp.createApplication().setHeight('60').setWidth('150');
//Change what the popup says here
app.setTitle("Your timetable CSV is ready!");
var panel = app.createPopupPanel()
//Change what the download button says here
var link = app.createAnchor('Click here to download', downloadURL);
panel.add(link);
app.add(panel);
var doc = SpreadsheetApp.getActive();
doc.show(app);
}
function convertRangeToCsvFile_(csvFileName, sheet) {
// get available data range in the spreadsheet
var activeRange = sheet.getDataRange();
try {
var data = activeRange.getValues();
var csvFile = undefined;
// loop through the data in the range and build a string with the csv data
if (data.length > 1) {
var csv = "";
for (var row = 1; row < data.length; row++) {
for (var col = 0; col < data[row].length; col++) {
if (data[row][col].toString().indexOf(",") != -1) {
data[row][col] = "\"" + data[row][col] + "\"";
}
}
// join each row's columns
// add a carriage return to end of each row, except for the last one
if (row < data.length-1) {
csv += data[row].join(",") + "\r\n";
}
else {
csv += data[row];
}
}
csvFile = csv;
}
return csvFile;
}
catch(err) {
Logger.log(err);
Browser.msgBox(err);
}
}
As you can see, I used for loop to export the rows and columns, how can I make change to let the two columns not showing in the export CSV
How about this modification?
Modification points :
Modify convertRangeToCsvFile_().
From data retrieved by getValues(), it removes the columns "N" and "P".
In order to reflect this, please modify as follows.
From :
var data = activeRange.getValues();
var csvFile = undefined;
To :
var data = activeRange.getValues();
data = data.map(function(e){return e.filter(function(_, i){return i != 13 && i != 15})}); // Added
var csvFile = undefined;
If I misunderstand your question, please tell me. I would like to modify it.

How to export csv from spreadsheett to drive folder

I have an spreadsheet with 4 sheets that I need in .CSV format. By now, I have a script that sends me the .csv files to my email, but I need to automacally save it into a google drive folder, do you have any ideas ?
This is my actual script:
function Csv(){
var ss = SpreadsheetApp.openById('spreadsheetID');
var url1 = "https://docs.google.com/spreadsheets/d/spreadsheetID/gviz/tq?tqx=out:csv&sheet=Sheet1";
var url2 = "https://docs.google.com/spreadsheets/d/spreadsheetID/gviz/tq?tqx=out:csv&sheet=Sheet2";
var url3 = "https://docs.google.com/spreadsheets/d/spreadsheetID/gviz/tq?tqx=out:csv&sheet=Sheet3";
var url4 = "https://docs.google.com/spreadsheets/d/spreadsheetID/gviz/tq?tqx=out:csv&sheet=Sheet4";
var params = {
method : "get",
headers : {"Authorization": "Bearer " + ScriptApp.getOAuthToken()},
muteHttpExceptions: true
};
var blob1 = UrlFetchApp.fetch(url1, params).getBlob();
blob1.setName("File1" +".csv");
var blob2 = UrlFetchApp.fetch(url2, params).getBlob();
blob2.setName("File2" +".csv");
var blob3 = UrlFetchApp.fetch(url3, params).getBlob();
blob3.setName("File3" +".csv");
var blob4 = UrlFetchApp.fetch(url4, params).getBlob();
blob4.setName("File4" +".csv");
MailApp.sendEmail("myemail#gmail.com", "Subject", "Body", {attachments: [blob1,blob2,blob3,blob4]});
}
Thanks!
you can check out the below script. Hope it will help you to manage your sheets as you expected.
/*
* script to export data in all sheets in the current spreadsheet as individual csv files
* files will be named according to the name of the sheet
* author: Shotez
*/
function onOpen() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var csvMenuEntries = [{name: "export as csv files", functionName: "saveAsCSV"}];
ss.addMenu("csv", csvMenuEntries);
};
function saveAsCSV() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheets = ss.getSheets();
// create a folder from the name of the spreadsheet
var folder = DriveApp.createFolder(ss.getName().toLowerCase().replace(/ /g,'_') + '_csv_' + new Date().getTime());
for (var i = 0 ; i < sheets.length ; i++) {
var sheet = sheets[i];
// append ".csv" extension to the sheet name
fileName = sheet.getName() + ".csv";
// convert all available sheet data to csv format
var csvFile = convertRangeToCsvFile_(fileName, sheet);
// create a file in the Docs List with the given name and the csv data
folder.createFile(fileName, csvFile);
}
Browser.msgBox('Files are waiting in a folder named ' + folder.getName());
}
function convertRangeToCsvFile_(csvFileName, sheet) {
// get available data range in the spreadsheet
var activeRange = sheet.getDataRange();
try {
var data = activeRange.getValues();
var csvFile = undefined;
// loop through the data in the range and build a string with the csv data
if (data.length > 1) {
var csv = "";
for (var row = 0; row < data.length; row++) {
for (var col = 0; col < data[row].length; col++) {
if (data[row][col].toString().indexOf(",") != -1) {
data[row][col] = "\"" + data[row][col] + "\"";
}
}
// join each row's columns
// add a carriage return to end of each row, except for the last one
if (row < data.length-1) {
csv += data[row].join(",") + "\r\n";
}
else {
csv += data[row];
}
}
csvFile = csv;
}
return csvFile;
}
catch(err) {
Logger.log(err);
Browser.msgBox(err);
}
}
After running the script just check your google drive for the folder which is containing the .csv files.

Google Data API Query

I use the Query https://www.googleapis.com/drive/v3/files/FileID/export?mimeType=text/tab-separated-values to download Google Sheets. My sheet has different tabs in it. Is there a way that I can download all the tabs in the sheet or a particular sheet with the name? Thanks in advance.
Based from this link, you can download a specific sheet using gID. Each sheet has a gID and you can find the gID of specific sheet in the URL of spreadsheet. You can use this link to download specific sheet https://docs.google.com/spreadsheets/d/<KEY>/export?format=xlsx&gid=<GID>.
Example:
https://docs.google.com/spreadsheets/d/1D5vzPaOJOx402RAEF41235qQTOs28_M51ee5glzPzj0/export?format=xlsx&gid=1990092150
KEY is the unique ID of spreadsheet.
You may also refer with this thread on how to export sheets in a spreadsheet to csv in Google Apps using Google Apps Script.
Couldn't find any built in way to do it so I wrote a script to use in Google Sheets
Just paste it in script editor and run
function onOpen() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var csvMenuEntries = [{name: "export as csv files", functionName: "saveAsCSV"}];
ss.addMenu("csv", csvMenuEntries);
};
function saveAsCSV() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheets = ss.getSheets();
// create a folder from the name of the spreadsheet
var folder = DocsList.createFolder(ss.getName().toLowerCase().replace(/ /g,'_') +'_csv_' + new Date().getTime());
for (var i = 0 ; i < sheets.length ; i++) {
var sheet = sheets[i];
// append ".csv" extension to the sheet name
fileName = sheet.getName() + ".csv";
// convert all available sheet data to csv format
var csvFile = convertRangeToCsvFile_(fileName, sheet);
// create a file in the Docs List with the given name and the csv data
folder.createFile(fileName, csvFile);
}
Browser.msgBox('Files are waitig in a folder named ' + folder.getName());
}
function convertRangeToCsvFile_(csvFileName, sheet) {
// get available data range in the spreadsheet
var activeRange = sheet.getDataRange();
try {
var data = activeRange.getValues();
var csvFile = undefined;
// loop through the data in the range and build a string with the csv data
if (data.length > 1) {
var csv = "";
for (var row = 0; row < data.length; row++) {
for (var col = 0; col < data[row].length; col++) {
if (data[row][col].toString().indexOf(",") != -1) {
data[row][col] = "\"" + data[row][col] + "\"";
}
}
// join each row's columns
// add a carriage return to end of each row, except for the last one
if (row < data.length-1) {
csv += data[row].join(",") + "\r\n";
}
else {
csv += data[row];
}
}
csvFile = csv;
}
return csvFile;
}
catch(err) {
Logger.log(err);
Browser.msgBox(err);
}
}