Custom PDF Export

Exporting SpreadJS to PDF files can be customized. The print settings in SpreadJS can be changed so you can export exactly the information that you need.

You can export all sheets or a specified sheet with the savePDF method: For each sheet, you can set detailed options by setting the sheet’s printInfo options:
<template> <div class="sample-tutorial"> <gc-spread-sheets class="sample-spreadsheets" @workbookInitialized="initSpread"> </gc-spread-sheets> <div class="options-container"> <div class="container"> <p>Adjust the options below then click the <b>Set PrintInfo</b> button to apply these options to the Spread PrintInfo.</p> <p> Click the <b>Export PDF</b> button to see how these settings affect the way the workbook is saved to PDF.</p> <div class="row"> <div class="group"> <label>RowStart:</label> <input v-model="printInfoRef.rowStart" id="rowStart" v-on:change="rowStartChange"> </div> <div class="group"> <label>RowEnd:</label> <input v-model="printInfoRef.rowEnd" id="rowEnd" v-on:change="rowEnd"> </div> </div> <div class="row"> <div class="group"> <label>ColumnStart:</label> <input v-model="printInfoRef.columnStart" id="columnStart" v-on:change="columnStart"> </div> <div class="group"> <label>ColumnEnd:</label> <input v-model="printInfoRef.columnEnd" id="columnEnd" v-on:change="columnEnd"> </div> </div> <div class="row"> <div class="group"> <label>RepeatRowStart:</label> <input v-model="printInfoRef.repeatRowStart" id="repeatRowStart" v-on:change="repeatRowStart"> </div> <div class="group"> <label>RepeatRowEnd:</label> <input id="repeatRowEnd" v-model="printInfoRef.repeatRowEnd" v-on:change="repeatRowEnd"> </div> </div> <div class="row"> <div class="group"> <label>RepeatColumnStart:</label> <input id="repeatColumnStart" v-model="printInfoRef.repeatColumnStart" v-on:change="repeatColumnStart"> </div> <div class="group"> <label>RepeatColumnEnd:</label> <input id="repeatColumnEnd" v-model="printInfoRef.repeatColumnEnd" v-on:change="repeatColumnEnd"> </div> </div> <div class="row"> <div class="group"> <label> <input type="checkbox" id="showBorder" v-model="printInfoRef.showBorder" v-on:change="showBorder"> ShowBorder </label> </div> <div class="group"> <label> <input type="checkbox" id="showGridLine" v-model="printInfoRef.showGridLine" v-on:change="showGridLine"> ShowGridLine </label> </div> <div class="group"> <label> <input type="checkbox" id="blackAndWhite" v-model="printInfoRef.blackAndWhite" v-on:change="blackAndWhite"> Black And White </label> </div> </div> <div class="row"> <div class="group"> <label>ShowRowHeader:</label> <select id="showRowHeader" v-model="printInfoRef.showRowHeader" v-on:change="showRowHeader"> <option value="0">Inherit</option> <option value="1">Hide</option> <option value="2">Show</option> <option value="3">ShowOnce</option> </select> </div> <div class="group"> <label>ShowColumnHeader:</label> <select id="showColumnHeader" v-model="printInfoRef.showColumnHeader" v-on:change="showColumnHeader"> <option value="0">Inherit</option> <option value="1">Hide</option> <option value="2">Show</option> <option value="3">ShowOnce</option> </select> </div> </div> <div class="row"> <div class="group"> <label>HeaderLeft:</label> <input id="headerLeft" v-model="printInfoRef.headerLeft" v-on:change="headerLeft"> </div> <div class="group"> <label>HeaderLeftImage:</label> <select id="headerLeftImage" v-model="printInfoRef.headerLeftImage" v-on:change="headerLeftImage"> <option value="$DEMOROOT$/spread/source/images/apple.jpg">Apple</option> <option value="$DEMOROOT$/spread/source/images/olympic.jpg">Olympic</option> </select> </div> </div> <div class="row"> <div class="group"> <label>HeaderCenter:</label> <input id="headerCenter" v-model="printInfoRef.headerCenter" v-on:change="headerCenter"> </div> <div class="group"> <label>HeaderCenterImage:</label> <select id="headerCenterImage" v-model="printInfoRef.headerCenterImage" v-on:change="headerCenterImage"> <option value="$DEMOROOT$/spread/source/images/apple.jpg">Apple</option> <option value="$DEMOROOT$/spread/source/images/olympic.jpg">Olympic</option> </select> </div> </div> <div class="row"> <div class="group"> <label>HeaderRight:</label> <input id="headerRight" v-model="printInfoRef.headerRight" v-on:change="headerRight"> </div> <div class="group"> <label>HeaderRightImage:</label> <select id="headerRightImage" v-model="printInfoRef.headerRightImage" v-on:change="headerRightImage"> <option value="$DEMOROOT$/spread/source/images/apple.jpg">Apple</option> <option value="$DEMOROOT$/spread/source/images/olympic.jpg">Olympic</option> </select> </div> </div> <div class="row"> <div class="group"> <label>FooterLeft:</label> <input id="footerLeft" v-model="printInfoRef.footerLeft" v-on:change="footerLeft"> </div> <div class="group"> <label>FooterLeftImage:</label> <select id="footerLeftImage" v-model="printInfoRef.footerLeftImage" v-on:change="footerLeftImage"> <option value="$DEMOROOT$/spread/source/images/apple.jpg">Apple</option> <option value="$DEMOROOT$/spread/source/images/olympic.jpg">Olympic</option> </select> </div> </div> <div class="row"> <div class="group"> <label>FooterCenter:</label> <input id="footerCenter" v-model="printInfoRef.footerCenter" v-on:change="footerCenter"> </div> <div class="group"> <label>FooterCenterImage:</label> <select id="footerCenterImage" v-model="printInfoRef.footerCenterImage" v-on:change="footerCenterImage"> <option value="$DEMOROOT$/spread/source/images/apple.jpg">Apple</option> <option value="$DEMOROOT$/spread/source/images/olympic.jpg">Olympic</option> </select> </div> </div> <div class="row"> <div class="group"> <label>FooterRight:</label> <input id="footerRight" v-model="printInfoRef.footerRight" v-on:change="footerRight"> </div> <div class="group"> <label>FooterRightImage:</label> <select id="footerRightImage" v-model="printInfoRef.footerRightImage" v-on:change="footerRightImage"> <option value="$DEMOROOT$/spread/source/images/apple.jpg">Apple</option> <option value="$DEMOROOT$/spread/source/images/olympic.jpg">Olympic</option> </select> </div> </div> <div class="row"> <div class="group"> <label></label> <input type="button" id="btnSetPrintInfo" value="Set PrintInfo" v-on:click='setPrintInfoBut'> </div> </div> <hr style="border: 1px solid white;border-bottom-color: lightgray;" /> <div> <input type="button" style="margin-bottom: 6px" value="Export PDF" id="savePDF" v-on:click='savePDF'> </div> </div> </div> </div> </template> <script setup> import '@mescius/spread-sheets-vue'; import { ref } from "vue"; import GC from "@mescius/spread-sheets"; import '@mescius/spread-sheets-print'; import '@mescius/spread-sheets-pdf'; const spreadNS = GC.Spread.Sheets; const spreadRef = ref(null); const autoGenerateColumns = ref(false); const printInfoRef = ref({ rowStart: -1, rowEnd: -1, columnStart: -1, columnEnd: 5, repeatRowStart: 0, repeatRowEnd: 1, repeatColumnStart: -1, repeatColumnEnd: -1, showBorder: false, showGridLine: false, blackAndWhite: false, showRowHeader: 1, showColumnHeader: 1, headerLeft: '', headerLeftImage: '', headerCenter: '', headerCenterImage: '', headerRight: '', footerLeft: '', headerRightImage: '', footerLeftImage: '', footerCenter: '', footerCenterImage: '', footerRight: '', footerRightImage: '' }); const footerRightImage = (e) => { printInfoRef.value.footerRightImage = e.target.value; } const footerRight = (e) => { printInfoRef.value.footerRight = e.target.value; } const footerCenterImage = (e) => { printInfoRef.value.footerCenterImage = e.target.value; } const footerCenter = (e) => { printInfoRef.value.footerCenter = e.target.value; } const footerLeftImage = (e) => { printInfoRef.value.footerLeftImage = e.target.value; } const headerRightImage = (e) => { printInfoRef.value.headerRightImage = e.target.value; } const footerLeft = (e) => { printInfoRef.value.footerLeft = e.target.value; } const headerRight = (e) => { printInfoRef.value.headerRight = e.target.value; } const headerCenterImage = (e) => { printInfoRef.value.headerCenterImage = e.target.value; } const headerCenter = (e) => { printInfoRef.value.headerCenter = e.target.value; } const headerLeftImage = (e) => { printInfoRef.value.headerLeftImage = e.target.value; } const headerLeft = (e) => { printInfoRef.value.headerLeft = e.target.value; } const showColumnHeader = (e) => { printInfoRef.value.showColumnHeader = e.target.value; } const showRowHeader = (e) => { printInfoRef.value.showRowHeader = e.target.value; } const blackAndWhite = (e) => { printInfoRef.value.blackAndWhite = e.target.checked; } const showGridLine = (e) => { printInfoRef.value.showGridLine = e.target.checked; } const showBorder = (e) => { printInfoRef.value.showBorder = e.target.checked; } const repeatColumnEnd = (e) => { printInfoRef.value.repeatColumnEnd = e.target.value; } const repeatColumnStart = (e) => { printInfoRef.value.repeatColumnStart = e.target.value; } const repeatRowEnd = (e) => { printInfoRef.value.repeatRowEnd = e.target.value; } const repeatRowStart = (e) => { printInfoRef.value.repeatRowStart = e.target.value; } const rowEnd = (e) => { printInfoRef.value.rowEnd = e.target.value; } const rowStartChange = (e) => { printInfoRef.value.rowStart = e.target.value; } const columnEnd = (e) => { printInfoRef.value.columnEnd = e.target.value; } const columnStart = (e) => { printInfoRef.value.columnStart = e.target.value; } const savePDF = () => { spreadRef.value.savePDF(function (blob) { saveAs(blob, 'download.pdf'); }, console.log); } const setPrintInfoBut = () => { const stateInfo = printInfoRef.value; function setPrintInfoNumberValueItem(printInfo, key) { let value = parseInt(stateInfo[key]); if (!isNaN(value)) { printInfo[key](value); } } let sheet = spreadRef.value.getActiveSheet(), printInfo = sheet.printInfo(); ["rowStart", "rowEnd", "columnStart", "columnEnd", "repeatRowStart", "repeatRowEnd", "repeatColumnStart", "repeatColumnEnd" ].forEach(function (name) { setPrintInfoNumberValueItem(printInfo, name); }); printInfo.showBorder(stateInfo.showBorder); printInfo.showGridLine(stateInfo.showGridLine); printInfo.blackAndWhite(stateInfo.blackAndWhite); printInfo.showRowHeader(parseInt(stateInfo.showRowHeader)); printInfo.showColumnHeader(parseInt(stateInfo.showColumnHeader)); printInfo.headerLeft(stateInfo.headerLeft); printInfo.headerLeftImage(stateInfo.headerLeftImage); printInfo.headerCenter(stateInfo.headerCenter); printInfo.headerCenterImage(stateInfo.headerCenterImage); printInfo.headerRight(stateInfo.headerRight); printInfo.headerRightImage(stateInfo.headerRightImage); printInfo.footerLeft(stateInfo.footerLeft); printInfo.footerLeftImage(stateInfo.footerLeftImage); printInfo.footerCenter(stateInfo.footerCenter); printInfo.footerCenterImage(stateInfo.footerCenterImage); printInfo.footerRight(stateInfo.footerRight); printInfo.footerRightImage(stateInfo.footerRightImage); } const initSpread = (spread) => { spreadRef.value = spread; let sd = data; if (sd && sd.sheets) { if (!spread) { return; } spread.suspendPaint(); spread.fromJSON(sd); let sheet = spread.sheets[0]; sheet.suspendPaint(); adjustLayoutForPrint(sheet); setPrintInfo(sheet); sheet.resumePaint(); spread.resumePaint(); } } const 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 (let 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 }); } const setPrintInfo = (sheet) => { let printInfo = sheet.printInfo(); let stateInfo = printInfoRef.value; // 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 stateInfo.rowStart = printInfo.rowStart(); stateInfo.rowEnd = printInfo.rowEnd(); stateInfo.columnStart = printInfo.columnStart(); stateInfo.columnEnd = printInfo.columnEnd(); stateInfo.repeatRowStart = printInfo.repeatRowStart(); stateInfo.repeatRowEnd = printInfo.repeatRowEnd(); stateInfo.repeatColumnStart = printInfo.repeatColumnStart(); stateInfo.repeatColumnEnd = printInfo.repeatColumnEnd(); stateInfo.showBorder = printInfo.showBorder(); stateInfo.showGridLine = printInfo.showGridLine(); stateInfo.blackAndWhite = printInfo.blackAndWhite(); stateInfo.showRowHeader = printInfo.showRowHeader(); stateInfo.showColumnHeader = printInfo.showColumnHeader(); stateInfo.headerLeft = printInfo.headerLeft(); stateInfo.headerLeftImage = printInfo.headerLeftImage(); stateInfo.headerCenter = printInfo.headerCenter(); stateInfo.headerCenterImage = printInfo.headerCenterImage(); stateInfo.headerRight = printInfo.headerRight(); stateInfo.headerRightImage = printInfo.headerRightImage(); stateInfo.footerLeft = printInfo.footerLeft(); stateInfo.footerLeftImage = printInfo.footerLeftImage(); stateInfo.footerCenter = printInfo.footerCenter(); stateInfo.footerCenterImage = printInfo.footerCenterImage(); stateInfo.footerRight = printInfo.footerRight(); stateInfo.footerRightImage = printInfo.footerRightImage(); } </script> <style scoped> #app { height: 100%; } .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; } </style>
<!DOCTYPE html> <html style="height:100%;font-size:14px;"> <head> <meta charset="utf-8" /> <meta http-equiv="X-UA-Compatible" content="IE=edge" /> <title>SpreadJS VUE</title> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <link rel="stylesheet" type="text/css" href="$DEMOROOT$/en/vue3/node_modules/@mescius/spread-sheets/styles/gc.spread.sheets.excel2013white.css"> <script src="$DEMOROOT$/en/vue3/node_modules/systemjs/dist/system.src.js"></script> <script src="./systemjs.config.js"></script> <script src="./compiler.js" type="module"></script> <script src="$DEMOROOT$/spread/source/js/FileSaver.js" type="text/javascript"></script> <script src="$DEMOROOT$/spread/source/data/exportPDF.js" type="text/javascript"></script> <script> var System = SystemJS; System.import("./src/app.js"); System.import('$DEMOROOT$/en/lib/vue3/license.js'); </script> </head> <body> <div id="app"></div> </body> </html>
(function (global) { SystemJS.config({ transpiler: 'plugin-babel', babelOptions: { es2015: true }, paths: { // paths serve as alias 'npm:': 'node_modules/' }, packageConfigPaths: [ './node_modules/*/package.json', "./node_modules/@mescius/*/package.json", "./node_modules/@babel/*/package.json", "./node_modules/@vue/*/package.json" ], map: { 'vue': "npm:vue/dist/vue.esm-browser.js", 'tiny-emitter': 'npm:tiny-emitter/index.js', 'plugin-babel': 'npm:systemjs-plugin-babel/plugin-babel.js', "systemjs-babel-build": "npm:systemjs-plugin-babel/systemjs-babel-browser.js", '@mescius/spread-sheets': 'npm:@mescius/spread-sheets/index.js', '@mescius/spread-sheets-vue': 'npm:@mescius/spread-sheets-vue/index.js', '@mescius/spread-sheets-print': 'npm:@mescius/spread-sheets-print/index.js', '@mescius/spread-sheets-pdf': 'npm:@mescius/spread-sheets-pdf/index.js', }, meta: { '*.css': { loader: 'systemjs-plugin-css' }, '*.vue': { loader: "../plugin-vue/index.js" } } }); })(this);