有没有办法将电子表格的多个选项卡(但不是全部)打印为一个 pdf?
Is there a way to print multiple tabs of a spreadsheet (but not all of them) as a single pdf?
我已经做了一些研究,但还没有找到任何方法来做到这一点。尝试按照安德鲁·罗伯茨 (Andrew Roberts) 在此处 http://www.andrewroberts.net/2017/03/apps-script-create-pdf-multi-sheet-google-sheet/ 的解释将点差 sheet(或特定标签)转换为 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")
})}
但我得到的是 每个 sheet 分别打印为一个 pdf。
隐藏除我想要的以外的所有选项卡并打印跨页sheet 对我来说不是一个选项,因为它有太多选项卡(大约 15 个)。除此之外,我不太可能将选定的 sheet 复制到新的传播 sheet 中,因为该函数将花费太长时间到 运行,除非我可以非常快地完成此操作。关于如何进行的任何想法?
如果我理解正确的话:
- 您想在单个 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 的名称始终是电子表格的名称,您始终必须提供电子表格 ID),但随时可以还原这些更改.
参考:
希望对您有所帮助。
- 您想通过 selecting 来自 Google 电子表格的表格来创建 PDF 文件。
- Google 电子表格有 15 张。
- 例如,您想要 select 2 张 "Table1" 和 "Table2",并希望将它们创建为一个 PDF 文件。然后,PDF 文件作为电子邮件发送。
- 您想降低实现上述过程的成本。
- 您想在 20 秒内完成 运行 脚本。
- 您想使用 Google Apps 脚本实现此目的。
从你的提问和回复来看,我大概理解了上面的意思。如果我的理解是正确的,那么这个答案呢?请将此视为几个可能的答案之一。
在这种情况下,我认为除了要使用的工作表之外隐藏其他工作表可能是合适的。为此,在这里,我想建议在SheetsAPI中使用spreadsheets.batchUpdate的方法隐藏sheets。因为我认为在这种情况下,Sheets API 的处理成本可以低于 Spreadsheet 服务
流量:
修改后的脚本流程如下
- 隐藏工作表,但要创建为 PDF 文件的工作表除外。
- 从电子表格创建 PDF 文件。
- 显示所有工作表。
修改后的脚本:
在您 运行 脚本 please enable Sheets API at 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 秒的处理时间。但是我不确定这是否可以用于您的实际情况。对此我深表歉意。
参考文献:
我已经做了一些研究,但还没有找到任何方法来做到这一点。尝试按照安德鲁·罗伯茨 (Andrew Roberts) 在此处 http://www.andrewroberts.net/2017/03/apps-script-create-pdf-multi-sheet-google-sheet/ 的解释将点差 sheet(或特定标签)转换为 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")
})}
但我得到的是 每个 sheet 分别打印为一个 pdf。
隐藏除我想要的以外的所有选项卡并打印跨页sheet 对我来说不是一个选项,因为它有太多选项卡(大约 15 个)。除此之外,我不太可能将选定的 sheet 复制到新的传播 sheet 中,因为该函数将花费太长时间到 运行,除非我可以非常快地完成此操作。关于如何进行的任何想法?
如果我理解正确的话:
- 您想在单个 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 的名称始终是电子表格的名称,您始终必须提供电子表格 ID),但随时可以还原这些更改.
参考:
希望对您有所帮助。
- 您想通过 selecting 来自 Google 电子表格的表格来创建 PDF 文件。
- Google 电子表格有 15 张。
- 例如,您想要 select 2 张 "Table1" 和 "Table2",并希望将它们创建为一个 PDF 文件。然后,PDF 文件作为电子邮件发送。
- 您想降低实现上述过程的成本。
- 您想在 20 秒内完成 运行 脚本。
- 您想使用 Google Apps 脚本实现此目的。
从你的提问和回复来看,我大概理解了上面的意思。如果我的理解是正确的,那么这个答案呢?请将此视为几个可能的答案之一。
在这种情况下,我认为除了要使用的工作表之外隐藏其他工作表可能是合适的。为此,在这里,我想建议在SheetsAPI中使用spreadsheets.batchUpdate的方法隐藏sheets。因为我认为在这种情况下,Sheets API 的处理成本可以低于 Spreadsheet 服务
流量:
修改后的脚本流程如下
- 隐藏工作表,但要创建为 PDF 文件的工作表除外。
- 从电子表格创建 PDF 文件。
- 显示所有工作表。
修改后的脚本:
在您 运行 脚本 please enable Sheets API at 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 秒的处理时间。但是我不确定这是否可以用于您的实际情况。对此我深表歉意。