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.

The demo is being dynamically compiled to support real-time code editing... For quicker access to features, switch to the "JavaScript" tab for a smoother experience! :)
Description
app.component.ts
index.html
app.component.html
styles.css
Copy to CodeMine

You can export all sheets or a specified sheet with the savePDF method:

    spread.savePDF();    // export all sheets as PDF

For each sheet, you can set detailed options by setting the sheet’s printInfo options:

    var sheet = spread.sheets[0];
    var printInfo = sheet.printInfo();
    printInfo.showGridLine(false);
    printInfo.showRowHeader(GC.Spread.Sheets.Print.PrintVisibilityType.show);
    printInfo.showColumnHeader(GC.Spread.Sheets.Print.PrintVisibilityType.show);
    printInfo.blackAndWhite(true);
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:
import { Component, NgModule, enableProdMode } from '@angular/core'; import { BrowserModule } from '@angular/platform-browser'; import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; import { SpreadSheetsModule } from '@mescius/spread-sheets-angular'; import GC from '@mescius/spread-sheets'; import '@mescius/spread-sheets-print'; import '@mescius/spread-sheets-pdf'; import './styles.css'; @Component({ selector: 'app-component', templateUrl: 'src/app.component.html' }) export class AppComponent { spread: GC.Spread.Sheets.Workbook; printInfo = { 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: '' }; hostStyle = { width: 'calc(100% - 280px)', height: '100%', overflow: 'hidden', float: 'left' }; footerRightImage(e: any) { this.printInfo.footerRightImage = e.target.value; } footerRight(e: any) { this.printInfo.footerRight = e.target.value; } footerCenterImage(e: any) { this.printInfo.footerCenterImage = e.target.value; } footerCenter(e: any) { this.printInfo.footerCenter = e.target.value; } footerLeftImage(e: any) { this.printInfo.footerLeftImage = e.target.value; } headerRightImage(e: any) { this.printInfo.headerRightImage = e.target.value; } footerLeft(e: any) { this.printInfo.footerLeft = e.target.value; } headerRight(e: any) { this.printInfo.headerRight = e.target.value; } headerCenterImage(e: any) { this.printInfo.headerCenterImage = e.target.value; } headerCenter(e: any) { this.printInfo.headerCenter = e.target.value; } headerLeftImage(e: any) { this.printInfo.headerLeftImage = e.target.value; } headerLeft(e: any) { this.printInfo.headerLeft = e.target.value; } showColumnHeader(e: any) { this.printInfo.showColumnHeader = e.target.value; } showRowHeader(e: any) { this.printInfo.showRowHeader = e.target.value; } blackAndWhite(e: any) { this.printInfo.blackAndWhite = e.target.checked; } showGridLine(e: any) { this.printInfo.showGridLine = e.target.checked; } showBorder(e: any) { this.printInfo.showBorder = e.target.checked; } repeatColumnEnd(e: any) { this.printInfo.repeatColumnEnd = e.target.value; } repeatColumnStart(e: any) { this.printInfo.repeatColumnStart = e.target.value; } repeatRowEnd(e: any) { this.printInfo.repeatRowEnd = e.target.value; } repeatRowStart(e: any) { this.printInfo.repeatRowStart = e.target.value; } rowEnd(e: any) { this.printInfo.rowEnd = e.target.value; } rowStartChange(e: any) { this.printInfo.rowStart = e.target.value; } columnEnd(e: any) { this.printInfo.columnEnd = e.target.value; } columnStart(e: any) { this.printInfo.columnStart = e.target.value; } savePDF() { this.spread.savePDF(function (blob: any) { saveAs(blob, 'download.pdf'); }, console.log); } setPrintInfoBut() { const stateInfo = this.printInfo; function setPrintInfoNumberValueItem(printInfo: any, key: string) { let value = parseInt(stateInfo[key]); if (!isNaN(value)) { printInfo[key](value); } } let sheet = this.spread.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); } initSpread($event: any) { this.spread = $event.spread; let spread = this.spread; this.spread = spread; let sd = data; if (sd && sd.sheets) { if (!spread) { return; } spread.suspendPaint(); spread.fromJSON(sd); let sheet = spread.sheets[0]; sheet.suspendPaint(); this.adjustLayoutForPrint(sheet); this.setPrintInfo(sheet); sheet.resumePaint(); spread.resumePaint(); } } adjustLayoutForPrint(sheet: GC.Spread.Sheets.Worksheet) { 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}); } setPrintInfo(sheet: GC.Spread.Sheets.Worksheet) { let printInfo = sheet.printInfo(); let stateInfo = this.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 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(); } } @NgModule({ imports: [BrowserModule, SpreadSheetsModule], declarations: [AppComponent], exports: [AppComponent], bootstrap: [AppComponent] }) export class AppModule {} enableProdMode(); // Bootstrap application with hash style navigation and global services. platformBrowserDynamic().bootstrapModule(AppModule);
<!doctype html> <html style="height:100%;font-size:14px;"> <head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <link rel="stylesheet" type="text/css" href="$DEMOROOT$/en/angular/node_modules/@mescius/spread-sheets/styles/gc.spread.sheets.excel2013white.css"> <!-- Polyfills --> <script src="$DEMOROOT$/en/angular/node_modules/core-js/client/shim.min.js"></script> <script src="$DEMOROOT$/en/angular/node_modules/zone.js/fesm2015/zone.min.js"></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> <!-- SystemJS --> <script src="$DEMOROOT$/en/angular/node_modules/systemjs/dist/system.js"></script> <script src="systemjs.config.js"></script> <script> // workaround to load 'rxjs/operators' from the rxjs bundle System.import('rxjs').then(function (m) { System.import('@angular/compiler'); System.set(SystemJS.resolveSync('rxjs/operators'), System.newModule(m.operators)); System.import('$DEMOROOT$/en/lib/angular/license.ts'); System.import('./src/app.component'); }); </script> </head> <body> <app-component></app-component> </body> </html>
<div class="sample-tutorial"> <gc-spread-sheets [hostStyle]="hostStyle" (workbookInitialized)="initSpread($event)"> </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 id="rowStart" (change)="rowStartChange($event)" value="{{printInfo.rowStart}}"> </div> <div class="group"> <label>RowEnd:</label> <input id="rowEnd" (change)="rowEnd($event)" value="{{printInfo.rowEnd}}"> </div> </div> <div class="row"> <div class="group"> <label>ColumnStart:</label> <input id="columnStart" (change)="columnStart($event)" value="{{printInfo.columnStart}}"> </div> <div class="group"> <label>ColumnEnd:</label> <input id="columnEnd" (change)="columnEnd($event)" value="{{printInfo.columnEnd}}"> </div> </div> <div class="row"> <div class="group"> <label>RepeatRowStart:</label> <input id="repeatRowStart" value="{{printInfo.repeatRowStart}}" (change)="repeatRowStart($event)"> </div> <div class="group"> <label>RepeatRowEnd:</label> <input id="repeatRowEnd" value="{{printInfo.repeatRowEnd}}" (change)="repeatRowEnd($event)"> </div> </div> <div class="row"> <div class="group"> <label>RepeatColumnStart:</label> <input id="repeatColumnStart" value="{{printInfo.repeatColumnStart}}" (change)="repeatColumnStart($event)"> </div> <div class="group"> <label>RepeatColumnEnd:</label> <input id="repeatColumnEnd" value="{{printInfo.repeatColumnEnd}}" (change)="repeatColumnEnd($event)"> </div> </div> <div class="row"> <div class="group"> <label> <input type="checkbox" id="showBorder" value="{{printInfo.showBorder}}" (change)="showBorder($event)"> ShowBorder </label> </div> <div class="group"> <label> <input type="checkbox" id="showGridLine" value="{{printInfo.showGridLine}}" (change)="showGridLine($event)"> ShowGridLine </label> </div> <div class="group"> <label> <input type="checkbox" id="blackAndWhite" value="{{printInfo.blackAndWhite}}" (change)="blackAndWhite($event)"> Black And White </label> </div> </div> <div class="row"> <div class="group"> <label>ShowRowHeader:</label> <select id="showRowHeader" (change)="showRowHeader($event)" value="{{printInfo.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" (change)="showColumnHeader($event)" value="{{printInfo.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" (change)="headerLeft($event)" value="{{printInfo.headerLeft}}"> </div> <div class="group"> <label>HeaderLeftImage:</label> <select id="headerLeftImage" (change)="headerLeftImage($event)" value="{{printInfo.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" (change)="headerCenter($event)" value="{{printInfo.headerCenter}}"> </div> <div class="group"> <label>HeaderCenterImage:</label> <select id="headerCenterImage" (change)="headerCenterImage($event)" value="{{printInfo.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" (change)="headerRight($event)" value="{{printInfo.headerRight}}"> </div> <div class="group"> <label>HeaderRightImage:</label> <select id="headerRightImage" (change)="headerRightImage($event)" value="{{printInfo.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" (change)="footerLeft($event)" value="{{printInfo.footerLeft}}"> </div> <div class="group"> <label>FooterLeftImage:</label> <select id="footerLeftImage" (change)="footerLeftImage($event)" value="{{printInfo.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" (change)="footerCenter($event)" value="{{printInfo.footerCenter}}"> </div> <div class="group"> <label>FooterCenterImage:</label> <select id="footerCenterImage" (change)="footerCenterImage($event)" value="{{printInfo.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" (change)="footerRight($event)" value="{{printInfo.footerRight}}"> </div> <div class="group"> <label>FooterRightImage:</label> <select id="footerRightImage" (change)="footerRightImage($event)" value="{{printInfo.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" (click)='setPrintInfoBut($event)'> </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" (click)='savePDF($event)'> </div> </div> </div> </div>
.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; }
(function (global) { System.config({ transpiler: 'ts', typescriptOptions: { tsconfig: true }, meta: { 'typescript': { "exports": "ts" }, '*.css': { loader: 'css' } }, paths: { // paths serve as alias 'npm:': 'node_modules/' }, // map tells the System loader where to look for things map: { 'core-js': 'npm:core-js/client/shim.min.js', 'zone': 'npm:zone.js/fesm2015/zone.min.js', 'rxjs': 'npm:rxjs/dist/bundles/rxjs.umd.min.js', '@angular/core': 'npm:@angular/core/fesm2022', '@angular/common': 'npm:@angular/common/fesm2022/common.mjs', '@angular/compiler': 'npm:@angular/compiler/fesm2022/compiler.mjs', '@angular/platform-browser': 'npm:@angular/platform-browser/fesm2022/platform-browser.mjs', '@angular/platform-browser-dynamic': 'npm:@angular/platform-browser-dynamic/fesm2022/platform-browser-dynamic.mjs', '@angular/common/http': 'npm:@angular/common/fesm2022/http.mjs', '@angular/router': 'npm:@angular/router/fesm2022/router.mjs', '@angular/forms': 'npm:@angular/forms/fesm2022/forms.mjs', 'jszip': 'npm:jszip/dist/jszip.min.js', 'typescript': 'npm:typescript/lib/typescript.js', 'ts': './plugin.js', 'tslib':'npm:tslib/tslib.js', 'css': 'npm:systemjs-plugin-css/css.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-print': 'npm:@mescius/spread-sheets-print/index.js', '@mescius/spread-sheets-pdf': 'npm:@mescius/spread-sheets-pdf/index.js', '@mescius/spread-sheets-angular': 'npm:@mescius/spread-sheets-angular/fesm2020/mescius-spread-sheets-angular.mjs', '@grapecity/jsob-test-dependency-package/react-components': 'npm:@grapecity/jsob-test-dependency-package/react-components/index.js' }, // packages tells the System loader how to load when no filename and/or no extension packages: { src: { defaultExtension: 'ts' }, rxjs: { defaultExtension: 'js' }, "node_modules": { defaultExtension: 'js' }, "node_modules/@angular": { defaultExtension: 'mjs' }, "@mescius/spread-sheets-angular": { defaultExtension: 'mjs' }, '@angular/core': { defaultExtension: 'mjs', main: 'core.mjs' } } }); })(this);