自定义 PDF 导出设置

SpreadJS 支持通过 PrintInfo 对象自定义 PDF 导出效果,包括打印区域、重复打印行列、页眉页脚、网格线、边框等多种打印选项。用户可以根据实际需求灵活配置导出参数,生成符合业务要求的 PDF 文档。

概述 本 Demo 展示了如何通过 PrintInfo 对象自定义 PDF 导出设置。Demo 提供了一个交互式界面,用户可以通过表单控件调整各种打印选项,包括打印区域、重复打印行列、页眉页脚内容及图片等,然后一键导出为 PDF 文件。 实现思路 初始化 Spread 工作簿,加载预设的表格数据 调用 sheet.printInfo() 获取打印信息对象,设置默认打印参数 将 PrintInfo 的各项属性值同步到界面表单控件中 用户修改表单控件后,点击"设置打印信息"按钮将配置应用到 PrintInfo 对象 点击"导出 PDF"按钮,调用 spread.savePDF() 方法导出 PDF 文件 代码解析 获取打印信息对象 通过 sheet.printInfo() 方法获取当前工作表的打印信息对象。PrintInfo 对象包含了所有与打印相关的配置项。 设置打印区域 这四个方法用于定义打印区域,只有指定范围内的单元格会被打印到 PDF 中。 设置重复打印行列 这些方法用于设置在每页重复打印的行列,适用于多页打印时需要显示表头的场景。 设置打印样式 showRowHeader 和 showColumnHeader 方法接受 PrintVisibilityType 枚举值,包括 inherit(继承)、hide(隐藏)、show(显示)和 showOnce(仅显示一次)。 设置页眉页脚 页眉页脚支持特殊格式代码: &P:当前页码 &N:总页数 &G:图片占位符 &D:当前日期 &T:当前时间 导出 PDF 文件 savePDF 方法接收成功回调和错误回调两个参数,成功时返回 Blob 对象,可以通过 saveAs 方法保存为文件。 运行效果 页面左侧显示包含运动员数据的表格,右侧显示打印设置面板 用户可以调整打印区域(起始行/列、结束行/列) 可以设置重复打印的行列(适用于多页打印时的表头) 可以配置是否显示边框、网格线、黑白打印模式 可以设置行标题和列标题的显示方式 可以配置页眉页脚的左、中、右三个区域的内容和图片 点击"设置打印信息"按钮将配置应用到表格 点击"导出 PDF"按钮生成并下载 PDF 文件 API 参考 printInfo() 方法 获取工作表的打印信息对象,用于配置打印和 PDF 导出选项。 打印区域方法 rowStart(value):设置打印起始行索引 rowEnd(value):设置打印结束行索引 columnStart(value):设置打印起始列索引 columnEnd(value):设置打印结束列索引 重复打印方法 repeatRowStart(value):设置每页顶部重复打印的起始行 repeatRowEnd(value):设置每页顶部重复打印的结束行 repeatColumnStart(value):设置每页左侧重复打印的起始列 repeatColumnEnd(value):设置每页左侧重复打印的结束列 打印样式方法 showBorder(value):是否打印外边框 showGridLine(value):是否打印网格线 blackAndWhite(value):是否黑白打印 showRowHeader(type):行标题显示方式 showColumnHeader(type):列标题显示方式 页眉页脚方法 headerLeft(text):页眉左侧内容 headerCenter(text):页眉中间内容 headerRight(text):页眉右侧内容 footerLeft(text):页脚左侧内容 footerCenter(text):页脚中间内容 footerRight(text):页脚右侧内容 headerLeftImage(path):页眉左侧图片路径 headerCenterImage(path):页眉中间图片路径 headerRightImage(path):页眉右侧图片路径 footerLeftImage(path):页脚左侧图片路径 footerCenterImage(path):页脚中间图片路径 footerRightImage(path):页脚右侧图片路径 savePDF() 方法 successCallback:导出成功的回调函数,参数为 Blob 对象 errorCallback:导出失败的回调函数 options:可选,PDF 文档属性(title、author、subject、keywords、creator) sheetIndex:可选,指定要导出的工作表索引,不指定则导出所有可见工作表
function _getElementById(id) { return document.getElementById(id); } window.onload = function () { var spread = new GC.Spread.Sheets.Workbook(document.getElementById("ss"), {sheetCount: 1}); initSpread(spread); _getElementById('btnSetPrintInfo').onclick = function () { function setPrintInfoNumberValueItem(printInfo, key) { var value = parseInt(_getElementById(key).value); if (!isNaN(value)) { printInfo[key](value); } } var sheet = spread.getActiveSheet(), printInfo = sheet.printInfo(); ["rowStart", "rowEnd", "columnStart", "columnEnd", "repeatRowStart", "repeatRowEnd", "repeatColumnStart", "repeatColumnEnd" ].forEach(function (name) { setPrintInfoNumberValueItem(printInfo, name); }); printInfo.showBorder(_getElementById('showBorder').checked); printInfo.showGridLine(_getElementById('showGridLine').checked); printInfo.blackAndWhite(_getElementById('blackAndWhite').checked); printInfo.showRowHeader(+_getElementById('showRowHeader').value); printInfo.showColumnHeader(+_getElementById('showColumnHeader').value); printInfo.headerLeft(_getElementById('headerLeft').value); printInfo.headerLeftImage(_getElementById('headerLeftImage').value); printInfo.headerCenter(_getElementById('headerCenter').value); printInfo.headerCenterImage(_getElementById('headerCenterImage').value); printInfo.headerRight(_getElementById('headerRight').value); printInfo.headerRightImage(_getElementById('headerRightImage').value); printInfo.footerLeft(_getElementById('footerLeft').value); printInfo.footerLeftImage(_getElementById('footerLeftImage').value); printInfo.footerCenter(_getElementById('footerCenter').value); printInfo.footerCenterImage(_getElementById('footerCenterImage').value); printInfo.footerRight(_getElementById('footerRight').value); printInfo.footerRightImage(_getElementById('footerRightImage').value); }; }; function adjustLayoutForPrint(sheet) { sheet.setRowHeight(0, 30); sheet.getRange(0, 0, 1, 5).hAlign(1).vAlign(1).font("bold 14px Times"); sheet.setColumnWidth(0, 220); sheet.setColumnWidth(2, 120); sheet.setColumnWidth(3, 50); sheet.setColumnWidth(4, 180); sheet.getRange(1, 0, 200, 5).textIndent(1); sheet.getRange(-1, 3, -1, 1).hAlign(1).textIndent(0); sheet.addColumns(0, 1); sheet.setColumnWidth(0, 30); for (var r = 5; r <= 200; r += 5) { sheet.getCell(r, 0) .text(r + '') .font("normal 9px Times"); } sheet.addRows(0, 1); sheet.setRowHeight(0, 10); sheet.getRange(1, 1, 202, 5).setBorder(new GC.Spread.Sheets.LineBorder("black", GC.Spread.Sheets.LineStyle.thin), {all: true}); } function setPrintInfo(sheet) { var printInfo = sheet.printInfo(); // custom printInfo for default output printInfo.showBorder(false); printInfo.showGridLine(false); printInfo.blackAndWhite(false); printInfo.columnEnd(5); printInfo.repeatRowStart(0); printInfo.repeatRowEnd(1); printInfo.showColumnHeader(GC.Spread.Sheets.Print.PrintVisibilityType.hide); printInfo.showRowHeader(GC.Spread.Sheets.Print.PrintVisibilityType.hide); printInfo.headerCenter("Olympic Athletes"); printInfo.headerLeft("&G"); printInfo.headerLeftImage("$DEMOROOT$/spread/source/images/olympic.jpg"); printInfo.footerCenter("&P/&N"); // sync with UI setting items _getElementById('rowStart').value = printInfo.rowStart(); _getElementById('rowEnd').value = printInfo.rowEnd(); _getElementById('columnStart').value = printInfo.columnStart(); _getElementById('columnEnd').value = printInfo.columnEnd(); _getElementById('repeatRowStart').value = printInfo.repeatRowStart(); _getElementById('repeatRowEnd').value = printInfo.repeatRowEnd(); _getElementById('repeatColumnStart').value = printInfo.repeatColumnStart(); _getElementById('repeatColumnEnd').value = printInfo.repeatColumnEnd(); _getElementById('showBorder').checked = printInfo.showBorder(); _getElementById('showGridLine').checked = printInfo.showGridLine(); _getElementById('blackAndWhite').checked = printInfo.blackAndWhite(); _getElementById('showRowHeader').value = printInfo.showRowHeader(); _getElementById('showColumnHeader').value = printInfo.showColumnHeader(); _getElementById('headerLeft').value = printInfo.headerLeft(); _getElementById('headerLeftImage').value = printInfo.headerLeftImage(); _getElementById('headerCenter').value = printInfo.headerCenter(); _getElementById('headerCenterImage').value = printInfo.headerCenterImage(); _getElementById('headerRight').value = printInfo.headerRight(); _getElementById('headerRightImage').value = printInfo.headerRightImage(); _getElementById('footerLeft').value = printInfo.footerLeft(); _getElementById('footerLeftImage').value = printInfo.footerLeftImage(); _getElementById('footerCenter').value = printInfo.footerCenter(); _getElementById('footerCenterImage').value = printInfo.footerCenterImage(); _getElementById('footerRight').value = printInfo.footerRight(); _getElementById('footerRightImage').value = printInfo.footerRightImage(); } function initSpread(spread) { _getElementById('savePDF').onclick = function () { spread.savePDF(function (blob) { saveAs(blob, 'download.pdf'); }, console.log); }; var sd = data; if (sd && sd.sheets) { if (!spread) { return; } spread.suspendPaint(); spread.fromJSON(sd); var sheet = spread.sheets[0]; sheet.suspendPaint(); adjustLayoutForPrint(sheet); setPrintInfo(sheet); sheet.resumePaint(); spread.resumePaint(); } }
<!doctype html> <html style="height:100%;font-size:14px;"> <head> <meta name="spreadjs culture" content="zh-cn" /> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <link rel="stylesheet" type="text/css" href="$DEMOROOT$/zh/purejs/node_modules/@grapecity-software/spread-sheets/styles/gc.spread.sheets.excel2013white.css"> <script src="$DEMOROOT$/zh/purejs/node_modules/@grapecity-software/spread-sheets/dist/gc.spread.sheets.all.min.js" type="text/javascript"></script> <script src="$DEMOROOT$/spread/source/js/FileSaver.js" type="text/javascript"></script> <script src="$DEMOROOT$/zh/purejs/node_modules/@grapecity-software/spread-sheets-print/dist/gc.spread.sheets.print.min.js" type="text/javascript"></script> <script src="$DEMOROOT$/zh/purejs/node_modules/@grapecity-software/spread-sheets-pdf/dist/gc.spread.sheets.pdf.min.js" type="text/javascript"></script> <script src="$DEMOROOT$/zh/purejs/node_modules/@grapecity-software/spread-sheets-resources-zh/dist/gc.spread.sheets.resources.zh.min.js" type="text/javascript"></script> <script src="$DEMOROOT$/spread/source/js/license.js" type="text/javascript"></script> <script src="$DEMOROOT$/spread/source/data/exportPDF.js" type="text/javascript"></script> <script src="app.js" type="text/javascript"></script> <link rel="stylesheet" type="text/css" href="styles.css"> </head> <body> <div class="sample-tutorial"> <div id="ss" class="sample-spreadsheets"></div> <div class="options-container"> <div class="container"> <p>调整以下选项,然后点击 <b>设置打印信息</b> 按钮将这些选项应用到 Spread 打印信息中。</p> <p> 点击 <b>导出 PDF</b> 按钮,查看这些设置如何影响工作簿保存为 PDF 的方式。</p> <div class="row"> <div class="group"> <label>起始行:</label> <input id="rowStart"> </div> <div class="group"> <label>结束行:</label> <input id="rowEnd"> </div> </div> <div class="row"> <div class="group"> <label>起始列:</label> <input id="columnStart"> </div> <div class="group"> <label>结束列:</label> <input id="columnEnd"> </div> </div> <div class="row"> <div class="group"> <label>重复起始行:</label> <input id="repeatRowStart"> </div> <div class="group"> <label>重复结束行:</label> <input id="repeatRowEnd"> </div> </div> <div class="row"> <div class="group"> <label>重复起始列:</label> <input id="repeatColumnStart"> </div> <div class="group"> <label>重复结束列:</label> <input id="repeatColumnEnd"> </div> </div> <div class="row"> <div class="group"> <label> <input type="checkbox" id="showBorder"> 显示边框 </label> </div> <div class="group"> <label> <input type="checkbox" id="showGridLine"> 显示网格线 </label> </div> <div class="group"> <label> <input type="checkbox" id="blackAndWhite"> 黑白模式 </label> </div> </div> <div class="row"> <div class="group"> <label>显示行标题:</label> <select id="showRowHeader"> <option value="0">继承</option> <option value="1">隐藏</option> <option value="2">显示</option> <option value="3">仅显示一次</option> </select> </div> <div class="group"> <label>显示列标题:</label> <select id="showColumnHeader"> <option value="0">继承</option> <option value="1">隐藏</option> <option value="2">显示</option> <option value="3">仅显示一次</option> </select> </div> </div> <div class="row"> <div class="group"> <label>页眉左侧:</label> <input id="headerLeft"> </div> <div class="group"> <label>页眉左侧图片:</label> <select id="headerLeftImage"> <option value="$DEMOROOT$/spread/source/images/apple.jpg">苹果</option> <option value="$DEMOROOT$/spread/source/images/olympic.jpg">奥运</option> </select> </div> </div> <div class="row"> <div class="group"> <label>页眉居中:</label> <input id="headerCenter"> </div> <div class="group"> <label>页眉居中图片:</label> <select id="headerCenterImage"> <option value="$DEMOROOT$/spread/source/images/apple.jpg">苹果</option> <option value="$DEMOROOT$/spread/source/images/olympic.jpg">奥运</option> </select> </div> </div> <div class="row"> <div class="group"> <label>页眉右侧:</label> <input id="headerRight"> </div> <div class="group"> <label>页眉右侧图片:</label> <select id="headerRightImage"> <option value="$DEMOROOT$/spread/source/images/apple.jpg">苹果</option> <option value="$DEMOROOT$/spread/source/images/olympic.jpg">奥运</option> </select> </div> </div> <div class="row"> <div class="group"> <label>页脚左侧:</label> <input id="footerLeft"> </div> <div class="group"> <label>页脚左侧图片:</label> <select id="footerLeftImage"> <option value="$DEMOROOT$/spread/source/images/apple.jpg">苹果</option> <option value="$DEMOROOT$/spread/source/images/olympic.jpg">奥运</option> </select> </div> </div> <div class="row"> <div class="group"> <label>页脚居中:</label> <input id="footerCenter"> </div> <div class="group"> <label>页脚居中图片:</label> <select id="footerCenterImage"> <option value="$DEMOROOT$/spread/source/images/apple.jpg">苹果</option> <option value="$DEMOROOT$/spread/source/images/olympic.jpg">奥运</option> </select> </div> </div> <div class="row"> <div class="group"> <label>页脚右侧:</label> <input id="footerRight"> </div> <div class="group"> <label>页脚右侧图片:</label> <select id="footerRightImage"> <option value="$DEMOROOT$/spread/source/images/apple.jpg">苹果</option> <option value="$DEMOROOT$/spread/source/images/olympic.jpg">奥运</option> </select> </div> </div> <div class="row"> <div class="group"> <label></label> <input type="button" id="btnSetPrintInfo" value="设置打印信息"> </div> </div> <hr style="border: 1px solid white;border-bottom-color: lightgray;" /> <div> <input type="button" style="margin-bottom: 6px" value="导出 PDF" id="savePDF"> </div> </div> </div> </div> </body> </html>
.sample-tutorial { position: relative; height: 100%; overflow: hidden; } .sample-spreadsheets { width: calc(100% - 280px); height: 100%; overflow: hidden; float: left; } .options-container { float: right; width: 280px; padding: 12px; height: 100%; box-sizing: border-box; background: #fbfbfb; overflow: auto; } .option-row { font-size: 14px; padding: 5px; margin-top: 10px; } .container { width: 100%; height: calc(100% - 40px); box-sizing: border-box; } .group { padding-bottom: 8px; } label { display: inline-block; min-width: 130px; } input, select { margin-top: 6px; padding: 4px 6px; width: 100%; display: block; box-sizing: border-box; } input[type=checkbox] { width: auto; display: inline-block; } hr { border: 1px solid white; border-bottom-color: lightgray; } body { position: absolute; top: 0; bottom: 0; left: 0; right: 0; }