Pivot Print

SpreadJS supports printing the pivot table to PDF or a printer. You can set different properties, such as printDrill, itemPrintTitles, and fieldPrintTitles to print a pivot table with different effects.

The printDrill option displays the expand or collapse buttons on the printed page. The itemPrintTitles option is used to print the row labels on the next page if the data spills over to multiple pages and the fieldPrintTitles adds the print title to each page.

In the PivotTable, there are three attributes to set the display form of print: printDrill: Print expand/collapse buttons when displayed on PivotTable. itemPrintTitles: Repeat row labels on each PivotTable. fieldPrintTitles: Set Print titles. You can set these three properties separately:
import * as React from 'react'; import { createRoot } from 'react-dom/client'; import './styles.css'; import { AppFunc } from './app-func'; import { App } from './app-class'; // 1. Functional Component sample createRoot(document.getElementById('app')).render(<AppFunc />); // 2. Class Component sample // createRoot(document.getElementById('app')).render(<App />);
import * as React from 'react'; import GC from '@mescius/spread-sheets'; import '@mescius/spread-sheets-print'; import '@mescius/spread-sheets-pdf'; import "@mescius/spread-sheets-shapes"; import "@mescius/spread-sheets-pivot-addon"; import { SpreadSheets, Worksheet } from '@mescius/spread-sheets-react'; import './styles.css'; const useState = React.useState; export function AppFunc() { const [spread, setSpread] = useState(null); const [pt, setPT] = useState(null); const [state, setState] = useState({ printDrill: true, itemPrintTitles: true, fieldPrintTitles: true }); const initSpread = (spread) => { spread.suspendPaint(); spread.setSheetCount(2); let sheet1 = spread.getSheet(0); let sheet2 = spread.getSheet(1); let tableName = getDataSource(sheet2, pivotSales); let pivotTable = initPivotTable(sheet1, tableName); setSpread(spread); setPT(pivotTable); spread.resumePaint(); } const getDataSource = (sheet, tableSource) => { sheet.name("DataSource"); sheet.setRowCount(117); sheet.setColumnWidth(0, 120); sheet.getCell(-1, 0).formatter("YYYY-mm-DD"); sheet.getRange(-1, 4, 0, 2).formatter("$ #,##0"); let table = sheet.tables.add('table', 0, 0, 117, 6); for (let i = 2; i <= 117; i++) { sheet.setFormula(i - 1, 5, '=D' + i + '*E' + i) } table.style(GC.Spread.Sheets.Tables.TableThemes["none"]); sheet.setArray(0, 0, tableSource); return table.name(); } const initPivotTable = (sheet, source) => { sheet.name("PivotTable"); sheet.setRowCount(1000); sheet.defaults.rowHeight = 24; let option = { bandRows: true, bandColumns: true, showRowHeader: true, showColumnHeader: true, insertBlankLineAfterEachItem: true, }; let pivotTable = sheet.pivotTables.add("pivotTable", source, 1, 1, GC.Spread.Pivot.PivotTableLayoutType.outline, GC.Spread.Pivot.PivotTableThemes.medium8, option); pivotTable.suspendLayout(); pivotTable.add("salesperson", "Salesperson", GC.Spread.Pivot.PivotTableFieldType.rowField); pivotTable.add("car", "Cars", GC.Spread.Pivot.PivotTableFieldType.rowField); let groupInfo = { originFieldName: "date", dateGroups: [{ by: GC.Pivot.DateGroupType.quarters }] }; pivotTable.group(groupInfo); pivotTable.add("Quarters (date)", "Quarters (date)", GC.Spread.Pivot.PivotTableFieldType.columnField); pivotTable.add("price", "Price", GC.Spread.Pivot.PivotTableFieldType.valueField, GC.Pivot.SubtotalType.sum); pivotTable.add("total", "Totals", GC.Spread.Pivot.PivotTableFieldType.valueField, GC.Pivot.SubtotalType.sum); let style = new GC.Spread.Sheets.Style(); style.formatter = "$ #,##0"; pivotTable.setStyle({ dataOnly: true }, style); pivotTable.resumeLayout(); pivotTable.autoFitColumn(); return pivotTable; } const exportPDF = () => { spread.savePDF( function (blob) { saveAs(blob, 'SpreadJS_PivotTable.pdf'); }); } const setPrintDrill = (e) => { setState({ ...state, printDrill: !state.printDrill }) } const setItemPrintTitles = (e) => { setState({ ...state, itemPrintTitles: !state.itemPrintTitles }) } const setFieldPrintTitles = (e) => { setState({ ...state, fieldPrintTitles: !state.fieldPrintTitles }) } const printClick = () => { pt.options.printDrill = state.printDrill; pt.options.itemPrintTitles = state.itemPrintTitles; pt.options.fieldPrintTitles = state.fieldPrintTitles; spread.print(0); } return ( <div className='sample-tutorial'> <div id="ss" class="sample-spreadsheets"> <SpreadSheets workbookInitialized={spread => initSpread(spread)}> <Worksheet> </Worksheet> <Worksheet> </Worksheet> </SpreadSheets> </div> <div className='options-container' id='container'> <div class="option-item"> <label><b>Settings</b></label> </div> <hr /> <div className="option-item"> <input type="checkbox" id="printDrill" name="printDrill" value="printDrill" className="select-option" checked={state.printDrill} onChange={(e) => setPrintDrill(e)} /> <label for="printDrill">Print Drill</label> </div> <div className="option-item"> <input type="checkbox" id="itemPrintTitles" name="itemPrintTitles" value="itemPrintTitles" className="select-option" checked={state.itemPrintTitles} onChange={(e) => setItemPrintTitles(e)} /> <label for="itemPrintTitles">Item Print Titles</label> </div> <div className="option-item"> <input type="checkbox" id="fieldPrintTitles" name="fieldPrintTitles" value="fieldPrintTitles" className="select-option" checked={state.fieldPrintTitles} onChange={(e) => setFieldPrintTitles(e)} /> <label for="fieldPrintTitles">Field Print Titles</label> </div> <input type="button" value="Print" className="set-option" id="set-option" onClick={() => printClick()} /> <br /> <input type='button' id="savePDF" value="Export PDF" onClick={(e) => { exportPDF(e) }} /> </div> </div> ); }
import * as React from 'react'; import GC from '@mescius/spread-sheets'; import '@mescius/spread-sheets-print'; import '@mescius/spread-sheets-pdf'; import "@mescius/spread-sheets-shapes"; import "@mescius/spread-sheets-pivot-addon"; import { SpreadSheets, Worksheet } from '@mescius/spread-sheets-react'; import './styles.css'; const Component = React.Component; export class App extends Component { constructor(props) { super(props); this.state = { printDrill: true, itemPrintTitles: true, fieldPrintTitles: true } } render() { return ( <div className = 'sample-tutorial'> <div id="ss" class="sample-spreadsheets"> <SpreadSheets workbookInitialized={spread=>this.initSpread(spread)}> <Worksheet> </Worksheet> <Worksheet> </Worksheet> </SpreadSheets> </div> <div className = 'options-container' id = 'container'> <div class="option-item"> <label><b>Settings</b></label> </div> <hr /> <div className="option-item"> <input type="checkbox" id="printDrill" name="printDrill" value="printDrill" className="select-option" checked={this.state.printDrill} onChange={(e) => this.setPrintDrill(e)}/> <label for="printDrill">Print Drill</label> </div> <div className="option-item"> <input type="checkbox" id="itemPrintTitles" name="itemPrintTitles" value="itemPrintTitles" className="select-option" checked={this.state.itemPrintTitles} onChange={(e) => this.setItemPrintTitles(e)}/> <label for="itemPrintTitles">Item Print Titles</label> </div> <div className="option-item"> <input type="checkbox" id="fieldPrintTitles" name="fieldPrintTitles" value="fieldPrintTitles" className="select-option" checked ={this.state.fieldPrintTitles} onChange={(e) => this.setFieldPrintTitles(e)}/> <label for="fieldPrintTitles">Field Print Titles</label> </div> <input type="button" value="Print" className="set-option" id="set-option" onClick={() => this.printClick()}/> <br/> <input type = 'button' id="savePDF" value="Export PDF" onClick={(e)=>{this.exportPDF(e)}} /> </div> </div> ); } initSpread(spread) { spread.suspendPaint(); spread.setSheetCount(2); let sheet1 = spread.getSheet(0); let sheet2 = spread.getSheet(1); let tableName = this.getDataSource(sheet2, pivotSales); let pivotTable = this.initPivotTable(sheet1, tableName); spread.resumePaint(); this.setState(() => ({ spread: spread, pt: pivotTable })) } getDataSource(sheet, tableSource){ sheet.name("DataSource"); sheet.setRowCount(117); sheet.setColumnWidth(0, 120); sheet.getCell(-1, 0).formatter("YYYY-mm-DD"); sheet.getRange(-1,4,0,2).formatter("$ #,##0"); let table = sheet.tables.add('table', 0, 0, 117, 6); for(let i=2;i<=117;i++) { sheet.setFormula(i-1,5,'=D'+i+'*E'+i) } table.style(GC.Spread.Sheets.Tables.TableThemes["none"]); sheet.setArray(0, 0, tableSource); return table.name(); } initPivotTable(sheet, source){ sheet.name("PivotTable"); sheet.setRowCount(1000); sheet.defaults.rowHeight = 24; let option = { bandRows:true, bandColumns:true, showRowHeader:true, showColumnHeader:true, insertBlankLineAfterEachItem: true, }; let pivotTable = sheet.pivotTables.add("pivotTable", source, 1, 1, GC.Spread.Pivot.PivotTableLayoutType.outline, GC.Spread.Pivot.PivotTableThemes.medium8,option); pivotTable.suspendLayout(); pivotTable.add("salesperson", "Salesperson", GC.Spread.Pivot.PivotTableFieldType.rowField); pivotTable.add("car", "Cars", GC.Spread.Pivot.PivotTableFieldType.rowField); let groupInfo = { originFieldName: "date", dateGroups: [{ by: GC.Pivot.DateGroupType.quarters }] }; pivotTable.group(groupInfo); pivotTable.add("Quarters (date)", "Quarters (date)", GC.Spread.Pivot.PivotTableFieldType.columnField); pivotTable.add("price", "Price", GC.Spread.Pivot.PivotTableFieldType.valueField, GC.Pivot.SubtotalType.sum); pivotTable.add("total", "Totals", GC.Spread.Pivot.PivotTableFieldType.valueField, GC.Pivot.SubtotalType.sum); let style = new GC.Spread.Sheets.Style(); style.formatter = "$ #,##0"; pivotTable.setStyle({dataOnly: true}, style); pivotTable.resumeLayout(); pivotTable.autoFitColumn(); return pivotTable; } exportPDF() { this.state.spread.savePDF( function (blob) { saveAs(blob, 'SpreadJS_PivotTable.pdf'); }); } setPrintDrill(e) { let value = e.target.checked; this.setState(() => ({ printDrill: value })) } setItemPrintTitles(e) { let value = e.target.checked; this.setState(() => ({ itemPrintTitles: value })) } setFieldPrintTitles(e) { let value = e.target.checked; this.setState(() => ({ fieldPrintTitles: value })) } printClick() { this.state.pt.options.printDrill = this.state.printDrill; this.state.pt.options.itemPrintTitles = this.state.itemPrintTitles; this.state.pt.options.fieldPrintTitles = this.state.fieldPrintTitles; this.state.spread.print(0); } }
<!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/react/node_modules/@mescius/spread-sheets/styles/gc.spread.sheets.excel2013white.css"> <script src="$DEMOROOT$/spread/source/data/pivot-data.js" type="text/javascript"></script> <!-- SystemJS --> <script src="$DEMOROOT$/en/react/node_modules/systemjs/dist/system.src.js"></script> <script src="$DEMOROOT$/spread/source/js/FileSaver.js" type="text/javascript"></script> <script src="systemjs.config.js"></script> <script> System.import('$DEMOROOT$/en/lib/react/license.js').then(function () { System.import('./src/app'); }); </script> </head> <body> <div id="app" style="height: 100%;"></div> </body> </html>
.sample-tutorial { position: relative; height: 100%; overflow: hidden; } .sample-spreadsheets { width: calc(100% - 300px); height: 100%; overflow: hidden; float: left; } .options-container { float: right; width: 300px; padding: 12px; height: 100%; box-sizing: border-box; background: #fbfbfb; overflow: auto; } body { position: absolute; top: 0; bottom: 0; left: 0; right: 0; } .set-option { display: block; margin-top: 20px; width: 250px; } #reportFilterFieldsPerColumn { width: 28px; } .select-option-class{ display: block; margin-top: 20px; margin-bottom: 10px } .select-option-select{ width: 250px; display: block; margin-bottom: 20px; } .option-item{ height: 20px; margin-bottom: 10px; }
(function (global) { System.config({ transpiler: 'plugin-babel', babelOptions: { es2015: true, react: true }, meta: { '*.css': { loader: 'css' } }, paths: { // paths serve as alias 'npm:': 'node_modules/' }, // map tells the System loader where to look for things map: { '@mescius/spread-sheets': 'npm:@mescius/spread-sheets/index.js', '@mescius/spread-sheets-shapes': 'npm:@mescius/spread-sheets-shapes/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-pivot-addon': 'npm:@mescius/spread-sheets-pivot-addon/index.js', '@mescius/spread-sheets-react': 'npm:@mescius/spread-sheets-react/index.js', '@grapecity/jsob-test-dependency-package/react-components': 'npm:@grapecity/jsob-test-dependency-package/react-components/index.js', 'react': 'npm:react/cjs/react.production.js', 'react-dom': 'npm:react-dom/cjs/react-dom.production.js', 'react-dom/client': 'npm:react-dom/cjs/react-dom-client.production.js', 'scheduler': 'npm:scheduler/cjs/scheduler.production.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' }, // packages tells the System loader how to load when no filename and/or no extension packages: { src: { defaultExtension: 'jsx' }, "node_modules": { defaultExtension: 'js' }, } }); })(this);