Overview

You can print a single sheet or all of the sheets in SpreadJS using the print plugin. This makes it easy to give users the ability to print the SpreadJS instance, which can be particularly useful if there is some sort of dashboard or form where they have entered information and want a physical copy.

This demo also shows how to display the worksheet print line and customize it through the .sjs-print-line CSS class.

In order to use the print feature, add the JS file link into the document's head section below the SpreadJS link. For example: Then you can use the print feature by using the print method. It is defined as: where the optional parameter sheetIndex tells which sheet to print (omit for printing all sheets). For example you can print all sheets with the following code: You can show the worksheet print preview lines and customize their color and width by overriding the corresponding CSS classes: .sjs-print-line controls the automatically calculated print lines. Its default border color is #9f9f9f and its default border width is 1px. .sjs-print-page-break controls manual row and column page breaks. Its default border color is #000000 and its default border width is 1px. .sjs-print-area controls the boundary of the configured print area. Its default border color is #000000 and its default border width is 1px. This demo overrides all three classes so their styles can be adjusted independently from the settings panel.
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 { createRoot } from 'react-dom/client'; import GC from '@mescius/spread-sheets'; import { SpreadSheets, Worksheet } from '@mescius/spread-sheets-react'; import '@mescius/spread-sheets-print'; import './styles.css'; const Component = React.Component; export function AppFunc() { let spread = null; let initSpread = function (value) { spread = value; let sheet = spread.getActiveSheet(); sheet.suspendPaint(); sheet.options.allowCellOverflow = true; sheet.name("Demo"); spread.sheets[0].setText(31, 8, " "); sheet.addSpan(1, 1, 1, 1); sheet.setValue(1, 1, "Month"); sheet.setValue(2, 1, "January"); sheet.setValue(3, 1, "February"); sheet.setValue(4, 1, "March"); sheet.setValue(5, 1, "April"); sheet.setValue(6, 1, "May"); sheet.setValue(7, 1, "June"); sheet.setValue(8, 1, "July"); sheet.setValue(9, 1, "August"); sheet.setValue(10, 1, "September"); sheet.setValue(11, 1, "October"); sheet.setValue(12, 1, "November"); sheet.setValue(13, 1, "December"); sheet.addSpan(1, 2, 1, 1); sheet.setValue(1, 2, "Quantity"); sheet.setValue(2, 2, 60); sheet.setValue(3, 2, 100); sheet.setValue(4, 2, 110); sheet.setValue(5, 2, 90); sheet.setValue(6, 2, 112); sheet.setValue(7, 2, 137); sheet.setValue(8, 2, 80); sheet.setValue(9, 2, 88); sheet.setValue(10, 2, 118); sheet.setValue(11, 2, 122); sheet.setValue(12, 2, 130); sheet.setValue(13, 2, 135); sheet.addSpan(1, 3, 1, 1); sheet.setValue(1, 3, "Price"); sheet.setValue(2, 3, 30.0); sheet.setValue(3, 3, 45.0); sheet.setValue(4, 3, 10.0); sheet.setValue(5, 3, 99.9); sheet.setValue(6, 3, 89.0); sheet.setValue(7, 3, 150.0); sheet.setValue(8, 3, 35.0); sheet.setValue(9, 3, 59.9); sheet.setValue(10, 3, 47.9); sheet.setValue(11, 3, 55.0); sheet.setValue(12, 3, 32.0); sheet.setValue(13, 3, 20.0); sheet.addSpan(1, 4, 1, 1); sheet.setValue(1, 4, "Total"); sheet.setFormula(2, 4, "=C3*D3"); sheet.setFormula(3, 4, "=C4*D4"); sheet.setFormula(4, 4, "=C5*D5"); sheet.setFormula(5, 4, "=C6*D6"); sheet.setFormula(6, 4, "=C7*D7"); sheet.setFormula(7, 4, "=C8*D8"); sheet.setFormula(8, 4, "=C9*D9"); sheet.setFormula(9, 4, "=C10*D10"); sheet.setFormula(10, 4, "=C11*D11"); sheet.setFormula(11, 4, "=C12*D12"); sheet.setFormula(12, 4, "=C13*D13"); sheet.setFormula(13, 4, "=C14*D14"); // set column width sheet.setColumnWidth(0, 50); sheet.setColumnWidth(1, 100); sheet.setColumnWidth(2, 60); sheet.setColumnWidth(3, 60); sheet.setColumnWidth(4, 90); sheet.setColumnWidth(5, 50); //set alignment sheet.getRange(1, 1, 1, 4).hAlign(GC.Spread.Sheets.HorizontalAlign.center) //set formatter sheet.getRange(2, 3, 12, 1).formatter("$ #,##0"); sheet.getRange(2, 4, 12, 1).formatter("$ #,##0"); //set color sheet.getRange(1, 1, 1, 4).backColor("#69a569").foreColor("white"); //set lineBorder sheet.getRange(2, 1, 12, 4).setBorder(new GC.Spread.Sheets.LineBorder("#A8A9AD", GC.Spread.Sheets.LineStyle.dotted), { all: true }); addFigures(sheet); const printInfo = sheet.printInfo(); printInfo.paperSize(new GC.Spread.Sheets.Print.PaperSize(GC.Spread.Sheets.Print.PaperKind.a4)); printInfo.rowStart(1); printInfo.rowEnd(19); printInfo.columnStart(1); printInfo.columnEnd(13); sheet.setRowPageBreak(16, true); sheet.setColumnPageBreak(2, true); sheet.isPrintLineVisible(true); sheet.resumePaint(); } let handelPrint = function () { spread.print(); } let addFigures = function (sheet) { sheet.getRange(20, -1, 1, -1).visible(false); sheet.addSpan(4, 6, 6, 3); sheet.setFormula(4, 6, '=PIESPARKLINE(E3:E7, "#e6f0e6","#c9dec9","#a3c8a3","#73ab73","#d1ffd1")'); sheet.addSpan(10, 6, 1, 3); sheet.getCell(10, 6).text("Figure 1").hAlign(1); } return (<div class="sample-tutorial"> <div class="sample-spreadsheets"> <SpreadSheets workbookInitialized={spread => initSpread(spread)}> <Worksheet /> </SpreadSheets> </div> <Panel getSpread={() => spread} handelPrint={(e) => { handelPrint(e) }} /> </div>); } class Panel extends Component { constructor(props) { super(props); this.state = { printLineColor: "#2e9d5b", printLineWidth: "2", pageBreakColor: "#87ceeb", pageBreakWidth: "2", printAreaColor: "#ffc0cb", printAreaWidth: "2" }; } componentDidMount() { this.updatePrintPreviewStyle(true); } updatePrintPreviewStyle(immediate = false) { if (!this.printPreviewStyle) { this.printPreviewStyle = document.createElement("style"); this.printPreviewStyle.id = "print-preview-style"; document.head.appendChild(this.printPreviewStyle); } this.printPreviewStyle.textContent = [ ".sjs-print-line { border-color: " + this.state.printLineColor + "; border-width: " + this.state.printLineWidth + "px; }", ".sjs-print-page-break { border-color: " + this.state.pageBreakColor + "; border-width: " + this.state.pageBreakWidth + "px; }", ".sjs-print-area { border-color: " + this.state.printAreaColor + "; border-width: " + this.state.printAreaWidth + "px; }" ].join("\n"); this.scheduleRepaint(immediate); } scheduleRepaint(immediate = false) { if (this.repaintTimer) { clearTimeout(this.repaintTimer); this.repaintTimer = null; } if (immediate) { this.repaintPrintPreview(); return; } this.repaintTimer = setTimeout(() => this.repaintPrintPreview(), 80); } repaintPrintPreview() { const spread = this.props.getSpread && this.props.getSpread(); if (spread) { const sheet = spread.getActiveSheet(); if (sheet && sheet.repaint) { sheet.repaint(); } else if (spread.repaint) { spread.repaint(); } } } updatePrintLineColor(e, immediate = false) { const printLineColor = e.target.value; this.setState({ printLineColor }, () => this.updatePrintPreviewStyle(immediate)); } updatePrintLineWidth(e, immediate = false) { const printLineWidth = e.target.value; this.setState({ printLineWidth }, () => this.updatePrintPreviewStyle(immediate)); } updatePageBreakColor(e, immediate = false) { const pageBreakColor = e.target.value; this.setState({ pageBreakColor }, () => this.updatePrintPreviewStyle(immediate)); } updatePageBreakWidth(e, immediate = false) { const pageBreakWidth = e.target.value; this.setState({ pageBreakWidth }, () => this.updatePrintPreviewStyle(immediate)); } updatePrintAreaColor(e, immediate = false) { const printAreaColor = e.target.value; this.setState({ printAreaColor }, () => this.updatePrintPreviewStyle(immediate)); } updatePrintAreaWidth(e, immediate = false) { const printAreaWidth = e.target.value; this.setState({ printAreaWidth }, () => this.updatePrintPreviewStyle(immediate)); } render() { return ( <div class="options-container"> <div class="panel-header"> <div> <h3>Print Preview Settings</h3> </div> </div> <div class="settings-stack"> <section class="settings-group" aria-labelledby="printLineHeading"> <h4 id="printLineHeading">Print Line</h4> <div class="setting-row"> <label for="printLineColor">Color</label> <div class="control-inline"> <input type="color" id="printLineColor" value={this.state.printLineColor} onChange={(e) => this.updatePrintLineColor(e, false)} onBlur={(e) => this.updatePrintLineColor(e, true)} /> <span>{this.state.printLineColor}</span> </div> </div> <div class="setting-row"> <label for="printLineWidth">Width</label> <div class="control-inline"> <input type="range" id="printLineWidth" min="1" max="8" value={this.state.printLineWidth} onChange={(e) => this.updatePrintLineWidth(e, false)} onMouseUp={(e) => this.updatePrintLineWidth(e, true)} onTouchEnd={(e) => this.updatePrintLineWidth(e, true)} /> <span>{this.state.printLineWidth}px</span> </div> </div> </section> <section class="settings-group" aria-labelledby="pageBreakHeading"> <h4 id="pageBreakHeading">Page Break</h4> <div class="setting-row"> <label for="pageBreakColor">Color</label> <div class="control-inline"> <input type="color" id="pageBreakColor" value={this.state.pageBreakColor} onChange={(e) => this.updatePageBreakColor(e, false)} onBlur={(e) => this.updatePageBreakColor(e, true)} /> <span>{this.state.pageBreakColor}</span> </div> </div> <div class="setting-row"> <label for="pageBreakWidth">Width</label> <div class="control-inline"> <input type="range" id="pageBreakWidth" min="1" max="8" value={this.state.pageBreakWidth} onChange={(e) => this.updatePageBreakWidth(e, false)} onMouseUp={(e) => this.updatePageBreakWidth(e, true)} onTouchEnd={(e) => this.updatePageBreakWidth(e, true)} /> <span>{this.state.pageBreakWidth}px</span> </div> </div> </section> <section class="settings-group" aria-labelledby="printAreaHeading"> <h4 id="printAreaHeading">Print Area</h4> <div class="setting-row"> <label for="printAreaColor">Color</label> <div class="control-inline"> <input type="color" id="printAreaColor" value={this.state.printAreaColor} onChange={(e) => this.updatePrintAreaColor(e, false)} onBlur={(e) => this.updatePrintAreaColor(e, true)} /> <span>{this.state.printAreaColor}</span> </div> </div> <div class="setting-row"> <label for="printAreaWidth">Width</label> <div class="control-inline"> <input type="range" id="printAreaWidth" min="1" max="8" value={this.state.printAreaWidth} onChange={(e) => this.updatePrintAreaWidth(e, false)} onMouseUp={(e) => this.updatePrintAreaWidth(e, true)} onTouchEnd={(e) => this.updatePrintAreaWidth(e, true)} /> <span>{this.state.printAreaWidth}px</span> </div> </div> </section> </div> <div class="panel-actions"> <input type="button" value="Print" id="btnPrint" onClick={(e) => { this.props.handelPrint() }} /> </div> </div> ) } }
import * as React from 'react'; import { createRoot } from 'react-dom/client'; import GC from '@mescius/spread-sheets'; import { SpreadSheets, Worksheet } from '@mescius/spread-sheets-react'; import '@mescius/spread-sheets-print'; import './styles.css'; const Component = React.Component; function _getElementById(id) { return document.getElementById(id); } export class App extends Component { constructor(props) { super(props); } render() { return (<div class="sample-tutorial"> <div class="sample-spreadsheets"> <SpreadSheets workbookInitialized={spread => this.initSpread(spread)}> <Worksheet /> </SpreadSheets> </div> <Panel getSpread={() => this.spread} handelPrint={(e) => { this.handelPrint(e) }} /> </div>); } initSpread(spread) { this.spread = spread; let sheet = spread.getActiveSheet(); sheet.suspendPaint(); sheet.options.allowCellOverflow = true; sheet.name("Demo"); this.spread.sheets[0].setText(31, 8, " "); sheet.addSpan(1, 1, 1, 1); sheet.setValue(1, 1, "Month"); sheet.setValue(2, 1, "January"); sheet.setValue(3, 1, "February"); sheet.setValue(4, 1, "March"); sheet.setValue(5, 1, "April"); sheet.setValue(6, 1, "May"); sheet.setValue(7, 1, "June"); sheet.setValue(8, 1, "July"); sheet.setValue(9, 1, "August"); sheet.setValue(10, 1, "September"); sheet.setValue(11, 1, "October"); sheet.setValue(12, 1, "November"); sheet.setValue(13, 1, "December"); sheet.addSpan(1, 2, 1, 1); sheet.setValue(1, 2, "Quantity"); sheet.setValue(2, 2, 60); sheet.setValue(3, 2, 100); sheet.setValue(4, 2, 110); sheet.setValue(5, 2, 90); sheet.setValue(6, 2, 112); sheet.setValue(7, 2, 137); sheet.setValue(8, 2, 80); sheet.setValue(9, 2, 88); sheet.setValue(10, 2, 118); sheet.setValue(11, 2, 122); sheet.setValue(12, 2, 130); sheet.setValue(13, 2, 135); sheet.addSpan(1, 3, 1, 1); sheet.setValue(1, 3, "Price"); sheet.setValue(2, 3, 30.0); sheet.setValue(3, 3, 45.0); sheet.setValue(4, 3, 10.0); sheet.setValue(5, 3, 99.9); sheet.setValue(6, 3, 89.0); sheet.setValue(7, 3, 150.0); sheet.setValue(8, 3, 35.0); sheet.setValue(9, 3, 59.9); sheet.setValue(10, 3, 47.9); sheet.setValue(11, 3, 55.0); sheet.setValue(12, 3, 32.0); sheet.setValue(13, 3, 20.0); sheet.addSpan(1, 4, 1, 1); sheet.setValue(1, 4, "Total"); sheet.setFormula(2, 4, "=C3*D3"); sheet.setFormula(3, 4, "=C4*D4"); sheet.setFormula(4, 4, "=C5*D5"); sheet.setFormula(5, 4, "=C6*D6"); sheet.setFormula(6, 4, "=C7*D7"); sheet.setFormula(7, 4, "=C8*D8"); sheet.setFormula(8, 4, "=C9*D9"); sheet.setFormula(9, 4, "=C10*D10"); sheet.setFormula(10, 4, "=C11*D11"); sheet.setFormula(11, 4, "=C12*D12"); sheet.setFormula(12, 4, "=C13*D13"); sheet.setFormula(13, 4, "=C14*D14"); // set column width sheet.setColumnWidth(0, 50); sheet.setColumnWidth(1, 100); sheet.setColumnWidth(2, 60); sheet.setColumnWidth(3, 60); sheet.setColumnWidth(4, 90); sheet.setColumnWidth(5, 50); //set alignment sheet.getRange(1, 1, 1, 4).hAlign(GC.Spread.Sheets.HorizontalAlign.center) //set formatter sheet.getRange(2, 3, 12, 1).formatter("$ #,##0"); sheet.getRange(2, 4, 12, 1).formatter("$ #,##0"); //set color sheet.getRange(1, 1, 1, 4).backColor("#69a569").foreColor("white"); //set lineBorder sheet.getRange(2, 1, 12, 4).setBorder(new GC.Spread.Sheets.LineBorder("#A8A9AD", GC.Spread.Sheets.LineStyle.dotted), { all: true }); this.addFigures(sheet); const printInfo = sheet.printInfo(); printInfo.paperSize(new GC.Spread.Sheets.Print.PaperSize(GC.Spread.Sheets.Print.PaperKind.a4)); printInfo.rowStart(1); printInfo.rowEnd(19); printInfo.columnStart(1); printInfo.columnEnd(13); sheet.setRowPageBreak(16, true); sheet.setColumnPageBreak(2, true); sheet.isPrintLineVisible(true); sheet.resumePaint(); } handelPrint() { this.spread.print(); } addFigures(sheet) { sheet.getRange(20, -1, 1, -1).visible(false); sheet.addSpan(4, 6, 6, 3); sheet.setFormula(4, 6, '=PIESPARKLINE(E3:E7, "#e6f0e6","#c9dec9","#a3c8a3","#73ab73","#d1ffd1")'); sheet.addSpan(10, 6, 1, 3); sheet.getCell(10, 6).text("Figure 1").hAlign(1); } } class Panel extends Component { constructor(props) { super(props); this.state = { printLineColor: "#2e9d5b", printLineWidth: "2", pageBreakColor: "#87ceeb", pageBreakWidth: "2", printAreaColor: "#ffc0cb", printAreaWidth: "2" }; } componentDidMount() { this.updatePrintPreviewStyle(true); } updatePrintPreviewStyle(immediate = false) { if (!this.printPreviewStyle) { this.printPreviewStyle = document.createElement("style"); this.printPreviewStyle.id = "print-preview-style"; document.head.appendChild(this.printPreviewStyle); } this.printPreviewStyle.textContent = [ ".sjs-print-line { border-color: " + this.state.printLineColor + "; border-width: " + this.state.printLineWidth + "px; }", ".sjs-print-page-break { border-color: " + this.state.pageBreakColor + "; border-width: " + this.state.pageBreakWidth + "px; }", ".sjs-print-area { border-color: " + this.state.printAreaColor + "; border-width: " + this.state.printAreaWidth + "px; }" ].join("\n"); this.scheduleRepaint(immediate); } scheduleRepaint(immediate = false) { if (this.repaintTimer) { clearTimeout(this.repaintTimer); this.repaintTimer = null; } if (immediate) { this.repaintPrintPreview(); return; } this.repaintTimer = setTimeout(() => this.repaintPrintPreview(), 80); } repaintPrintPreview() { const spread = this.props.getSpread && this.props.getSpread(); if (spread) { const sheet = spread.getActiveSheet(); if (sheet && sheet.repaint) { sheet.repaint(); } else if (spread.repaint) { spread.repaint(); } } } updatePrintLineColor(e, immediate = false) { const printLineColor = e.target.value; this.setState({ printLineColor }, () => this.updatePrintPreviewStyle(immediate)); } updatePrintLineWidth(e, immediate = false) { const printLineWidth = e.target.value; this.setState({ printLineWidth }, () => this.updatePrintPreviewStyle(immediate)); } updatePageBreakColor(e, immediate = false) { const pageBreakColor = e.target.value; this.setState({ pageBreakColor }, () => this.updatePrintPreviewStyle(immediate)); } updatePageBreakWidth(e, immediate = false) { const pageBreakWidth = e.target.value; this.setState({ pageBreakWidth }, () => this.updatePrintPreviewStyle(immediate)); } updatePrintAreaColor(e, immediate = false) { const printAreaColor = e.target.value; this.setState({ printAreaColor }, () => this.updatePrintPreviewStyle(immediate)); } updatePrintAreaWidth(e, immediate = false) { const printAreaWidth = e.target.value; this.setState({ printAreaWidth }, () => this.updatePrintPreviewStyle(immediate)); } render() { return ( <div class="options-container"> <div class="panel-header"> <div> <h3>Print Preview Settings</h3> </div> </div> <div class="settings-stack"> <section class="settings-group" aria-labelledby="printLineHeading"> <h4 id="printLineHeading">Print Line</h4> <div class="setting-row"> <label for="printLineColor">Color</label> <div class="control-inline"> <input type="color" id="printLineColor" value={this.state.printLineColor} onChange={(e) => this.updatePrintLineColor(e, false)} onBlur={(e) => this.updatePrintLineColor(e, true)} /> <span>{this.state.printLineColor}</span> </div> </div> <div class="setting-row"> <label for="printLineWidth">Width</label> <div class="control-inline"> <input type="range" id="printLineWidth" min="1" max="8" value={this.state.printLineWidth} onChange={(e) => this.updatePrintLineWidth(e, false)} onMouseUp={(e) => this.updatePrintLineWidth(e, true)} onTouchEnd={(e) => this.updatePrintLineWidth(e, true)} /> <span>{this.state.printLineWidth}px</span> </div> </div> </section> <section class="settings-group" aria-labelledby="pageBreakHeading"> <h4 id="pageBreakHeading">Page Break</h4> <div class="setting-row"> <label for="pageBreakColor">Color</label> <div class="control-inline"> <input type="color" id="pageBreakColor" value={this.state.pageBreakColor} onChange={(e) => this.updatePageBreakColor(e, false)} onBlur={(e) => this.updatePageBreakColor(e, true)} /> <span>{this.state.pageBreakColor}</span> </div> </div> <div class="setting-row"> <label for="pageBreakWidth">Width</label> <div class="control-inline"> <input type="range" id="pageBreakWidth" min="1" max="8" value={this.state.pageBreakWidth} onChange={(e) => this.updatePageBreakWidth(e, false)} onMouseUp={(e) => this.updatePageBreakWidth(e, true)} onTouchEnd={(e) => this.updatePageBreakWidth(e, true)} /> <span>{this.state.pageBreakWidth}px</span> </div> </div> </section> <section class="settings-group" aria-labelledby="printAreaHeading"> <h4 id="printAreaHeading">Print Area</h4> <div class="setting-row"> <label for="printAreaColor">Color</label> <div class="control-inline"> <input type="color" id="printAreaColor" value={this.state.printAreaColor} onChange={(e) => this.updatePrintAreaColor(e, false)} onBlur={(e) => this.updatePrintAreaColor(e, true)} /> <span>{this.state.printAreaColor}</span> </div> </div> <div class="setting-row"> <label for="printAreaWidth">Width</label> <div class="control-inline"> <input type="range" id="printAreaWidth" min="1" max="8" value={this.state.printAreaWidth} onChange={(e) => this.updatePrintAreaWidth(e, false)} onMouseUp={(e) => this.updatePrintAreaWidth(e, true)} onTouchEnd={(e) => this.updatePrintAreaWidth(e, true)} /> <span>{this.state.printAreaWidth}px</span> </div> </div> </section> </div> <div class="panel-actions"> <input type="button" value="Print" id="btnPrint" onClick={(e) => { this.props.handelPrint() }} /> </div> </div> ) } }
<!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"> <!-- SystemJS --> <script src="$DEMOROOT$/en/react/node_modules/systemjs/dist/system.src.js"></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"></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: 18px 16px; height: 100%; box-sizing: border-box; background: #f7f8fa; border-left: 1px solid #dde2e8; overflow: auto; color: #202734; } .panel-header { padding-bottom: 16px; margin-bottom: 16px; border-bottom: 1px solid #e2e6eb; } .panel-header h3 { margin: 0 0 6px; font-size: 16px; font-weight: 600; } .settings-stack { display: flex; flex-direction: column; gap: 12px; } .settings-group { padding: 12px; border: 1px solid #e0e5eb; border-radius: 6px; background: #fff; } .settings-group h4 { margin: 0 0 12px; color: #202734; font-size: 14px; font-weight: 600; } .setting-row { margin-bottom: 16px; } .setting-row:last-child { margin-bottom: 0; } .setting-row label { display: block; margin-bottom: 8px; color: #394252; font-size: 13px; font-weight: 600; } .control-inline { display: flex; align-items: center; gap: 10px; } .control-inline input[type="color"] { flex: 0 0 auto; width: 38px; height: 32px; padding: 0; border: 1px solid #cfd6df; border-radius: 4px; background: #fff; } .control-inline input[type="range"] { flex: 1 1 auto; min-width: 0; } .control-inline span { min-width: 48px; color: #4d5767; font-size: 12px; text-align: right; } .panel-actions { margin-top: 16px; } input[type="button"] { display: block; width: 100%; height: 30px; padding: 4px 12px; border: 1px solid #9db8dd; border-radius: 2px; background: #fff; color: #003e7e; font-weight: 600; cursor: pointer; } input[type="button"]:hover { border-color: #6e9ed4; background: #f5f9ff; } input[type="button"]:active { border-color: #3f7ec0; background: #eaf3ff; } body { position: absolute; top: 0; bottom: 0; left: 0; right: 0; overflow: hidden; } #app { height: 100%; overflow: hidden; }
(function (global) { System.config({ transpiler: 'plugin-babel', babelOptions: { es2015: true, react: true }, meta: { '*.css': { loader: 'css' } }, paths: { // paths serve as alias 'npm:': 'node_modules/', 'cdn:': 'https://cdn.mescius.io/demoapps/packages/spreadjs/19.2.4-master-2026-09-29-2130/' }, // map tells the System loader where to look for things map: { '@mescius/spread-sheets-print': 'cdn:@mescius/spread-sheets-print/index.js', '@mescius/spread-sheets': 'cdn:@mescius/spread-sheets/index.js', '@mescius/spread-sheets-react': 'cdn:@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);