Есть ли способ напечатать несколько вкладок электронной таблицы (но не все) в виде одного PDF-файла? - PullRequest
1 голос
/ 05 февраля 2020

Я провел некоторое исследование, но не нашел способа сделать это. Пытался сделать то, что Эндрю Робертс объясняет здесь http://www.andrewroberts.net/2017/03/apps-script-create-pdf-multi-sheet-google-sheet/, чтобы преобразовать электронную таблицу (или конкретную c вкладку) в pdf:

    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=A4'      // 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 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);
  }

Глядя на комментарии, он предлагает добавить следующий код, который я поместил в другую функцию:

  function printtwopdfs() {

  var sheetNames = ["Table1,"Table2"]

  sheetNames.forEach(function(sheetName) {
  convertSpreadsheetToPdf(TEST_EMAIL, "xxxxxx", sheetName, 
  "pdfteste")
  })}

Но я получил каждый лист, напечатанный отдельно в виде одного PDF-файла.

Скрыть все вкладки, кроме тех, которые мне нужны, и распечатать электронную таблицу в целом - не вариант для меня, поскольку в ней слишком много вкладок (около 15). Кроме того, я вряд ли скопирую выбранные листы в новую электронную таблицу, потому что эта функция может занять слишком много времени, если я не смогу сделать это очень быстро. Есть идеи, как поступить?

Ответы [ 2 ]

1 голос
/ 06 февраля 2020
  • Вы хотите создать файл PDF, выбрав листы из таблицы Google.
    • В электронной таблице Google 15 листов.
    • Например, вы хотите выбрать 2 листа «Таблица1» и «Таблица2» и создать их в виде одного файла PDF. Затем файл PDF отправляется по электронной почте.
  • Вы хотите уменьшить стоимость процесса для достижения выше.
    • Вы хотите закончить sh, чтобы запустить скрипт за 20 секунд.
  • Вы хотите добиться этого с помощью скрипта Google Apps.

По твоему вопросу и ответу я мог понять как выше. Если мое понимание верно, как насчет этого ответа? Пожалуйста, подумайте об этом как об одном из нескольких возможных ответов.

В этом случае я подумал, что скрывающие листы, за исключением листов, которые вы хотите использовать, могут подойти. Для этого здесь я хотел бы предложить скрыть листы, используя метод spreadsheets.batchUpdate в Sheets API. Потому что я думал, что в этом случае стоимость процесса Sheets API может быть ниже, чем у сервиса Spreadsheet.

Поток:

Последовательность действий этого измененного сценария следующая.

  1. Скрыть листы, кроме листов, которые вы хотите создать в виде файла PDF.
  2. Создать файл PDF из электронной таблицы.
  3. Показать все листы.

Модифицированный скрипт:

Перед запуском скрипта включите Sheets API в Advanced Google services . И, пожалуйста, установите переменные sheetNames, email и spreadsheetId. И запустите функцию printtwopdfs().

function convertSpreadsheetToPdf(email, spreadsheetId, pdfName) {
  var spreadsheet = spreadsheetId ? SpreadsheetApp.openById(spreadsheetId) : SpreadsheetApp.getActiveSpreadsheet();
  var spreadsheetId = spreadsheetId ? spreadsheetId : spreadsheet.getId();
  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
  + '&id=' + spreadsheetId
  + '&size=A4'      // 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 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);
  }
}

// Please run this function.
function printtwopdfs() {
  var sheetNames = ["Table1", "Table2"];
  var email = "###";  // Please set email address.
  var spreadsheetId = "###";  // Please set Spreadsheet ID.

  // Hide sheets.
  var allSheets = SpreadsheetApp.openById(spreadsheetId).getSheets();
  var hiddenResource = allSheets.map(function(s) {
    var obj = {updateSheetProperties: {properties: {sheetId: s.getSheetId(), hidden: true}, fields: "hidden"}};
    if (sheetNames.indexOf(s.getSheetName()) != -1) obj.updateSheetProperties.properties.hidden = false;
    return obj;
  });
  Sheets.Spreadsheets.batchUpdate({requests: hiddenResource}, spreadsheetId);

  // Create PDF file.
  convertSpreadsheetToPdf(email, spreadsheetId, "pdfteste");

  // Show all sheets.
  var showResource = allSheets.map(function(s) {return {updateSheetProperties: {properties: {sheetId: s.getSheetId(), hidden: false}, fields: "hidden"}}});
  Sheets.Spreadsheets.batchUpdate({requests: showResource}, spreadsheetId);
}

Примечание:

  • В моей среде, когда вышеуказанный скрипт используется для электронной таблицы Google, включающей 20 листов, значения которых находятся в клетки, время процесса составляло около 5 секунд. Но я не уверен, может ли это быть использовано в вашей реальной ситуации. Я прошу прощения за это.

Ссылки:

0 голосов
/ 05 февраля 2020

Если я вас правильно понимаю:

  • Вы хотите напечатать некоторые, но не все листы в одном PDF.
  • Это можно сделать, скрыв ненужные листы и распечатав полная электронная таблица (печатаются только невидимые листы).
  • Нежелательно прятать и показывать ненужные листы неудобно каждый раз, когда вы хотите напечатать PDF, особенно когда их много.

Если вышеприведенное верно, то вы можете использовать сценарий, чтобы сначала спрятать ненужные листы, затем распечатать PDF-файл и, наконец, снова показать эти нежелательные листы. Это можно сделать следующим образом (проверьте встроенные комментарии для получения более подробной информации):

function convertSpreadsheetToPdf(email, spreadsheetId, sheetsToPrint) {
  var ss = SpreadsheetApp.openById(spreadsheetId);
  // Get the names of all sheets in the spreadsheet:
  var allSheets = ss.getSheets().map(function(sheet) {
    return sheet.getName();
  });
  // Get the names of the sheets to ignore:
  var sheetsToHide = allSheets.filter(function(sheetName) {
    return sheetsToPrint.indexOf(sheetName) === -1;
  });
  // Hide the sheets to ignore:
  sheetsToHide.forEach(function(sheetName) {
    var sheet = ss.getSheetByName(sheetName);
    sheet.hideSheet();
  })
  var pdfName = ss.getName();
  var parents = DriveApp.getFileById(spreadsheetId).getParents();
  var folder = parents.hasNext() ? parents.next() : DriveApp.getRootFolder();
  var url_base = ss.getUrl().replace(/edit$/,'');  
  var url_ext = 'export?exportFormat=pdf&format=pdf'   //export as pdf  
  // Print either the entire Spreadsheet (only unhidden sheets):
  + '&id=' + spreadsheetId 
  // following parameters are optional...
  + '&size=A4'      // 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 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);
  }
  // Show the ignored sheets:
  sheetsToHide.forEach(function(sheetName) {
    var sheet = ss.getSheetByName(sheetName);
    sheet.showSheet();
  })    
}

Эта функция принимает email, spreadsheetId и массив, состоящий из имен листов для печати. в качестве параметров. Возможный вызов может быть таким:

convertSpreadsheetToPdf("your-email@your-domain", "your-spreadsheet-id", ["Sheet1","Sheet2","Sheet5"])

Я немного упростил этот код, чтобы работать над этим (имя PDF-файла всегда является именем электронной таблицы, и вы всегда должны предоставлять идентификатор таблицы), но не стесняйтесь отменить эти изменения.

Ссылка:

Надеюсь, это поможет.

...