カスタムPDFエクスポート

SpreadJSからPDFファイルへのエクスポートはカスタマイズできます。SpreadJSの印刷設定を変更できるため、必要な情報を正確にエクスポートできます。

savePDFメソッドを使用すると、すべてのシート、または指定のシートをエクスポートできます。 個々のシートに対し、シートのprintInfoオプションを設定して、個別に詳細オプションを設定できます。
import { Component, NgModule, enableProdMode } from '@angular/core'; import { bootstrapApplication, BrowserModule } from '@angular/platform-browser'; import GC from '@mescius/spread-sheets'; import '@mescius/spread-sheets-resources-ja'; GC.Spread.Common.CultureManager.culture("ja-jp"); import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; import { SpreadSheetsModule } from '@mescius/spread-sheets-angular'; import '@mescius/spread-sheets-print'; import '@mescius/spread-sheets-pdf'; import './styles.css'; @Component({ standalone: true, imports: [SpreadSheetsModule, BrowserModule], 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(); this.registerPDFFont("游明朝", "normal", "$DEMOROOT$/spread/source/data/ipaexm.ttf"); this.registerPDFFont("Calibri", "normal", "$DEMOROOT$/spread/source/data/ipaexg.ttf"); } } adjustLayoutForPrint(sheet: GC.Spread.Sheets.Worksheet) { sheet.setRowHeight(0, 30); sheet.getRange(0, 0, 1, 5).hAlign(1).vAlign(1).font("bold 14px 游明朝"); 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("オリンピックアスリート"); 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(); } registerPDFFont(name: string, type: string, fontPath:string) { const xhr = new XMLHttpRequest(); xhr.open('GET', fontPath, true); xhr.responseType = 'arraybuffer'; xhr.onload = function (e) { if (this.status == 200) { const fontArrayBuffer: any = this.response; let fonts: any = {}; fonts[type] = fontArrayBuffer; GC.Spread.Sheets.PDF.PDFFontsManager.registerFont(name, fonts); } }; xhr.send(); } } enableProdMode(); bootstrapApplication(AppComponent);
<!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$/ja/angular/node_modules/@mescius/spread-sheets/styles/gc.spread.sheets.excel2013white.css"> <!-- Polyfills --> <script src="$DEMOROOT$/ja/angular/node_modules/core-js/client/shim.min.js"></script> <script src="$DEMOROOT$/ja/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/exportPDFJP.js" type="text/javascript"></script> <!-- SystemJS --> <script src="$DEMOROOT$/ja/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$/ja/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>以下のオプションを変更して、画面下部にスクロールして[PrintInfoを設定]ボタンをクリックすると、SpreadのPrintInfoにこれらのオプションが設定されます。[PDFにエクスポート]ボタンをクリックすると、これらの設定に基づき、ワークブックがどのように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="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="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', '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', 'tslib':'npm:tslib/tslib.js', '@mescius/spread-sheets': 'npm:@mescius/spread-sheets/index.js', '@mescius/spread-sheets-resources-ja': 'npm:@mescius/spread-sheets-resources-ja/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', meta: { "*.component.ts": { loader: "system.component-loader.js" } } }, 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);