Sheet a pdf con encabezado y pie de pagina (Sheet to pdf with header and footer)

Tirarlos a la papelera por favor.
Y como respuesta tenga la URL del libro PDF generado.

Quedo atento a tu apoyo amigo :slight_smile:

Requiero de tu apoyo @TIMAI2 por favor :pensive:

Por favor estimado @TIMAI2 :pray:t2:

No time to develop your app for you at the moment, but here is how to do it:

No entiendo mucho esos script's, tú crees que si espero, me puedas apoyar?

Por favor amigo @TIMAI2

OK, found some time, and now we hopefully have a solution, if I have understood your requirements correctly. The following will generate a single pdf, with multiple pages consisting of a header and footer and up to 25 records per page.

My tests were with a google spreadsheet that contained just one sheet, with a header (A1:F11) a data section (A12:F1011) for upto 1000 records, and a footer (A1012:F1017).

The google apps script web app will generate a new sheet for each 25 records, with a header and footer, then hide the original records sheets, and generate a single pdf from the remaining sheets. I have annotated the script as best I can to explain what each line of the code does.

The google apps script needs to be fed 5 parameters:

  1. The spreadsheet ID
  2. The sheet name
  3. The folder ID
  4. The records number (25)
  5. The pdf name

The google apps script will return the ID of the newly created pdf file, which can then be accessed by inserting it to this url:

https://drive.google.com/file/d/<fileId here>/view

SCRIPT
function doGet(e) {
  var fileId;
  var ss = SpreadsheetApp.openById(e.parameter.ssId); //get the spreadsheet
  var sh = ss.getSheetByName(e.parameter.shName); //get the sheet with the records
  var rngLength = sh.getRange("A12:A1011").getValues().filter(String).length; //get the number of records on the sheet
  var num = Math.ceil(rngLength/e.parameter.recNo); //get the ceiling (round up) for the number of pages
  for (var i=0;i<num;i++) {
    sh.hideRows(12,1000); //hide all the individual record rows
    sh.showRows(12+(25*i),25); // show the records based upon the recrod numbers
    sh.copyTo(ss); //copy the original sheet to a new sheet
    SpreadsheetApp.flush(); //set all operations on the spreadsheet
  } //create a new sheet for each set of records, based on the records number,
  sh.hideSheet(); //hide the sheet with the recrods in it
  var folder = DriveApp.getFolderById(e.parameter.folderId); //get the folder to store the pdf
  var url_base = 'https://docs.google.com/spreadsheets/d/' + e.parameter.ssId; //the base url
  var url_ext = '/export?exportFormat=pdf&format=pdf'
      + '&id=' + e.parameter.ssId; // !important - sets the spreadsheet to be converted to a pdf (instead of just the first sheet)
      + '&size=7'      // paper size A4 = 7
      + '&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=true'  // show gridlines
      + '&horizontal_alignment=CENTER' //centre range on page
      + '&fzr=false';       // do not repeat row headers (frozen rows) on each page
      // all the options for the pdf, including the requirement to set the entire spreadsheet to the pdf
  var options = { headers: { 'Authorization': 'Bearer ' +  ScriptApp.getOAuthToken(), } } //authorisation
  var response = UrlFetchApp.fetch(url_base + url_ext, options); //now fetch the spreadsheet
  var blob = response.getBlob().setName(e.parameter.pdfName + '.pdf'); //create a blob of the spreadsheet with the filename
  fileId = folder.createFile(blob).getId(); //create the pdf file and get the file ID
  SpreadsheetApp.flush(); //set all operations on the spreadsheet
  sh.showSheet(); //show the original records sheet
  sh.showRows(12,1000); //show all the record rows
  var sheets = ss.getSheets(); //get all the sheets for the spreadsheet
  sheets.shift(); //remove the first sheet (the original records sheet)
  for (var i = 0;i<sheets.length;i++) {
  ss.deleteSheet(sheets[i]);
  } //delete all the generated sheets
  return ContentService.createTextOutput(fileId); //return the file ID as a string
}
BLOCKS example

Here also an example output pdf file, created from 165 records in the Records sheet, using 25 records per sheet, which generated 7 pages. This took @ 7 seconds to create.

testPDF.pdf (75.1 KB)

Credits should go to this SO Q&A,and the contributors there, which helped me put part of this together

I trust you can make use of this, or adapt it for your needs

Muy agradecido @TIMAI2 @SO @Q&A estoy muy agradecido con su apoyo. :slight_smile:

Solamente me queda encontrar la forma en que mi cuota de api drive sea extensa, ya que mi APP INVENTOR genera firmas con canva y los guarda al Folder Drive y en la hoja sheet en la cual generaré estos reportes PDF, pero he leido que solo te deja crear 250 docs. por día y mi necesidad se ajusta a 5000 por día, ya que es una app para uso de agroindustrial con firmas de los colaboradores al entregar un presente por días festivos.

Sin más extenderme @TIMAI2 has sido parte de mi proyecto.

Does it work for you ?

Sobre el script que me proporcionaste voy a probarlo, es una buena salida (aunque deseaba que se genere en la misma hoja sheet filtrando los registros como en el script anterior brindado), pero no puedo ser mal agradecido así que lo pondré en marcha :muscle:t2:

Sobre las cuotas limites de api drive, no sé si me podrá permitir crear 5000 firmas de archivos .png por día, o en realidad en algunos días específicos durante el año

Si funciona.
Pero existe la forma en que el libro pdf sea generado desde la hoja de donde están los registros sin necesidad de crear hojas temporales nuevas?

Tal cual como el script que me brindarte antes pero fusionando esos pdf que se obtenían.

Then my work is done.

Ummm ok @TIMAI2 gracias.
Veré la forma de adecuarlo a que no me genere hojas temporales :raised_hands:

Hola @TIMAI2 nuevamente.
No logré concretar mi duda, el script que me brindaste hace que copie de 25 en 25 registros en nuevas hojas y luego se eliminen, oculta la hoja activa o de origen, el tema es que tengo más que una hoja en el libro sheet, no hay la posibilidad que me puedas apoyar de que se genere el libro pdf con 25 registros cada hoja pdf sin tener que agregar hojas temporales sheet's??

In the script, hide sheets you do not want in the pdf, then unhide them again once the pdf is created. This is already being done for Sheet1.

Mira @TIMAI2 con esto me genera lo deseado, pero puedes darle una revisada sino hay algo que altere el proceso en este script:

function doGet(e) {
  var fileId;
  var ss = SpreadsheetApp.openById(e.parameter.ssId);
  var sh = ss.getSheetByName(e.parameter.shName);
  var rngLength = sh.getRange("A22:A320").getValues().filter(String).length;
  var num = Math.ceil(rngLength / e.parameter.recNo);
  
  for (var i = 0; i < num; i++) {
    sh.hideRows(22, 298);
    sh.showRows(22 + (25 * i), 25);
    sh.copyTo(ss);
    SpreadsheetApp.flush();
  }
  
  // Hide original data sheet and additional sheets
  var sheetsToHide = [sh, ss.getSheetByName("Copia de Hoja 3"), ss.getSheetByName("SIMPLE2"), ss.getSheetByName("SIMPLE1"), ss.getSheetByName("INDUMENTARIA"), ss.getSheetByName("LONCHERA"), ss.getSheetByName("CANASTA"), ss.getSheetByName("Ev."), ss.getSheetByName("DANIEL")]; // Add additional sheets here
  sheetsToHide.forEach(function(sheet) {
    sheet.hideSheet();
  });

  var folder = DriveApp.getFolderById(e.parameter.folderId);
  var url_base = 'https://docs.google.com/spreadsheets/d/' + e.parameter.ssId;
  var url_ext = '/export?exportFormat=pdf&format=pdf'
      + '&id=' + e.parameter.ssId
      + '&size=7'
      + '&portrait=true'
      + '&fitw=true'
      + '&sheetnames=false&printtitle=false&pagenumbers=false'
      + '&gridlines=true'
      + '&horizontal_alignment=CENTER'
      + '&fzr=false';
  var options = { headers: { 'Authorization': 'Bearer ' +  ScriptApp.getOAuthToken(), } };
  var response = UrlFetchApp.fetch(url_base + url_ext, options);
  var blob = response.getBlob().setName(e.parameter.pdfName + '.pdf');
  fileId = folder.createFile(blob).getId();
  SpreadsheetApp.flush();
  
  // Show original data sheet and additional sheets
  var sheetsToShow = [sh, ss.getSheetByName("Copia de Hoja 3"), ss.getSheetByName("SIMPLE2"), ss.getSheetByName("SIMPLE1"), ss.getSheetByName("INDUMENTARIA"), ss.getSheetByName("LONCHERA"), ss.getSheetByName("CANASTA"), ss.getSheetByName("Ev."), ss.getSheetByName("DANIEL")]; // Add additional sheets here
  sheetsToShow.forEach(function(sheet) {
    sheet.showSheet();
  });
  sh.showRows(22,298);
  
  var sheets = ss.getSheets();
  var sheetsToKeep = ["Sheet1", "Sheet2", "Sheet3", "Sheet4", "Sheet5"]; // Specify the names of the sheets you want to keep
  for (var i = sheets.length - 1; i >= 0; i--) {
    var sheetName = sheets[i].getName();
    if (sheetsToKeep.indexOf(sheetName) === -1 && sheetName !== e.parameter.shName) {
      ss.deleteSheet(sheets[i]);
    }
  }
  
  return ContentService.createTextOutput(fileId);
}

Well if it works for you, then all is OK, yes ?

Gracias @TIMAI2
Voy a cerrar esto, agradecido con tu apoyo

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.