导出Google Sheet为PDF时如何设置分页符在指定行实现分页
Google Sheet导出PDF固定第10行分页实现方案
修改说明
- 保留原有脚本的全部导出功能,仅新增分页逻辑
- 实现逻辑:先在工作表第10行插入手动分页符,导出参数开启分页符识别,导出PDF时自动按分页符拆分页面
核心修改点
- 在
_getAsBlob函数的导出URL参数中添加&pagebreaks=true,开启分页符识别 - 在对应导出函数开头,新增第10行分页符插入逻辑
修改后完整代码
var saveToRootFolder = false function onOpen() { SpreadsheetApp.getUi() .createAddonMenu() .addItem('导出所有工作表', 'exportAsPDF') .addItem('将所有工作表导出为独立文件', 'exportAllSheetsAsSeparatePDFs') .addItem('导出当前工作表', 'exportCurrentSheetAsPDF') .addItem('导出选中区域', 'exportPartAsPDF') .addItem('导出预设区域', '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); // 展示导出成功弹窗 const htmlOutput = HtmlService .createHtmlOutput('<p>点击打开 <a href="' + pdfFile.getUrl() + '" target="_blank">' + fileName + '</a></p>') .setWidth(300) .setHeight(80) SpreadsheetApp.getUi().showModalDialog(htmlOutput, '导出成功') } function exportAsPDF() { var spreadsheet = SpreadsheetApp.getActiveSpreadsheet() // 给所有工作表第10行插入分页符 spreadsheet.getSheets().forEach(sheet => { sheet.setRowBreak(9) }) 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() } 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' // 改为CENTER可在页面底部打印页码 + '&gridlines=true' + '&fzr=FALSE' + '&pagebreaks=true' // 新增:开启手动分页符识别 + 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) { // 导出频率过高,重试 Utilities.sleep(3000) } else { break } } if (i === 5) { throw new Error('导出失败,待导出工作表数量过多') } 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) // 给当前工作表第10行插入分页符 sheet.setRowBreak(9) 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>点击打开PDF文件</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, '导出成功') } function exportCurrentSheetAsPDF() { var spreadsheet = SpreadsheetApp.getActiveSpreadsheet() var currentSheet = SpreadsheetApp.getActiveSheet() // 给当前工作表第10行插入分页符 currentSheet.setRowBreak(9) 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('请至少选择一个待导出的区域') return } selectedRanges = activeRangeList.getRanges() fileSuffix = '-selected' } if (selectedRanges.length === 1) { // 带格式导出特殊场景 var currentSheet = selectedRanges[0].getSheet() currentSheet.setRowBreak(9) 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()) // 给临时表第10行插入分页符 destSheet.setRowBreak(9) } // 删除空的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('找到命名区域 ' + namedRange.getName()) toPrintNamedRanges.push(namedRange.getRange()) } } if (toPrintNamedRanges.length === 0) { SpreadsheetApp.getUi().alert('未找到打印区域,请在菜单 数据 > 命名区域 中添加至少一个以`print_area_`开头的命名区域') return } else { toPrintNamedRanges.sort(function (a, b) { return a.getSheet().getIndex() - b.getSheet().getIndex() }) exportPartAsPDF(toPrintNamedRanges) } }
可选配置
如果你不需要在原始表格中保留分页符,可在导出完成的逻辑后添加代码删除分页符,示例:
// 导出完成后删除第10行的分页符 currentSheet.removeRowBreak(9)
内容的提问来源于stack exchange,提问作者NOOR UL KARIM
相关产品推荐
相关产品推荐

