Crear PDFs desde Google Sheets y Google Apps Script

Crear PDFs desde Google Sheets

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:

  1. Vamos a «Archivo» > «Descargar» > «PDF»
  2. 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:

  1. Conectarnos con el libro actual con SpreadsheetApp.getActiveSpreadsheet()
  2. Convertir el libro en un archivo blob con .getBlob()
  3. Crear el PDF a partir del blob con DriveApp.createFile(blob)
  4. 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:

  1. Conectarnos con el libro actual con SpreadsheetApp.getActiveSpreadsheet()
  2. Averiguamos la URL del libro con .getURL()
  3. Le quitamos al URL el texto «edit»
  4. Le agregamos a la URL, el texto «»export?exportFormat=pdf»
  5. Creamos el objeto «parametros»
  6. Creamos una respuesta HTML, llamando el método URLFetchApp.fetch() con la URL y los parámetros.
  7. Convertimos la respuesta en un blob con el método .getAs()
  8. 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

  1. Llamar a la hoja (En nuestro ejemplo va a ser la hoja activa)
  2. Traer la ID de la pestaña que queremos exportar
  3. 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:

  1. Llamamos el rango deseado, en nuestro caso va a ser el rango activo
  2. Extraemos la columna inicial y final, y la fila inicial y final del rango
  3. 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


Publicado

en

,

por

Etiquetas:

Comentarios

23 respuestas a «Crear PDFs desde Google Sheets»

  1. Avatar de Juan
    Juan

    Excelente, me sirvio demasiado, utilice el primer codigo y oculte las otras hojas

    1. Avatar de jsguzmanb
      jsguzmanb

      Hola

      Excelente! Me alegra ser de utilidad.

      Un gran saludo!

  2. Avatar de Javier Villalba
    Javier Villalba

    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.

    1. Avatar de jsguzmanb
      jsguzmanb

      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!

  3. Avatar de Jonathan
    Jonathan

    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!

    1. Avatar de jsguzmanb
      jsguzmanb

      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!

  4. Avatar de Vicente Masip
    Vicente Masip

    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).

  5. Avatar de Hermes
    Hermes

    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.

    1. Avatar de jsguzmanb
      jsguzmanb

      Hola!

      Normalmente puede ser que estas tratando de poner algo a una constante

      Saludos!

  6. Avatar de Jamil
    Jamil

    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.

    1. Avatar de jsguzmanb
      jsguzmanb

      ASegurate que el código este exacto, particularmente la parte del urlfetch
      Saludos!

  7. Avatar de Luciana
    Luciana

    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.-

    1. Avatar de jsguzmanb
      jsguzmanb

      Hola Luciana

      Disculpa la demora

      Espero hayas logrado solucionar

      Saludos!

  8. Avatar de Carlos

    Se podría hacer un link de descarga directa? Qué le pique y se descargue en pdf

    1. Avatar de jsguzmanb
      jsguzmanb

      Hmmm
      No creo que se pueda, pero me equivocado en el pasado
      Saludos!

  9. Avatar de Carla
    Carla

    ¡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

    1. Avatar de jsguzmanb
      jsguzmanb

      Hola!
      Claro que si
      En setName incluyes la variable que se refiere a la celda que quieres
      Saludos!

  10. Avatar de Charlie
    Charlie

    Hola Juan G.

    Muchas gracias por la info bastante detallada en tu explicación.
    Muy buen aporte de 5 estrellas.

    1. Avatar de jsguzmanb
      jsguzmanb

      Gracias por el comentario!

  11. Avatar de Rebeca
    Rebeca

    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

    1. Avatar de jsguzmanb
      jsguzmanb

      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

  12. Avatar de Diego
    Diego

    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!

    1. Avatar de jsguzmanb
      jsguzmanb

      HOla, creo que A4 tambien la acepta. Ya probaste?

      Mil gracias por tus palabras!

      Saludos!

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.