在Apps Script中将单个工作表导出为PDF

8
我有一个包含多个工作表的电子表格。我想每次导出其中的两个工作表。其中,Sheet One(工作表一)是包含信息的工作表,Sheet Two(工作表二)是需要提供给客户的工作表,它从Sheet One中引用数据。
目前,我会创建一个新的临时电子表格,将Sheet One复制到新电子表格中,然后再将Sheet Two复制到临时电子表格中。接下来,我将临时电子表格转换为PDF格式,然后删除临时电子表格,并将PDF保存到Google Drive文件夹中。
生成的PDF包含两个工作表各两页。但我只需要Sheet Two。如果我仅传输Sheet Two,则该工作表上会有许多#REF错误,因为Sheet One不存在。是否有方法可以仅导出Sheet Two而不会产生#REF错误?
以下是我的代码:
//create a temporary spreadsheet, copy both files onto it
var newSpreadsheet = SpreadsheetApp.create(nameOfSheet);
var d = ss.getSheetByName('Data').copyTo(newSpreadsheet); //the sheet     with all the information
d.setName('Data');

sheetToCopy.copyTo(newSpreadsheet); //the sheet that uses references from the data sheet
newSpreadsheet.deleteSheet(newSpreadsheet.getSheetByName("Sheet1")); //delete the original sheet of the new spreadsheet
var blobOfNewSpreadsheet = newSpreadsheet.getBlob(); //create pdf
folder.createFile(blobOfNewSpreadsheet); //add to folder


//delete the temporary spreadsheet2
var deleteSpreadsheet = DriveApp.getFileById(newSpreadsheet.getId());
deleteSpreadsheet.setTrashed(true);
3个回答

12

当通过getBlob导出电子表格时,隐藏的工作表不会被包括在内。因此,在导出之前,您可以暂时隐藏任何不需要的工作表。

function export() {    
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var sheet = ss.getSheetByName('Unwanted Sheet');
  sheet.hideSheet();
  DriveApp.createFile(ss.getBlob());
  sheet.showSheet();
}

以上代码只隐藏了一个工作表,在您的问题背景下已经足够。这里有一个版本,可以将除一个之外的所有工作表都隐藏起来。

function exportSheet(sheetName) {    
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var sheets = ss.getSheets();
  for (var i = 0; i < sheets.length; i++) {
    if (sheets[i].getSheetName() !== sheetName) {
      sheets[i].hideSheet()
    }
  }
  DriveApp.createFile(ss.getBlob());
  for (var i = 0; i < sheets.length; i++) {
    sheets[i].showSheet()
  }
}

1
很棒的解决方案!我想到的方法是复制我想要的工作表的显示值,而不是每个单元格的引用。这个解决方案速度更快。 - Kevin Bai
请注意,这将以纵向方向保存电子表格。 - user1251007

6

我有同样的问题,现在我已经尝试了许多解决方案,但以下代码是我所知道的最好的代码。此脚本不会创建临时表格,并且比旧方法快一些。

如果我说错了,请原谅我,只是为了让每个人受益而分享。

function generatePdf() {
  SpreadsheetApp.flush();
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var sourceSpreadsheet = SpreadsheetApp.getActive(); // Get active spreadsheet.
  var sheets = sourceSpreadsheet.getSheets(); // Get active sheet.
  var sheetName = sourceSpreadsheet.getActiveSheet().getName();
  var sourceSheet = sourceSpreadsheet.getSheetByName(sheetName);
  var pdfName = sheetName + ".pdf"; // Set the output filename as SheetName.
  var parents = DriveApp.getFileById(sourceSpreadsheet.getId()).getParents(); // Get folder containing spreadsheet to save pdf in.
  if (parents.hasNext()) {
    var folder = parents.next();
  } else {
    folder = DriveApp.getRootFolder();
  }
  var theBlob = createblobpdf(sheetName, pdfName);
  var newFile = folder.createFile(theBlob);
  var email = Session.getActiveUser().getEmail() || 'admin@gmail.com';
  var custemail = sourceSheet.getRange('A1').getValue();
  email = email + "," + custemail;
  // Subject of email message
  const subject = `Your subject Attachement: ${sheetName}`;
  // Email Body can  be HTML too with your image
  const body = "body";
  if (MailApp.getRemainingDailyQuota() > 0)
    GmailApp.sendEmail(email, subject, body, {
      htmlBody: body,
      attachments: [theBlob]
    });
  // delete pdf if already exists
  var files = folder.getFilesByName(pdfName);
  while (files.hasNext()) {
    files.next().setTrashed(true);
  }
  sourceSpreadsheet.toast("Emailed to " + email, "Success");

}

function createblobpdf(sheetName, pdfName) {
  var sourceSpreadsheet = SpreadsheetApp.getActive();
  var sourceSheet = sourceSpreadsheet.getSheetByName(sheetName);
  var url = 'https://docs.google.com/spreadsheets/d/' + sourceSpreadsheet.getId() + '/export?exportFormat=pdf&format=pdf' // export as pdf / csv / xls / xlsx
    +    '&size=A4' // paper size legal / letter / A4
    +    '&portrait=true' // orientation, false for landscape
    +    '&fitw=true' // fit to page width, false for actual size
    +    '&sheetnames=true&printtitle=false' // hide optional headers and footers
    +    '&pagenum=RIGHT&gridlines=false' // hide page numbers and gridlines
    +    '&fzr=false' // do not repeat row headers (frozen rows) on each page
    +    '&horizontal_alignment=CENTER' //LEFT/CENTER/RIGHT
    +    '&vertical_alignment=TOP' //TOP/MIDDLE/BOTTOM
    +    '&gid=' + sourceSheet.getSheetId(); // the sheet's Id
  var token = ScriptApp.getOAuthToken();
  // request export url
  var response = UrlFetchApp.fetch(url, {
    headers: {
      'Authorization': 'Bearer ' + token
    }
  });
  var theBlob = response.getBlob().setName(pdfName);
  return theBlob;
};


谢谢您提供的解决方案。我一直在追寻类似的内容,但是没有找到所有查询参数的文档。您能否指点一下我呢?谢谢! - Dave in Ohio

3

顶部的解决方案对我没有用,即使使用了“修复”功能,引用也失效了。

但是以下方法有效。

这种方法更加优雅,因为它“隐藏”了你不需要的工作表,与最受欢迎的解决方案相反,后者复制了一个电子表格,删除了一些工作表,然后再下载它。

function exportSheet() { 
  var sheetName = "YOUR SHEET NAME HERE";
  var ss = SpreadsheetApp.openById("YOUR SPREADSHEET ID HERE");
  var sheets = ss.getSheets();
  for (var i = 0; i < sheets.length; i++) {
    if (sheets[i].getSheetName() !== sheetName) {
      sheets[i].hideSheet()
    }
  }
  var newFile = DriveApp.createFile(ss.getBlob());
  for (var i = 0; i < sheets.length; i++) {
    sheets[i].showSheet()
  }
  newFile.moveTo(DriveApp.getFolderById("FolderID")); 
  //I just did this to move the file to somewhere else. 
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接