Google表格导出到PDF脚本 - 为什么它导出隐藏的行



我有一个用于在给定文件夹中保存单独的Google表作为PDF文档的脚本。

由于表的内容是动态的,有时在底部有一个空网格行,因此我在导出文件之前包括了一种无需内容的行的方法。

直到最近,这已经有效。现在,该函数隐藏了行,但创建的文件将行显示为未底定的行。

任何想法是否是由于最近更改Google表API的结果,并且我有什么可以恢复到旧功能的方法吗?

这是我以前有效的代码块:

// API function for saving a single sheet without hiding sheets
// *******************************************************************************

function singleSheetAPIExport(){
  // Get active spreadsheet URL
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var sheetName = 'Example';
  var main = ss.getSheetByName(sheetName)
  var folderID = '1wsxxxxxxblahblah' // Google Drive Folder ID
  Logger.log('maxrows: ' + main.getMaxRows());
  Logger.log('last row: ' + main.getLastRow());
  // Base URL
  var url = "https://docs.google.com/spreadsheets/d/SS_ID/export?".replace("SS_ID", ss.getId());
  /* Specify PDF export parameters
  From: https://code.google.com/p/google-apps-script-issues/issues/detail?id=3579
  */
  var url_ext = 'exportFormat=pdf&format=pdf'        // export as pdf / csv / xls / xlsx
  + '&size=letter'                                   // paper size legal / letter / A4
  + '&portrait=true'                                // orientation, false for landscape
  + '&fitw=true&source=labnol'                       // fit to page width, false for actual size
  + '&sheetnames=false&printtitle=false'             // hide optional headers and footers
  + '&pagenumbers=false&gridlines=false'             // hide page numbers and gridlines
  + '&fzr=false'                                     // do not repeat row headers (frozen rows) on each page
  + '&gid=';                                         // the sheet's Id
  var token = ScriptApp.getOAuthToken();
  // Hide All Empty Rows in the Print Sheet
  var maxRows = main.getMaxRows(); 
  var lastRow = main.getLastRow();
  if (maxRows-lastRow != 0){
    main.hideRows(lastRow+1, maxRows-lastRow);
  }
  // Get the response for your specific sheet that can later be converted to blob
  var response = UrlFetchApp.fetch(url + url_ext + main.getSheetId(), {
    headers: {
      'Authorization': 'Bearer ' +  token
    }
  });
  // Save pdf version
  var saveFolder = 'PDF';
  var parentFolder = DriveApp.getFolderById(folderID);
  var folder, folders = DriveApp.getFoldersByName(saveFolder);
   if (folders.hasNext()) {
     folder = folders.next();
   } else {
     folder = parentFolder.createFolder(saveFolder);
   }
  var name = main.getRange("B8").getValue(); 
  var cleanName = name.replace(/([^a-zA-Z0-9() #%~-])/g, "-");
  folder.createFile(response.getBlob().setName(cleanName));
  // Unhide the rows again
  var fullSheetRange = main.getRange(1,1,main.getMaxRows(), main.getMaxColumns());
  main.unhideRow(fullSheetRange); 
}

功能在6月17日至19日之间发生了变化,这可能暗示了对API的更改,但我无法找到任何更改的证据。

我之前将其发布到Stack Exchange的Web应用程序网站上,但在此处删除并重新发布了Google Apps Team推荐查询的Stackoverflow。

我在您提供的测试表上测试了您的代码,并且它适用于我。但是,如果我创建大量的额外行 - 的确,我可以重现您被导出的隐藏行的错误。

代码中的问题是,您在隐藏空行后立即创建文件,并在创建文件后立即将行放开:

您必须知道createFile()是异步请求 - 就像所有Google API调用一样。这意味着,如果创建可能需要更长的时间,则可以在创建文件之前执行您的unhideRow()方法。

类似地,如果您在隐藏所有行之前执行呼叫,这将导致您同样的问题。该解决方案在于使用SpreadsheetApp.flush();函数,该功能可以确保仅在上一个函数完成后才执行功能。folder.createFile(response.getBlob().setName(cleanName));之前和之后插入SpreadsheetApp.flush();解决您的问题。

还有另一种方法可以将纸将其导出到PDF文件,这指示了所需的导出单元格。而且您无需隐藏不必要的行。

function exportPDF(ssID,source,options,format){
  var dt=new Date();
  var d=encodeDate(dt.getFullYear(),dt.getMonth(),dt.getDate(),dt.getHours(),dt.getMinutes(),dt.getSeconds());
  var pc=[null,null,null,null,null,null,null,null,null,0,
          source,
          10000000,null,null,null,null,null,null,null,null,null,null,null,null,null,null,
          d,
          null,null,
          options,
          format,
          null,0,null,0];
  
 var js = " 
    <script> 
      window.open('https://docs.google.com/spreadsheets/d/"+ssID+"/pdf?esid="+(Math.round(Math.random()*10000000))+"&id="+ssID+"&a=true&pc="+JSON.stringify(pc)+"&gf=[]'); 
      google.script.host.close(); 
    </script> 
  ";
  
  var html = HtmlService.createHtmlOutput(js)
    .setHeight(10)
    .setWidth(100);
  SpreadsheetApp.getUi().showModalDialog(html, "Save To PDF"); 
}
function myExportPDF(){
  var as = SpreadsheetApp.getActiveSpreadsheet();
  var sheet = as.getActiveSheet();
  exportPDF(as.getId(), // Идентификатор таблицы
    [
      [sheet.getSheetId().toString(), // Sheet ID
       0,                             // vertical start border (from the first line)
       160,                           // vertical end boundary (160th line inclusive)
       0,                             // horizontal start border (from cell A)
       8                              // horizontal end boundary (cell H inclusive)
      ]
    ],
    [
      0,         // Do not show notes
      null,
      1,         // Show grid lines
      0,         // Do not show page numbers
      0,         // Do not show book title
      0,         // Do not show sheet title
      0,         // Do not show date
      0,         // Do not show time
      1,         // Repeat pinned rows
      1,         // Repeat pinned columns
      1,         // Page order down then up
      1,
      null,
      null,
      1,         // Left Alignment
      1          // Top Alignment
    ],
    [
      "A4",      // A4 sheet format
      1,         // Page Orientation Vertical
      2,         // Align to height
      1,
      [
        0.75,    // Top margin 0.75 inch
        0.75,    // Bottom margin 0.75 inch
        0.7,     // Left margin 0.7 inch
        0.7      // Right margin 0.7 inch
      ]
    ]
  );
}

我的网站上有一个详细的描述https://kandiral.ru/googlescript/eksport_tablic_google_sheets_v_pdf_fajl.html

upd:上面的代码用于下载PDF文件。这是一个可以保存到Google Drive

的脚本
function exportPDFtoGDrive(ssID,filename,source,options,format){
  var dt=new Date();
  var d=encodeDate(dt.getFullYear(),dt.getMonth(),dt.getDate(),dt.getHours(),dt.getMinutes(),dt.getSeconds());
  var pc=[null,null,null,null,null,null,null,null,null,0,
          source,
          10000000,null,null,null,null,null,null,null,null,null,null,null,null,null,null,
          d,
          null,null,
          options,
          format,
          null,0,null,0];
  
  var folder=null;
  var parents = DriveApp.getFileById(ssID).getParents();
  if (parents.hasNext())folder = parents.next();
  else folder = DriveApp.getRootFolder();
  
  var options = {
    'method': 'post',
    'payload': "a=true&pc="+JSON.stringify(pc)+"&gf=[]",
    'headers': {Authorization: "Bearer " + ScriptApp.getOAuthToken()},
    'muteHttpExceptions': true
  };
  var theBlob = UrlFetchApp.fetch("https://docs.google.com/spreadsheets/d/"+ssID+"/pdf?id="+ssID, options).getBlob();
  folder.createFile(theBlob).setName(filename+".pdf");
}
function myExportPDFtoGDrive(){
  var as = SpreadsheetApp.getActiveSpreadsheet();
  var sheet = as.getActiveSheet();
  var filename = as.getName()+" "+sheet.getName();
  exportPDFtoGDrive(
    as.getId(),  // Идентификатор таблицы
    filename,    // Имя файла
    [[sheet.getSheetId().toString(),0,160,0,8]],
    [0,null,1,0,0,0,0,0,1,1,1,1,null,null,1,1],
    ["A4",1,2,1,[0.75,0.75,0.7,0.7]]
  );
}

upd:添加了ESID变量以下载请求

最新更新