Google sheet create pdf from another sheet ID - google-apps-script

Hi how could this code be modified to create a PDF file from another worksheet instead of the active open worksheet.
Here's part of the code I'm using and it works but I would like to create a PDF from another worksheet ID
Thanks
var source = SpreadsheetApp.getActiveSpreadsheet();
var spreadsheet = spreadsheetId ? SpreadsheetApp.openById(spreadsheetId) : SpreadsheetApp.getActiveSpreadsheet();
var spreadsheetId = SpreadsheetApp.getActiveSpreadsheet().getId();
var ticketnum = source.getSheetByName("Print Page").getRange('X1').getValue();
var body = 'Attached is your copy'
var Client = source.getSheetByName("Print Page").getRange('O5').getValue();
var Cons = source.getSheetByName("Print Page").getRange('T4').getValue() ;
var jobN = source.getSheetByName("Ticket PDF").getRange('G9').getValue() ;
var mailTo = source.getSheetByName("Print Page").getRange('Z1').getValue() ;
var folder = DriveApp.getFoldersByName('Ticket').next();
var token = ScriptApp.getOAuthToken();
var ssID = spreadsheetId;
var url = "https://docs.google.com/spreadsheets/d/"+ssID+"/export"+
"?format=pdf&"+
'&portrait=true' +
'&fzr=true' +
'&fitw=True' +
//'&scale=4' +
'&top_margin=0.25' +
'&bottom_margin=0.25' +
'&left_margin=0.25' +
'&right_margin=0.25' +
'&horizontal_alignment=CENTER' +
'&gridlines=false'+
'&sheetnames=False';
var response = UrlFetchApp.fetch(url, {
headers: {
'Authorization': 'Bearer ' + token
}
});
var pdf = response.getBlob().setName( Client + " " + ticketnum + " # " + jobN + " " + '.PDF');
folder.createFile(pdf)

How about this modification?
In this modification, it supposes that another worksheet ID in your question is the other sheet in the active Spreadsheet.
Modified script:
In order to export the specific sheet in the Spreadsheet as PDF file, you can use the query parameter of gid as follows.
From:
"?format=pdf&"+
To:
"?format=pdf&gid=" + spreadsheet.getSheetByName("###").getSheetId() + "&" +
In this case, please set the sheet name you want to export as a PDF to ###.
Note:
If you want to export several sheets in the Spreadsheet as a PDF file, this thread might be useful.
If I misunderstood your question and this was not the direction you want, I apologize.
Added
You want to export the specific Spreadsheet, which is not the active Spreadsheet, as a PDF file.
In your script, please give spreadsheetId. When spreadsheetId is not given the active Spreadsheet by var spreadsheet = spreadsheetId ? SpreadsheetApp.openById(spreadsheetId) : SpreadsheetApp.getActiveSpreadsheet();. And spreadsheetId is retrieved from the active Spreadsheet. So please modify as follows.
From:
var source = SpreadsheetApp.getActiveSpreadsheet();
var spreadsheet = spreadsheetId ? SpreadsheetApp.openById(spreadsheetId) : SpreadsheetApp.getActiveSpreadsheet();
var spreadsheetId = SpreadsheetApp.getActiveSpreadsheet().getId();
To:
var spreadsheetId = "###"; // Please set the Spreadsheet ID.
var source = SpreadsheetApp.getActiveSpreadsheet();
var spreadsheet = SpreadsheetApp.openById(spreadsheetId);
var spreadsheetId = spreadsheet.getId();
If you want to export the specific sheet in the Spreadsheet, please use the query parameter gid. And if you want to export several sheets in the Spreadsheet, this thread might be useful.

Related

Server error when trying to save range of Google sheet cells to PDF in Google Apps Script

I have the following code, running in Google Apps Script. The code attempts to take a range of a spreadsheet and save it as a PDF:
var range = sheet.getRange("A586:K" + lastRow);
// Get the currently active spreadsheet URL (link)
var ss = SpreadsheetApp.getActiveSpreadsheet();
var pdfBlob = DriveApp.getFileById(ss.getId()).getAs('application/pdf');
pdfBlob.setName('test.pdf');
// Save the PDF to your Google Drive.
var folder = DriveApp.getFolderById("1EJIzvW-oOnFfFOopiAAsudhbHsF5FGKz");
var file = folder.createFile(pdfBlob);
When I run the code, it runs for a while, then gives me the error:
We're sorry, a server error occurred. Please wait a bit and try again
Any tips on what might be going on?
I believe your goal is as follows.
You want to export the specific range of a sheet as a PDF format using Google Apps Script.
In your script, range is not used. And, the whole sheet is exported. In this case, I think that your goal can be achieved by the query parameter. Ref When this is reflected in your script, how about the following modification?
Modified script:
function myFunction() {
const sheetName = "Sheet1"; // Please set your sheet name.
const folderId = "###"; // Please set your folder ID.
const ss = SpreadsheetApp.getActiveSpreadsheet();
const sheet = ss.getSheetByName(sheetName);
const range = sheet.getRange("A586:K" + sheet.getLastRow());
const startRow = range.getRow() - 1;
const endRow = startRow + range.getNumRows();
const startCol = range.getColumn() - 1;
const endCol = startCol + range.getNumColumns();
const url = `https://docs.google.com/spreadsheets/d/${ss.getId()}/export?format=pdf&gid=${sheet.getSheetId()}&r1=${startRow}&c1=${startCol}&r2=${endRow}&c2=${endCol}`;
const res = UrlFetchApp.fetch(url, { headers: { authorization: "Bearer " + ScriptApp.getOAuthToken() } });
const folder = DriveApp.getFolderById(folderId);
folder.createFile(res.getBlob().setName("sample.pdf"));
}
References:
fetch(url, params)
Related thread.
How to adjust as custom size margins and paper size in script to save google spreadsheet in PDF?

download pdf from google sheet and

I found this code where I can download google sheet to pdf but I want to change it in order to chose another sheet then the active one and download the pdf once the code run without the box.
function PDF() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheetId = ss.getActiveSheet().getSheetId();
var url = "https://docs.google.com/a/mydomain.org/spreadsheets/d/" + ss.getId() + "/export?exportFormat=pdf&gid=" + sheetId + "&access_token=" + ScriptApp.getOAuthToken();
var str = '<input type="button" value="Download" onClick="location.href=\'' + url + '\'" >';
var html = HtmlService.createHtmlOutput(str);
SpreadsheetApp.getUi().showModalDialog(html, "Download_Report");
}
From What I meant is I want to run this code on a sheet other then the one I am currently using, for example, if you want to use sheetId of other sheet except for the active sheet, how about the following modification?
From:
var sheetId = ss.getActiveSheet().getSheetId();
To:
When you want to use the sheet name, please modify as follows.
var sheetId = ss.getSheetByName("Sheet2").getSheetId(); // Please set the sheet name like "Sheet2".
When you want to use the index of the sheet, please modify as follows. In this case, index = 1 is the 2nd sheet. So, the 1st sheet index is 0.
var index = 1; // Please set the index of the sheet you want to use.
var sheetId = ss.getSheets()[index].getSheetId();
Of cource, you can directly put the specific sheet ID you want to use.
References:
getSheetByName(name)
getSheets()

Script To Write Auto-Gen'd Google Doc URL To Spreadsheet

I have a Google Form that does two things upon hitting the Submit button. First, it dumps that data into a Spreadsheet, then it autofills a Google Doc Template with the info from the Form.
In my script to autofill the Google Doc, I've grabbed the URL for the Google Doc. But I need to write this URL into the last row of Column J in my Google Sheet. Correction: using the getActiveSheet functions are fine, I forgot this script is running from the (Active) Google Sheet (apologies!).
Can anyone assist with this? Here's a snippet of the script to get the URL:
function autoFillGoogleDocFromForm(e) {
//e.values is an array of form values
var TimeStamp = e.values[0];
var Technician = e.values[1];
var Vendor = e.values[2];
var xxx = e.values[3];
var yyy = e.values[4];
var SerialNumber = e.values[5];
var AssetTag = e.values[6];
var TicketNumber = e.values[7];
var HostName = e.values[8];
var DocumentLink = e.values[9];
var Return = e.values[10];
var Platform = e.values[11];
var Summary = e.values[12];
var URL = "";
//file is the template file, and you get it by ID
var file = DriveApp.getFileById('aaa');
//Put auto filled Google Doc into the appropriate Vendor Folder
//file.makeCopy will return a Google Drive file object
if (Vendor == "111") {
var folder = DriveApp.getFolderById('bbb')
var copy = file.makeCopy(TicketNumber + ' - ' + SerialNumber, folder);
}
if (Vendor == "222") {
var folder = DriveApp.getFolderById('ccc')
var copy = file.makeCopy(TicketNumber + ' - ' + SerialNumber, folder);
}
if (Vendor == "333") {
var folder = DriveApp.getFolderById('ddd')
var copy = file.makeCopy(TicketNumber + ' - ' + SerialNumber, folder);
}
//Once we've got the new file created, we need to open it as a document by using its ID
var doc = DocumentApp.openById(copy.getId());
//Get the url of the newly created Google Doc
var url = doc.getUrl();
//Script to write this URL into the Shared Google Sheet will go here
//Since everything we need to change is in the body, we need to get that
var body = doc.getBody();
//Then we call all of our replaceText methods
body.replaceText('{{EmailAddress}}', Technician);
body.replaceText('{{TicketNumber}}', TicketNumber);
body.replaceText('{{HostName}}', HostName);
body.replaceText('{{SerialNumber}}', SerialNumber);
body.replaceText('{{AssetTag}}', AssetTag);
body.replaceText('{{Summary}}', Summary);
body.replaceText('{{Vendor}}', Vendor);
body.replaceText('{{URL}}', url);
//Lastly we save and close the document to persist our changes
doc.saveAndClose();
Thanks in advance!
From your following situation in your question,
Also this is a shared Google Sheet, so I can't use the getActiveSheet function, I'd need to reference the Google Sheet URL, I believe.
If you have the permission to write the values to the shared Google Spreadsheet, how about the following modification?
From:
var url = doc.getUrl();
//Script to write this URL into the Shared Google Sheet will go here
To:
var url = doc.getUrl();
//Script to write this URL into the Shared Google Sheet will go here
var sheet = SpreadsheetApp.openById("### Spreadsheet ID ###").getSheetByName("### sheet name ###");
sheet.appendRow([url]);
In this modification, please set the Spredsheet ID and sheet name. By this, the value of url is appended to the next row of the last row of the sheet in the Google Spreadsheet.
If you want to use the Spreadsheet URL instead of Spreadsheet ID, please modify openById("### Spreadsheet ID ###") to openByUrl("### Spreadsheet URL ###").
References:
openById(id)
openByUrl(url)
appendRow(rowContents)
Edit:
From the following replying,
That doesn't seem to work to insert the URL into the last row of column J unfortunately. It looks like this script can use the Active Sheet afterall, I'll edit the OP.
In this case, how about the following modification?
From:
var url = doc.getUrl();
//Script to write this URL into the Shared Google Sheet will go here
To:
var url = doc.getUrl();
//Script to write this URL into the Shared Google Sheet will go here
// var sheet = SpreadsheetApp.openById("### Spreadsheet ID ###").getSheetByName("### sheet name ###");
var sheet = SpreadsheetApp.getActiveSheet(); // or SpreadsheetApp.getActiveSpreadsheet().getSheetByName("sheetname")
sheet.getRange("J" + (sheet.getLastRow() + 1)).setValue(url);
Or
var url = doc.getUrl();
//Script to write this URL into the Shared Google Sheet will go here
// This is from https://stackoverflow.com/a/44563639/7108653
Object.prototype.get1stEmptyRowFromTop = function (columnNumber, offsetRow = 1) {
const range = this.getRange(offsetRow, columnNumber, 2);
const values = range.getDisplayValues();
if (values[0][0] && values[1][0]) {
return range.getNextDataCell(SpreadsheetApp.Direction.DOWN).getRow() + 1;
} else if (values[0][0] && !values[1][0]) {
return offsetRow + 1;
}
return offsetRow;
};
// var sheet = SpreadsheetApp.openById("### Spreadsheet ID ###").getSheetByName("### sheet name ###");
var sheet = SpreadsheetApp.getActiveSheet(); // or SpreadsheetApp.getActiveSpreadsheet().getSheetByName("sheetname")
sheet.getRange("J" + sheet.get1stEmptyRowFromTop(10)).setValue(url);
Suggestion:
If you need to write the URL value into the last row of Column J in a shared Google Spreadsheet file, you can try this sample below:
function sample() {
var ss = SpreadsheetApp.openByUrl('https://docs.google.com/spreadsheets/d/SHEET_ID_IS_HERE/edit#gid=0');
var sheet = ss.getSheets()[0]; // access first sheet
var activeSheet = ss.setActiveSheet(sheet);
//Sample setValue() action to the shared sheet file
activeSheet.getRange("A1").setValue("URL");
}
NOTE: You would need to have an editor permission on the Shared Google Sheet file that you're accessing
References:
openByUrl(url)
getSheets()
setActiveSheet(sheet)
Here's the code that ended up working for me.
//Get the url of the newly created Google Doc
var url = doc.getUrl();
// var sheet = SpreadsheetApp.openById("### Spreadsheet ID ###").getSheetByName("### sheet name ###");
var sheet = SpreadsheetApp.getActiveSheet(); // or SpreadsheetApp.getActiveSpreadsheet().getSheetByName("sheetname")
sheet.getRange("J" + (sheet.getLastRow())).setValue(url);

Script to automatically send a Sheet by email

I am trying to automate by a script the sending of a Sheet (active or not) of a workbook and only one sheet and not the whole workbook to a list of email addresses. Furthermore, I would like the Sheet to be converted to excel format when it is attached to the email.
Thank you for your answers
Try this:
function emailSpreadsheetAsPDF() {
const sheetToPrint = 'SPREADSHEET_NAME'; // name of the sheet to print
const ss = SpreadsheetApp.getSheetByName('SHEET_NAME'); // the sheets to use
const email = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('SHEET_NAME').getRange('RANGE').getValue().toString(); // grab the email address from the specified cell
const subject = `SUBJECT - ${ss.getName()}`; // the subject of the email
const body = "BODY"; // body of the email
const shID = ss.getSheetByName(sheetToPrint).getSheetId(); // the ID of the sheet
const url = 'https://docs.google.com/spreadsheets/d/SS_ID/export?'.replace('SS_ID', ss.getId()); // url of the spreadsheet
const exportOptions =
'exportFormat=pdf&format=xlsx' + // export as pdf / csv / xls / xlsx
'&gid='+shID; // the sheet's Id
var params = {method:"GET",headers:{"authorization":"Bearer "+ ScriptApp.getOAuthToken()}};
// generate the file
var response = UrlFetchApp.fetch(url+exportOptions, params).getBlob();
// send the email to the specified address with the specified body text and attached file
GmailApp.sendEmail(email, subject, body, {
htmlBody: body,
attachments: [{
fileName: `EKOL Hungary - ${ss.getName()}` + ".xlsx",
content: response.getBytes(),
mimeType: "application/xlsx"
}]
});
}
Just substitute the SPREADSHEET_NAME, SHEET_NAME, RANGE, and BODY to what is true for your spreadsheet.
You can add a Trigger under the Triggers menu point (left side of the Script Editor) to automatically run the script whenever you want it to run.
Thanks but I failed to use it
But by combining several scripts, I found one that works:
function onSubmit(e){
Logger.log('submit ran');
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getActiveSheet();
//Send active sheet as email attachment
var ss = SpreadsheetApp.getActiveSpreadsheet()
var ssID = ss.getId();
var sheetgId = ss.getActiveSheet().getSheetId();
var sheetName = ss.getName();
var token = ScriptApp.getOAuthToken();
var email = "xxx#xx";
var subject = "xxxxx";
var body = "xxxxx";
var url = "https://docs.google.com/spreadsheets/d/"+ssID+"/export?" + "format=xlsx" + "&gid="+sheetgId+ "&portrait=false" + "&exportFormat=xlsx";
var result = UrlFetchApp.fetch(url, {
headers: {
'Authorization': 'Bearer ' + token
}
});
var contents = result.getContent();
MailApp.sendEmail(email,subject ,body, {attachments:[{fileName:sheetName+".xlsx", content:contents, mimeType:"application//xlsx"}]});
};
Now what I would like is to be able to send the sheet to email addresses located on another sheet.
Also in "subject", I would like to combine "xxxx" + a date in a cell of the active sheet: "xxxx dd / mm / yyyy"
I haven't figured out how to do it yet !!!

Get specific Range to Export

can anyone help me with my problem?
Need to export a specific range (A1:J39), not the full sheet.
function SavePDFtoDrive() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var ltrsht = ss.getSheetByName("Schichtübergabe-Protokoll");
var datasheet = ss.getSheetByName("Daten");
var sheets=SpreadsheetApp.getActiveSpreadsheet().getSheets();
for(var i =0;i<sheets.length;i++){
if(sheets[i].getName()!="Schichtübergabe-Protokoll"){ sheets[i].hideSheet() }
}
var pdf = DriveApp.getFileById(ss.getId());
var theBlob = pdf.getBlob().getAs('application/pdf').setName(datasheet.getRange("I8").getValue()+".pdf");
var folderID = "1dyKFNvQWrSiNFA8N5PyUMPJQpWSVhsLf"; // Folder id to save in a folder
var folder = DriveApp.getFolderById(folderID);
var newFile = folder.createFile(theBlob);
}
Answer:
Rather than getting your blob using DriveApp, you can obtain your blob from an export URL using UrlFetchApp.
More Information:
When you use DriveApp to create a blob of a file, it doesn't have the functionality to read the specifics of the file. In this case, you can't specify the range of a Sheet you wish to export with DriveApp.
You can, however, build a URL with all your export parameters and create your export in Drive by creating a blob of the response and creating it in Drive.
Code:
function SavePDFtoDrive() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var ltrsht = ss.getSheetByName("Schichtübergabe-Protokoll");
var datasheet = ss.getSheetByName("Daten");
// build your URL:
var url = "https://docs.google.com/spreadsheets/d/" + ss.getId() + "/export?"
//define your parameters:
var params = 'exportFormat=pdf&format=pdf'
+ '&portrait=false'
+ '&fitw=true'
+ '&gid=' + ltrsht.getSheetId()
+ '&range=A1:J39';
//get token for UrlFetch:
var token = ScriptApp.getOAuthToken();
var response = UrlFetchApp.fetch(url + params, {
'headers': {
'Authorization': 'Bearer ' + token
}
});
var fileName = datasheet.getRange("I8").getValue() + ".pdf";
var theBlob = response.getBlob().setName(fileName);
var folderID = "1Hp-P1dzWaKHhhS2FTPzKib6pwJibS12t";
var folder = DriveApp.getFolderById(folderID);
folder.createFile(theBlob);
}
References:
Class UrlFetchApp | Apps Script | Google Developers
Related Questions/Answers:
how to print a long Google sheets column in fewer columns