En este artículo vemos como generar PDFs a partir de nuestro libro, hojas y rangos de nuestra hoja de cálculo, tanto de manera manual, como de manera automática con código.
Qué es un PDF
PDF son las siglas de Printable Document Format, un formato de archivo que tiene dos importantes características
- Tal como lo imprimimos, lo va a ver nuestro destinatario o público.
- No se puede modificar.
Por qué exportar a PDF
PDF ha sido un formato muy utilizado en los últimos años debido a su facilidad de compartir, y a que todos los computadores, exploradores y dispositivos.
Por eso es mucho más fácil enviar un PDF que un Excel o un Sheets
Exportar PDFs manualmente desde Google Sheets
Sheets, como muchos otros programas, nos da la opción de exportar nuestros Sheets cómo PDFs
Esto lo podemos hacer de dos maneras:
- Vamos a «Archivo» > «Descargar» > «PDF»
- Vamos a «Archivo» > «Imprimir», y en «Siguiente», y en «Destino», seleccionamos «Guardar como PDF»
La diferencia entre los dos métodos es que al imprimir tenemos varias opciones de márgenes y ajuste, y así controlar un poco más la apariencia de nuestro PDF
Exportar PDFs con Google Apps Script
Tenemos varias maneras de crear PDFs desde Google Apps Script y Google Sheets
Entre otras podríamos hacer lo siguiente
- Crear un PDF de un libro
- Crear PDF de una hoja
- Crear PDF de un rango
- Crear PDF a partir de una fila y una plantilla (Docs, Slides, Html o Sheets)
Glosario
PDF: Formato de Archivo Imprimible
Blob: Archivo crudo que contiene un tamaño y un tipo
MimeType: El tipo de archivo del blob
«application/pdf»: El tipo de archivo de un pdf
Exportar el libro
Vamos a empezar con el método más sencillo: exportar un libro entero
Para esto debemos:
- Conectarnos con el libro actual con SpreadsheetApp.getActiveSpreadsheet()
- Convertir el libro en un archivo blob con .getBlob()
- Crear el PDF a partir del blob con DriveApp.createFile(blob)
- Darle un nombre con .setName(nombre)
//Conectar con el libro de Sheets
var libro = SpreadsheetApp.getActiveSpreadsheet()
//Crear el blob
var blob=libro.getBlob()
//Crear el pdf
DriveApp.createFile(blob).setName("PDF ahora si con formato")
Exportar PDF con más opciones de formato
La anterior es una manera muy válida de exportar pero es poco flexible porque no podemos controlar el aspecto de nuestro PDF
Hay una manera un poco más complicada pero mucho más robusta y profesional
Estos son los pasos:
- Conectarnos con el libro actual con SpreadsheetApp.getActiveSpreadsheet()
- Averiguamos la URL del libro con .getURL()
- Le quitamos al URL el texto «edit»
- Le agregamos a la URL, el texto «»export?exportFormat=pdf»
- Creamos el objeto «parametros»
- Creamos una respuesta HTML, llamando el método URLFetchApp.fetch() con la URL y los parámetros.
- Convertimos la respuesta en un blob con el método .getAs()
- Crear el PDF a partir del blob con DriveApp.createFile(blob)Darle un nombre con .setName(nombre)
function crearPDFPersonalizable() {
var libro = SpreadsheetApp.getActiveSpreadsheet();
var url = libro.getUrl()
var urlNuevo = url.replace("edit", "")
urlNuevo += "export?exportFormat=pdf"
var parametros = {
muteHttpExceptions: true,
headers: {
Authorization: 'Bearer ' + ScriptApp.getOAuthToken(),
}
}
var respuesta=UrlFetchApp.fetch(urlNuevo, parametros)
var blob=respuesta.getAs("application/pdf")
DriveApp.createFile(blob).setName("Nombre del PDF")
}
Insertar las opciones de Formato
Diras tu, pero que diferencia hay entre el primer método que vimos, y este mucho mas complicado, si el resultado es exactamente el mismo.
La diferencia radica en que podemos incluir opciones de parametrización y formato para nuestro HTML
Y lo único que debemos hacer es agregar a nuestra URL la opción que queremos modificar y el valor de la misma
Aquí les dejo el listado de todas las opciones.
Siéntete libre de agregar o eliminar el que necesites
function crearPDFPersonalizable() {
var libro = SpreadsheetApp.getActiveSpreadsheet();
var url = libro.getUrl()
var urlNuevo = url.replace("edit", "") +
"export?exportFormat=pdf"+
"&format=pdf"+ //Formato de exportación {pdf}
"&size=LETTER" + //Tamaño de Papel {LETTER=carta, LEGAL=oficio}
"&portrait=true" + //Orientación {true=vertical, false=horizontal}
"&fitw=false" + //Ajustar al ancho {true=ajusta, false=no ajusta}
"&scale=1" + //Ajustes {1=100%,2=Ancho,3=Alto,4=Página}
"&gridlines=false" + //Lineas de cuadrícula {true=se muestran. false=no}
"&fzr=true" + //Encabezados en todas las hojas {true=si, false=no}
"&fzc=false"+ //Primera columna en todas las hojas {true=si, false=no}
"&printtitle=true" + //Titulo en parte superior izq {true=si, false=no}
"&pagenum=CENTER" + //Numeración pie de página {CENTER=si, UNDEFINED =no}
"&sheetnames=true"+ //Nombre de la hoja superior derecha {true=si, false=no}
"&top_margin=0.7"+
"&bottom_margin=0.7"+
"&left_margin=1"+
"&right_margin=1" + //Unidades de margenes, acepta decimales {0 es nada, 2 es mucho}
"&horizontal_alignment=CENTER"+ //Alineación horizontal {LEFT,CENTER,RIGHT}
"&vertical_alignment=BOTTOM"+ //Alineación vertical {TOP,MIDDLE,BOTTOM}
"&printnotes=false" + //Imprimir notas {true=imprime (default), false=no imprime}
"&pageorder=1" + // Orden si se desborda la tabla {1=Abajo y despues derecha, 2=Al revés}
var parametros = {
muteHttpExceptions: true,
headers: {
Authorization: 'Bearer ' + ScriptApp.getOAuthToken(),
}
}
var respuesta=UrlFetchApp.fetch(urlNuevo, parametros)
var blob=respuesta.getAs("application/pdf")
DriveApp.createFile(blob).setName("Nombre del PDF")
}
Exportar una hoja de Google Sheets como PDF
Esta es una extensión del código anterior
Lo único adicional que debemos hacer es
- Llamar a la hoja (En nuestro ejemplo va a ser la hoja activa)
- Traer la ID de la pestaña que queremos exportar
- Agregar esa id a la url con el parametro «&gid=»
Esto sería lo que agregaríamos
var hoja=libro.getActiveSheet();
var idHoja=hoja.getSheetId();
.
.
.
urlNuevo += "export?exportFormat=pdf" + "&gid=" + idHoja
Quedaría así el código total
function crearPDFPersonalizable() {
var libro = SpreadsheetApp.getActiveSpreadsheet();
var url = libro.getUrl()
var hoja=libro.getActiveSheet();
var idHoja=hoja.getSheetId();
var urlNuevo = url.replace("edit", "") +
"export?exportFormat=pdf"+
"&format=pdf"+ //Formato de exportación {pdf}
"&size=LETTER" + //Tamaño de Papel {LETTER=carta, LEGAL=oficio}
"&portrait=true" + //Orientación {true=vertical, false=horizontal}
"&fitw=false" + //Ajustar al ancho {true=ajusta, false=no ajusta}
"&scale=1" + //Ajustes {1=100%,2=Ancho,3=Alto,4=Página}
"&gridlines=false" + //Lineas de cuadrícula {true=se muestran. false=no}
"&fzr=true" + //Encabezados en todas las hojas {true=si, false=no}
"&fzc=false"+ //Primera columna en todas las hojas {true=si, false=no}
"&printtitle=true" + //Titulo en parte superior izq {true=si, false=no}
"&pagenum=CENTER" + //Numeración pie de página {CENTER=si, UNDEFINED =no}
"&sheetnames=true"+ //Nombre de la hoja superior derecha {true=si, false=no}
"&top_margin=0.7"+
"&bottom_margin=0.7"+
"&left_margin=1"+
"&right_margin=1" + //Unidades de margenes, acepta decimales {0 es nada, 2 es mucho}
"&horizontal_alignment=CENTER"+ //Alineación horizontal {LEFT,CENTER,RIGHT}
"&vertical_alignment=BOTTOM"+ //Alineación vertical {TOP,MIDDLE,BOTTOM}
"&printnotes=false" + //Imprimir notas {true=imprime (default), false=no imprime}
"&pageorder=1" + // Orden si se desborda la tabla {1=Abajo y despues derecha, 2=Al revés}
urlNuevo += "export?exportFormat=pdf" + "&gid=" + idHoja
var parametros = {
muteHttpExceptions: true,
headers: {
Authorization: 'Bearer ' + ScriptApp.getOAuthToken(),
}
}
var respuesta=UrlFetchApp.fetch(urlNuevo, parametros)
var blob=respuesta.getAs("application/pdf")
DriveApp.createFile(blob).setName("Nombre del PDF")
}
Exportar un rango
Una última cosa que podemos agregar al código anterior es la habilidad de exportar un rango específico. Para esto debemos adicionar lo siguiente:
- Llamamos el rango deseado, en nuestro caso va a ser el rango activo
- Extraemos la columna inicial y final, y la fila inicial y final del rango
- Agregamos estos valores a nuestro url con los parámetros r1,r2,c1 y c2
Esto sería lo que agregaríamos:
var columnaInicial = rango.getColumn() - 1;
var filaInicial = rango.getRow() - 1;
var columnaFinal = rango.getLastColumn();
var filaFinal = rango.getLastRow();
.
.
.
urlNuevo += "&r1=" + filaInicial + //Fila de inicio (Ej: 0 es la fila 1)
"&r2=" + filaFinal + //Fila de fin (Ej: # de la fila final)
"&c1=" + columnaInicial + //Col de inicio (Ej: 0 es la columna A)
"&c2=" + columnaFinal // Col de fin (Ej: 2 es la columna B)
Así quedaría todo el código
function crearPDFPersonalizable() {
var libro = SpreadsheetApp.getActiveSpreadsheet(
var url = libro.getUrl()
var hoja=libro.getActiveSheet();
var idHoja=hoja.getSheetId();
var columnaInicial = rango.getColumn() - 1;
var filaInicial = rango.getRow() - 1;
var columnaFinal = rango.getLastColumn();
var filaFinal = rango.getLastRow();
var urlNuevo = url.replace("edit", "") +
"export?exportFormat=pdf"+
"&format=pdf"+ //Formato de exportación {pdf}
"&size=LETTER" + //Tamaño de Papel {LETTER=carta, LEGAL=oficio}
"&portrait=true" + //Orientación {true=vertical, false=horizontal}
"&fitw=false" + //Ajustar al ancho {true=ajusta, false=no ajusta}
"&scale=1" + //Ajustes {1=100%,2=Ancho,3=Alto,4=Página}
"&gridlines=false" + //Lineas de cuadrícula {true=se muestran. false=no}
"&fzr=true" + //Encabezados en todas las hojas {true=si, false=no}
"&fzc=false"+ //Primera columna en todas las hojas {true=si, false=no}
"&printtitle=true" + //Titulo en parte superior izq {true=si, false=no}
"&pagenum=CENTER" + //Numeración pie de página {CENTER=si, UNDEFINED =no}
"&sheetnames=true"+ //Nombre de la hoja superior derecha {true=si, false=no}
"&top_margin=0.7"+
"&bottom_margin=0.7"+
"&left_margin=1"+
"&right_margin=1" + //Unidades de margenes, acepta decimales {0 es nada, 2 es mucho}
"&horizontal_alignment=CENTER"+ //Alineación horizontal {LEFT,CENTER,RIGHT}
"&vertical_alignment=BOTTOM"+ //Alineación vertical {TOP,MIDDLE,BOTTOM}
"&printnotes=false" + //Imprimir notas {true=imprime (default), false=no imprime}
"&pageorder=1" + // Orden si se desborda la tabla {1=Abajo y despues derecha, 2=Al revés}
urlNuevo += "export?exportFormat=pdf" + "&gid=" + idHoja
urlNuevo += "&r1=" + filaInicial + //Fila de inicio (Ej: 0 es la fila 1)
"&r2=" + filaFinal + //Fila de fin (Ej: numero de la fila donde termina el rango)
"&c1=" + columnaInicial + //Columna de inicio (Ej: 0 es la columna A)
"&c2=" + columnaFinal // Columna de fin (Ej: 2 es la columna B)
var parametros = {
muteHttpExceptions: true,
headers: {
Authorization: 'Bearer ' + ScriptApp.getOAuthToken(),
}
}
var respuesta=UrlFetchApp.fetch(urlNuevo, parametros)
var blob=respuesta.getAs("application/pdf")
DriveApp.createFile(blob).setName("Nombre del PDF")
}
Conclusión
Como ves, no es tan difícil crear PDFs desde nuestros Sheets, con un poco de código
Y hasta ahora estamos tocando la punta del iceberg, porque hay muchas más cosas que podemos hacer con nuestras tablas para hacer informes automatizados en PDF
Excelente, me sirvio demasiado, utilice el primer codigo y oculte las otras hojas
Hola
Excelente! Me alegra ser de utilidad.
Un gran saludo!
Buenas, muchos consejo me han servido para ir mejorando los trabajos que hago con google sheets, soy docente de escuela técnica, encargado de la comunicación por web para las familias y directivo.
La consulta es la siguiente:
En una celda A1 pego ‘https://docs.google.com/spreadsheets/…’ y en A2’=A1&»pub?output=pdf»‘
Por lo tanto creo el siguiente vínculo en A2 ‘https://docs.google.com/spreadsheets/d/e/xxxxx/pub?output=pdf’
El mismo me imprime en un formato único y deseo cambiarlo, a ajuste a hoja y letter, podría darme una ayuda.
Desde ya muchas y saludos desde Argentina.
Hola!
De pronto hay una opción para que despues del output=pdf pongas los demas parametros como lo explico en el articulo
Intenta por ejemplo poner
A1&»pub?output=pdf&size=LETTER»
a ver que pasa
Saludos!
hola juan! me encanta tu contenido y es de excelente calidad, me gustaria saber como hago para exportar a pdf con appscript 2 hojas de una hoja de calculo suponiendo que esta tiene mas de 3. desde ya muchas gracias!
Hola!
Debes hacer un código que va hoja por hoja y oculta las que no son
El código de script con el libro te publica todas las hojas MOSTRADAS
Saludos!
Estimado Juan, Muchas gracias por el aporte. Sería posible insertar la fecha en el que creamos el PDF en el encabezado o pie de página, al igual que insertamos el título del libro (printtitle) o el número de páginas (pagenum).
Hola Juan, te hago una consulta.
Por qué me arroja este error al tratar de ejecutar el código?
Error de sintaxis: SyntaxError: Invalid left-hand side in assignment, línea: 9, archivo: Código.gs
He revisado bastante pero no comprendo que puede causar el error. Espero puedas ayudarme amigo. Saludos.
Hola!
Normalmente puede ser que estas tratando de poner algo a una constante
Saludos!
No se pudo abrir el archivo en este momento.
Verifica la dirección e inténtalo de nuevo.
buen día, al realizar el codigo de pdf especifico me sale este mensaje en el pdf y no las hojas del Sheet, como lo soluciono
Realiza tus proyectos con Google Drive
Las aplicaciones de Google Drive te facilitan la
tarea de crear, almacenar y compartir documentos,
hojas de cálculo, presentaciones y otros archivos
en línea.
Obtén más información en
drive.google.com/start/apps.
ASegurate que el código este exacto, particularmente la parte del urlfetch
Saludos!
Hola Juan! Tengo una consulta, al momento de ponerle el formato copiando el código de esta página no me lo cambia. Entiendo que el problema esta en la Url Nuevo pero no logro identificar cual es el error.
Muchas gracias.
Saludos.-
Hola Luciana
Disculpa la demora
Espero hayas logrado solucionar
Saludos!
Se podría hacer un link de descarga directa? Qué le pique y se descargue en pdf
Hmmm
No creo que se pueda, pero me equivocado en el pasado
Saludos!
¡Hola! ¿Es posible que el nombre del pdf incluya un número que está en una celda del mismo Sheets? No lo he podido lograr
Hola!
Claro que si
En setName incluyes la variable que se refiere a la celda que quieres
Saludos!
Hola Juan G.
Muchas gracias por la info bastante detallada en tu explicación.
Muy buen aporte de 5 estrellas.
Gracias por el comentario!
Hola, Juan
Es posible crear un pdf de varias páginas a partir de una hoja, como cuando exportas en pdf con áreas de impresión.
Muchas gracias
Hola Rebeca
Prueba imprimiendo un pdf manualmente y estableciendo los saltos de página ahi, y despues si ejecutas el código a ver como te va
Saludos
Hola Juan. Te hago una consulta, en cuanto a las opciones de tamaño de hoja, solo es posible Letter y Legal? Porque nosotros usamos el 100% en formato A4. No hay opción?? Gracias desde ya, y sos un genio hermano!
HOla, creo que A4 tambien la acepta. Ya probaste?
Mil gracias por tus palabras!
Saludos!