print - Convierta todas las hojas a PDF con Google Apps Script
google script create pdf (4)
Todavía no tengo la reputación de comentar, pero parece que hay un problema menor con la respuesta superior presentada por Gilbert W ... aunque es muy probable que no haya entendido algo.
Esa solución incluye la línea
+ (optSheetId ? (''&gid='' + sheet.getSheetId()) : (''&id='' + ss.getId()))
Sin embargo, "hoja" no se ha definido en el código antes de este punto. En el código de Mogsdad, "hoja" se define dentro del ciclo que se eliminó:
for (var i=0; i<sheets.length; i++) {
var sheet = sheets[i];
Y "hojas" se definió como
var sheets = ss.getSheets();
La solución funciona para alguien que quiere imprimir toda la hoja de cálculo, que es la pregunta que se hizo. Sin embargo, el código ya no funciona para alguien que quiere imprimir una sola página.
Otro problema con el código actualizado de Gilbert era que la solicitud HTML incluía una referencia a la ID de la hoja, pero no a la hoja de cálculo en sí misma. Esto provocó que la respuesta fallara si proporcionó una identificación de hoja específica, aunque funciona bien si no se proporcionó una identificación de hoja. Lo conseguí para trabajar otra vez invirtiendo la base de la URL a la manera que Mogsdad lo tenía.
Otro truco: el código de Gilbert nombra automáticamente al nuevo .PDF como el nombre de la hoja de cálculo. Mientras tanto, el código de Mogsdad imprime cada hoja de a una por vez, nombrando cada .PDF con el nombre de la hoja de cálculo seguido del nombre de la hoja actual. Quería imprimir el PDF con el nombre de la hoja única, si corresponde, y también proporcionar al usuario la capacidad de especificar un nombre de salida.
Como no existe ningún método para "getSheetById", dependiendo del contexto de su código, probablemente tenga más sentido que la función tome "optSheetName" en lugar de "optSheetID". La identificación de la hoja se puede tomar de "getSheetByName" si es necesario, y me parece que es más probable que un usuario tenga el nombre de la hoja que la identificación de la hoja. Tanto el nombre como el ID se pueden obtener programáticamente a partir de un script enlazado, pero solo el nombre se puede usar para obtener una hoja existente específica.
También agregué un parámetro de correo electrónico opcional para que pueda imprimir y enviar por correo electrónico el PDF al mismo tiempo.
Aquí está mi versión:
function savePDFs( optSSId , optSheetName , optOutputName, optEmail) {
// If a sheet ID was provided, open that sheet, otherwise assume script is
// sheet-bound, and open the active spreadsheet.
var ss = (optSSId) ? SpreadsheetApp.openById(optSSId) : SpreadsheetApp.getActiveSpreadsheet();
var optSheetId = ss.getSheetByName(optSheetName).getSheetId();
var outputName = (optOutputName ? optOutputName : (optSheetName ? optSheetName : ss.getName()))
// Get folder containing spreadsheet, for later export
var parents = DriveApp.getFileById(ss.getId()).getParents();
if (parents.hasNext()) {
var folder = parents.next();
}
else {
folder = DriveApp.getRootFolder();
}
var url_base = ss.getUrl().replace(/edit$/,'''');
//additional parameters for exporting the sheet as a pdf
var url_ext = ''export?exportFormat=pdf&format=pdf'' //export as pdf
// Print either the entire Spreadsheet or the specified sheet if optSheetId is provided
+ (optSheetId ? (''&gid='' + optSheetId) : (''&id='' + ss.getId())) // Print either the entire Spreadsheet or the specified sheet if optSheetId is provided
// following parameters are optional...
+ ''&size=letter'' // paper size
+ ''&portrait=true'' // orientation, false for landscape
+ ''&fitw=true'' // fit to width, false for actual size
+ ''&sheetnames=false&printtitle=false&pagenumbers=false'' //hide optional headers and footers
+ ''&gridlines=false'' // hide gridlines
+ ''&fzr=false''; // do not repeat row headers (frozen rows) on each page
var options = {
headers: {
''Authorization'': ''Bearer '' + ScriptApp.getOAuthToken(),
}
}
var response = UrlFetchApp.fetch(url_base + url_ext, options);
var blob = response.getBlob().setName((outputName)+ ''.pdf'');
folder.createFile(blob);
GmailApp.sendEmail(optEmail, "Here is a file named " + outputName, "Please let me know if you have any questions or comments.", {attachments:blob});
}
Intento convertir una hoja de cálculo de Google con varias hojas en un archivo PDF. El siguiente script funciona, pero solo crea un PDF con la última página de la hoja de cálculo.
function savePDFs() {
SpreadsheetApp.flush();
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheets = ss.getSheets();
var url = ss.getUrl();
//remove the trailing ''edit'' from the url
url = url.replace(/edit$/,'''');
//additional parameters for exporting the sheet as a pdf
var url_ext = ''export?exportFormat=pdf&format=pdf'' + //export as pdf
//below parameters are optional...
''&size=letter'' + //paper size
''&portrait=false'' + //orientation, false for landscape
''&fitw=true'' + //fit to width, false for actual size
''&sheetnames=false&printtitle=false&pagenumbers=false'' + //hide optional
''&gridlines=false'' + //false = hide gridlines
''&fzr=false'' + //do not repeat row headers (frozen rows) on each page
''&gid=''; //leave ID empty for now, this will be populated in the FOR loop
var token = ScriptApp.getOAuthToken();
//make an empty array to hold your fetched blobs
var blobs = [];
//.fetch is called for each sheet, the response is stored in var blobs[]
for(var i = 0; i < sheets.length; i++) {
var sheetname = sheets[i].getName();
//if the sheet is one that you don''t want to process,
//continue'' tells the for loop to skip this iteration of the loop
if(sheetname == "Team Member Numbers")
continue;
//grab the blob for the sheet
var response = UrlFetchApp.fetch(url + url_ext + sheets[i].getSheetId(), {
headers: {
''Authorization'': ''Bearer '' + token
}
});
//convert the response to a blob and store in our array
blobs.push(response.getBlob().setName(sheets[i].getName() + ''.pdf''));
var array_blob = response.getBlob().setName(sheets[i].getName() + ''.pdf'');
}
//from here you should be able to use and manipulate the blob to send and
//email or create a file per usual.
// send email
var subject = "Enter Subject"
var message = "See attached PDF"
MailApp.sendEmail("email addy here", subject, message,{attachments:[array_blob]});
}
He modificado ligeramente el código de @Mogsdad para imprimir toda la hoja de cálculo como un PDF. La clave es ajustar el parámetro de exportación. Básicamente reemplazar
''&gid='' + sheet.getSheetId() //the sheet''s Id
con
(optSheetId ? (''&gid='' + sheet.getSheetId()) : (''&id='' + ss.getId())) // Print either the entire Spreadsheet or the specified sheet if optSheetId is provided
Entonces el código anterior menos el bucle se ve así:
function savePDFs( optSSId, optSheetId ) {
// If a sheet ID was provided, open that sheet, otherwise assume script is
// sheet-bound, and open the active spreadsheet.
var ss = (optSSId) ? SpreadsheetApp.openById(optSSId) : SpreadsheetApp.getActiveSpreadsheet();
// Get folder containing spreadsheet, for later export
var parents = DriveApp.getFileById(ss.getId()).getParents();
if (parents.hasNext()) {
var folder = parents.next();
}
else {
folder = DriveApp.getRootFolder();
}
//additional parameters for exporting the sheet as a pdf
var url_ext = ''export?exportFormat=pdf&format=pdf'' //export as pdf
// Print either the entire Spreadsheet or the specified sheet if optSheetId is provided
+ (optSheetId ? (''&gid='' + sheet.getSheetId()) : (''&id='' + ss.getId()))
// following parameters are optional...
+ ''&size=letter'' // paper size
+ ''&portrait=true'' // orientation, false for landscape
+ ''&fitw=true'' // fit to width, false for actual size
+ ''&sheetnames=false&printtitle=false&pagenumbers=false'' //hide optional headers and footers
+ ''&gridlines=false'' // hide gridlines
+ ''&fzr=false''; // do not repeat row headers (frozen rows) on each page
var options = {
headers: {
''Authorization'': ''Bearer '' + ScriptApp.getOAuthToken()
}
}
var response = UrlFetchApp.fetch("https://docs.google.com/spreadsheets/" + url_ext, options);
var blob = response.getBlob().setName(ss.getName() + ''.pdf'');
//from here you should be able to use and manipulate the blob to send and email or create a file per usual.
//In this example, I save the pdf to drive
folder.createFile(blob);
}
Por cierto, gracias. ¡He estado buscando una solución para esto por mucho tiempo!
Aquí está mi variación sobre este tema, basada en la respuesta del Dr. Queso.
Todos los parámetros (descritos en el código) son opcionales y, si no se especifica ninguno, utiliza la hoja de cálculo activa, convierte todas las pestañas en un único PDF con el nombre de la hoja de cálculo y no envía el PDF.
function test() {
// Create a PDF containing all the tabs in the active spreadsheet, name it
// after the spreadsheet, and email it
convertSpreadsheetToPdf(''[email protected]'')
// Create a PDF containing all the tabs in the spreadsheet specified, name it
// after the spreadsheet, and email it
convertSpreadsheetToPdf(''[email protected]'', ''1r9INcnsyvSQmeduJWVYAvznOOYei9jeAjsy0acA3G1k'')
// Create a PDF just containing the tab ''Sheet2'' in the active spreadsheet, specify a name, and email it
convertSpreadsheetToPdf(''[email protected]'', null, ''Sheet2'', ''PDF 3'')
}
/*
* Save spreadsheet as a PDF
*
* @param {String} email Where to send the PDF [OPTIONAL]
* @param {String} spreadsheetId Or the active spreadsheet[OPTIONAL]
* @param {String} sheetName The tab to output [OPTIONAL]
* @param {String} PdfName [OPTIONAL]
*/
function convertSpreadsheetToPdf(email, spreadsheetId, sheetName, pdfName) {
var spreadsheet = spreadsheetId ? SpreadsheetApp.openById(spreadsheetId) : SpreadsheetApp.getActiveSpreadsheet();
spreadsheetId = spreadsheetId ? spreadsheetId : spreadsheet.getId()
var sheetId = sheetName ? spreadsheet.getSheetByName(sheetName).getSheetId() : null;
var pdfName = pdfName ? pdfName : spreadsheet.getName();
var parents = DriveApp.getFileById(spreadsheetId).getParents();
var folder = parents.hasNext() ? parents.next() : DriveApp.getRootFolder();
var url_base = spreadsheet.getUrl().replace(/edit$/,'''');
var url_ext = ''export?exportFormat=pdf&format=pdf'' //export as pdf
// Print either the entire Spreadsheet or the specified sheet if optSheetId is provided
+ (sheetId ? (''&gid='' + sheetId) : (''&id='' + spreadsheetId))
// following parameters are optional...
+ ''&size=letter'' // paper size
+ ''&portrait=true'' // orientation, false for landscape
+ ''&fitw=true'' // fit to width, false for actual size
+ ''&sheetnames=false&printtitle=false&pagenumbers=false'' //hide optional headers and footers
+ ''&gridlines=false'' // hide gridlines
+ ''&fzr=false''; // do not repeat row headers (frozen rows) on each page
var options = {
headers: {
''Authorization'': ''Bearer '' + ScriptApp.getOAuthToken(),
}
}
var response = UrlFetchApp.fetch(url_base + url_ext, options);
var blob = response.getBlob().setName(pdfName + ''.pdf'');
folder.createFile(blob);
if (email) {
var mailOptions = {
attachments:blob
}
MailApp.sendEmail(
email,
"Here is a file named " + pdfName,
"Please let me know if you have any questions or comments.",
mailOptions);
}
} // convertSpreadsheetToPdf()
Esta función es una adaptación de un script proporcionado por "ianshedd ..." aquí .
Eso:
- Genera archivos PDF de TODAS las hojas en una hoja de cálculo y las almacena en la misma carpeta que contiene la hoja de cálculo. (Supone que solo hay una carpeta haciendo eso, aunque Drive permite la contención múltiple).
- Nombres de archivos PDF con nombres de hojas de cálculo y hojas.
- Utiliza el servicio de Drive (DocsList está en desuso).
- Puede usar una ID de hoja de cálculo opcional para operar en cualquier hoja. Por defecto, espera trabajar en la "hoja de cálculo activa" que contiene la secuencia de comandos.
Solo necesita autorización "normal" para operar; no es necesario activar los servicios avanzados ( bueno ... necesitas algo, mira esto ) o
oAuthConfig
conoAuthConfig
.La autorización OAuth2 para la llamada
fetch()
que recupera el PDF de una hoja de cálculo se concede a través deScriptApp.getOAuthToken()
, que nos proporciona el token de acceso OAuth 2.0 para el usuario actual.
Con un poco de investigación y esfuerzo, puede conectarse a una API PDF Merge en línea para generar un solo archivo PDF. Salvo eso, y hasta que Google proporcione una forma de exportar todas las hojas en un PDF, se le atascarán los archivos por separado. ¡Vea el ajuste de Gilbert para obtener hojas múltiples!
Guión:
/**
* Export one or all sheets in a spreadsheet as PDF files on user''s Google Drive,
* in same folder that contained original spreadsheet.
*
* Adapted from https://code.google.com/p/google-apps-script-issues/issues/detail?id=3579#c25
*
* @param {String} optSSId (optional) ID of spreadsheet to export.
* If not provided, script assumes it is
* sheet-bound and opens the active spreadsheet.
* @param {String} optSheetId (optional) ID of single sheet to export.
* If not provided, all sheets will export.
*/
function savePDFs( optSSId, optSheetId ) {
// If a sheet ID was provided, open that sheet, otherwise assume script is
// sheet-bound, and open the active spreadsheet.
var ss = (optSSId) ? SpreadsheetApp.openById(optSSId) : SpreadsheetApp.getActiveSpreadsheet();
// Get URL of spreadsheet, and remove the trailing ''edit''
var url = ss.getUrl().replace(/edit$/,'''');
// Get folder containing spreadsheet, for later export
var parents = DriveApp.getFileById(ss.getId()).getParents();
if (parents.hasNext()) {
var folder = parents.next();
}
else {
folder = DriveApp.getRootFolder();
}
// Get array of all sheets in spreadsheet
var sheets = ss.getSheets();
// Loop through all sheets, generating PDF files.
for (var i=0; i<sheets.length; i++) {
var sheet = sheets[i];
// If provided a optSheetId, only save it.
if (optSheetId && optSheetId !== sheet.getSheetId()) continue;
//additional parameters for exporting the sheet as a pdf
var url_ext = ''export?exportFormat=pdf&format=pdf'' //export as pdf
+ ''&gid='' + sheet.getSheetId() //the sheet''s Id
// following parameters are optional...
+ ''&size=letter'' // paper size
+ ''&portrait=true'' // orientation, false for landscape
+ ''&fitw=true'' // fit to width, false for actual size
+ ''&sheetnames=false&printtitle=false&pagenumbers=false'' //hide optional headers and footers
+ ''&gridlines=false'' // hide gridlines
+ ''&fzr=false''; // do not repeat row headers (frozen rows) on each page
var options = {
headers: {
''Authorization'': ''Bearer '' + ScriptApp.getOAuthToken()
}
}
var response = UrlFetchApp.fetch(url + url_ext, options);
var blob = response.getBlob().setName(ss.getName() + '' - '' + sheet.getName() + ''.pdf'');
//from here you should be able to use and manipulate the blob to send and email or create a file per usual.
//In this example, I save the pdf to drive
folder.createFile(blob);
}
}
/**
* Dummy function for API authorization only.
* From: https://.com/a/37172203/1677912
*/
function forAuth_() {
DriveApp.getFileById("Just for authorization"); // https://code.google.com/p/google-apps-script-issues/issues/detail?id=3579#c36
}