【发布时间】:2021-10-24 01:32:59
【问题描述】:
我想将当前的 google sheet 数据导出到 pdf 页面,但我确实希望在第 10 行有一个分页符,以便第 10 行之后的任何数据都进入下一页。这意味着将有多个页面用于更多数据。我不想在一页上打印所有数据。最终的 pdf 文件应该有多个页面用于跨谷歌表中第 10 行的数据
var saveToRootFolder = false
function onOpen() {
SpreadsheetApp.getUi()
.createAddonMenu()
.addItem('Export all sheets', 'exportAsPDF')
.addItem('Export all sheets as separate files', 'exportAllSheetsAsSeparatePDFs')
.addItem('Export current sheet', 'exportCurrentSheetAsPDF')
.addItem('Export selected area', 'exportPartAsPDF')
.addItem('Export predefined area', 'exportNamedRangesAsPDF')
.addToUi()
}
function _exportBlob(blob, fileName, spreadsheet) {
blob = blob.setName(SpreadsheetApp.getActiveSheet().getRange('E4:G4').getValue())
var folder = saveToRootFolder ? DriveApp : DriveApp.getFileById(spreadsheet.getId()).getParents().next()
var pdfFile = folder.createFile(blob)
var folder = DriveApp.getFolderById("FOLDER_ID");
pdfFile.moveTo(folder);
// Display a modal dialog box with custom HtmlService content.
const htmlOutput = HtmlService
.createHtmlOutput('<p>Click to open <a href="' + pdfFile.getUrl() + '" target="_blank">' + fileName + '</a></p>')
.setWidth(300)
.setHeight(80)
SpreadsheetApp.getUi().showModalDialog(htmlOutput, 'Export Successful')
}
function exportAsPDF() {
var spreadsheet = SpreadsheetApp.getActiveSpreadsheet()
var blob = _getAsBlob(spreadsheet.getUrl())
_exportBlob(blob, spreadsheet.getName(), spreadsheet)
}
function _getAsBlob(url, sheet, range) {
var rangeParam = ''
var sheetParam = ''
if (range) {
rangeParam =
'&r1=' + (range.getRow() - 1)
+ '&r2=' + range.getLastRow()
+ '&c1=' + (range.getColumn() - 1)
+ '&c2=' + range.getLastColumn()
}
if (sheet) {
sheetParam = '&gid=' + sheet.getSheetId()
}
// A credit to https://gist.github.com/Spencer-Easton/78f9867a691e549c9c70
// these parameters are reverse-engineered (not officially documented by Google)
// they may break overtime.
var exportUrl = url.replace(/\/edit.*$/, '')
+ '/export?exportFormat=pdf&format=pdf'
+ '&size=A4'
+ '&portrait=true'
+ '&fitw=true'
+ '&top_margin=0.2'
+ '&bottom_margin=0.2'
+ '&left_margin=0.2'
+ '&right_margin=0.1'
+ '&scale=3'
+ '&sheetnames=false&printtitle=false'
+ '&pagenum=UNDEFINED' // change it to CENTER to print page numbers
+ '&gridlines=true'
+ '&fzr=FALSE'
+ sheetParam
+ rangeParam
Logger.log('exportUrl=' + exportUrl)
var response
var i = 0
for (; i < 5; i += 1) {
response = UrlFetchApp.fetch(exportUrl, {
muteHttpExceptions: true,
headers: {
Authorization: 'Bearer ' + ScriptApp.getOAuthToken(),
},
})
if (response.getResponseCode() === 429) {
// printing too fast, retrying
Utilities.sleep(3000)
} else {
break
}
}
if (i === 5) {
throw new Error('Printing failed. Too many sheets to print.')
}
return response.getBlob()
}
function exportAllSheetsAsSeparatePDFs() {
var spreadsheet = SpreadsheetApp.getActiveSpreadsheet()
var files = []
var folder = saveToRootFolder ? DriveApp : DriveApp.getFileById(spreadsheet.getId()).getParents().next()
spreadsheet.getSheets().forEach(function (sheet) {
spreadsheet.setActiveSheet(sheet)
var blob = _getAsBlob(spreadsheet.getUrl(), sheet)
var fileName = sheet.getName()
blob = blob.setName(fileName)
var pdfFile = folder.createFile(blob)
files.push({
url: pdfFile.getUrl(),
name: fileName,
})
})
const htmlOutput = HtmlService
.createHtmlOutput('<p>Click to open PDF files</p>'
+ '<ul>'
+ files.reduce(function (prev, file) {
prev += '<li><a href="' + file.url + '" target="_blank">' + file.name + '</a></li>'
return prev
}, '')
+ '</ul>')
.setWidth(300)
.setHeight(150)
SpreadsheetApp.getUi().showModalDialog(htmlOutput, 'Export Successful')
}
function exportCurrentSheetAsPDF() {
var spreadsheet = SpreadsheetApp.getActiveSpreadsheet()
var currentSheet = SpreadsheetApp.getActiveSheet()
var blob = _getAsBlob(spreadsheet.getUrl(), currentSheet)
_exportBlob(blob, currentSheet.getName(), spreadsheet)
}
function exportPartAsPDF(predefinedRanges) {
var ui = SpreadsheetApp.getUi()
var spreadsheet = SpreadsheetApp.getActiveSpreadsheet()
var selectedRanges
var fileSuffix
if (predefinedRanges) {
selectedRanges = predefinedRanges
fileSuffix = '-predefined'
} else {
var activeRangeList = spreadsheet.getActiveRangeList()
if (!activeRangeList) {
ui.alert('Please select at least one range to export')
return
}
selectedRanges = activeRangeList.getRanges()
fileSuffix = '-selected'
}
if (selectedRanges.length === 1) {
// special export with formatting
var currentSheet = selectedRanges[0].getSheet()
var blob = _getAsBlob(spreadsheet.getUrl(), currentSheet, selectedRanges[0])
var fileName = spreadsheet.getName() + fileSuffix
_exportBlob(blob, fileName, spreadsheet)
return
}
var tempSpreadsheet = SpreadsheetApp.create(spreadsheet.getName() + fileSuffix)
if (!saveToRootFolder) {
DriveApp.getFileById(tempSpreadsheet.getId()).moveTo(DriveApp.getFileById(spreadsheet.getId()).getParents().next())
}
var tempSheets = tempSpreadsheet.getSheets()
var sheet1 = tempSheets.length > 0 ? tempSheets[0] : undefined
SpreadsheetApp.setActiveSpreadsheet(tempSpreadsheet)
tempSpreadsheet.setSpreadsheetTimeZone(spreadsheet.getSpreadsheetTimeZone())
tempSpreadsheet.setSpreadsheetLocale(spreadsheet.getSpreadsheetLocale())
for (var i = 0; i < selectedRanges.length; i++) {
var selectedRange = selectedRanges[i]
var originalSheet = selectedRange.getSheet()
var originalSheetName = originalSheet.getName()
var destSheet = tempSpreadsheet.getSheetByName(originalSheetName)
if (!destSheet) {
destSheet = tempSpreadsheet.insertSheet(originalSheetName)
}
Logger.log('a1notation=' + selectedRange.getA1Notation())
var destRange = destSheet.getRange(selectedRange.getA1Notation())
destRange.setValues(selectedRange.getValues())
destRange.setTextStyles(selectedRange.getTextStyles())
destRange.setBackgrounds(selectedRange.getBackgrounds())
destRange.setFontColors(selectedRange.getFontColors())
destRange.setFontFamilies(selectedRange.getFontFamilies())
destRange.setFontLines(selectedRange.getFontLines())
destRange.setFontStyles(selectedRange.getFontStyles())
destRange.setFontWeights(selectedRange.getFontWeights())
destRange.setHorizontalAlignments(selectedRange.getHorizontalAlignments())
destRange.setNumberFormats(selectedRange.getNumberFormats())
destRange.setTextDirections(selectedRange.getTextDirections())
destRange.setTextRotations(selectedRange.getTextRotations())
destRange.setVerticalAlignments(selectedRange.getVerticalAlignments())
destRange.setWrapStrategies(selectedRange.getWrapStrategies())
}
// remove empty Sheet1
if (sheet1) {
Logger.log('lastcol = ' + sheet1.getLastColumn() + ',lastrow=' + sheet1.getLastRow())
if (sheet1 && sheet1.getLastColumn() === 0 && sheet1.getLastRow() === 0) {
tempSpreadsheet.deleteSheet(sheet1)
}
}
exportAsPDF()
SpreadsheetApp.setActiveSpreadsheet(spreadsheet)
DriveApp.getFileById(tempSpreadsheet.getId()).setTrashed(true)
}
function exportNamedRangesAsPDF() {
var spreadsheet = SpreadsheetApp.getActiveSpreadsheet()
var allNamedRanges = spreadsheet.getNamedRanges()
var toPrintNamedRanges = []
for (var i = 0; i < allNamedRanges.length; i++) {
var namedRange = allNamedRanges[i]
if (/^print_area_.*$/.test(namedRange.getName())) {
Logger.log('found named range ' + namedRange.getName())
toPrintNamedRanges.push(namedRange.getRange())
}
}
if (toPrintNamedRanges.length === 0) {
SpreadsheetApp.getUi().alert('No print areas found. Please add at least one \'print_area_1\' named range in the menu Data > Named ranges.')
return
} else {
toPrintNamedRanges.sort(function (a, b) {
return a.getSheet().getIndex() - b.getSheet().getIndex()
})
exportPartAsPDF(toPrintNamedRanges)
}
}
【问题讨论】:
-
在 Google 表格或幻灯片中不提供休息时间 -- support.google.com/docs/answer/… 恐怕您还需要一项壮举:将表格放入 Document。或者等待@Tanaike 发明一些解决方法。
-
您好!除了@YuriKhristich 所说的之外,您还可以开发一个 Apps 脚本解决方案,该解决方案创建一个包含所需行的新工作表,然后将其转换为 PDF。在您的场景中,这会是一个有效的解决方案吗?
标签: javascript google-apps-script google-sheets export-to-pdf page-break