Password Support

SpreadJS File Format supports the use of passwords to import and export xlsx files.

SpreadJS File Format supports encryption and decryption using passwords when importing and exporting. Export Example: Import Example errorCode is defined by GC.Spread.Sheets.IO.ErrorCode
import * as React from 'react'; import * as ReactDOM from 'react-dom'; import './styles.css'; import { AppFunc } from './app-func'; import { App } from './app-class'; // 1. Functional Component sample ReactDOM.render(<AppFunc />, document.getElementById('app')); // 2. Class Component sample ReactDOM.render(<App />, document.getElementById('app'));
import * as React from 'react'; import { SpreadSheets, Worksheet } from '@mescius/spread-sheets-react'; import GC from '@mescius/spread-sheets'; import '@mescius/spread-sheets-io'; import '@mescius/spread-sheets-shapes'; import '@mescius/spread-sheets-charts'; import '@mescius/spread-sheets-slicers'; import '@mescius/spread-sheets-pivot-addon'; import '@mescius/spread-sheets-reportsheet-addon'; import "@mescius/spread-sheets-tablesheet"; import "@mescius/spread-sheets-ganttsheet"; import './styles.css'; const useState = React.useState; let spread = null; let selectedFileBtn = null; export function AppFunc() { const [state, setState] = useState({ selectedFile: null, importPassword: '', importDisabled: true, shakeAnimation: '', showWarning: false, warningMessage: '', exportPassword: '', }) const initSpread = (workbook) => { spread = workbook; } const selectedFileChange = (e) => { let selectedFile = e.target.files[0]; setState({ ...state, selectedFile, importDisabled: false }); } const selectFileHandler = () => { selectedFileBtn.click(); } const importFileHandler = () => { const wrongPasswordHandler = message => { setState({ ...state, showWarning: true, shakeAnimation: "shake 0.5s", warningMessage: message, importPassword: '' }); setTimeout(() => setState({ ...state, shakeAnimation: '' }), 500); }; spread.import(state.selectedFile, console.log, error => { if (error.errorCode === GC.Spread.Sheets.IO.ErrorCode.noPassword || error.errorCode === GC.Spread.Sheets.IO.ErrorCode.invalidPassword ) { wrongPasswordHandler(error.errorMessage); } }, { fileType: GC.Spread.Sheets.FileType.excel, password: state.importPassword }); } const exportFileHandler = () => { let password = state.exportPassword; spread.export(blob => saveAs(blob, (password ? 'encrypted-' : '') + 'export.xlsx'), console.log, { fileType: GC.Spread.Sheets.FileType.excel, password: password }); } const initPassword = () => { setState({ ...state, showWarning: false, warningMessage: '' }); } return ( <div class="sample-tutorial"> <div class="sample-container"> <div class="sample-spreadsheets"> <SpreadSheets workbookInitialized={spread => initSpread(spread)}> <Worksheet> </Worksheet> </SpreadSheets> </div> <div id="statusBar"></div> </div> <div className="options-container"> <div className="option-row"> <div class="inputContainer"> <div class="options-title">Import:</div> <input class={"passwordIpt " + (state.showWarning ? 'warning' : '')} id="importPassword" type="password" placeholder="Password" name="importPassword" value={state.importPassword} disabled={state.importDisabled} style={{ animation: state.shakeAnimation }} onFocus={() => { initPassword() }} onChange={(e) => setState({ ...state, importPassword: e.target.value })} /> <br /> <div id="warningBox">{state.warningMessage}</div> <input id="selectedFile" type="file" accept=".xlsx" onChange={(e) => selectedFileChange(e)} ref={(el) => selectedFileBtn = el} /> <button class="settingButton" id="selectBtn" onClick={() => selectFileHandler()}>Select</button> <button class="settingButton" id="importBtn" onClick={() => importFileHandler()} disabled={state.importDisabled}>Import</button> </div> <div class="inputContainer"> <div class="options-title">Export:</div> <input class="passwordIpt" id="exportPassword" type="password" placeholder="Password" name="exportPassword" value={state.exportPassword} onChange={(e) => setState({ ...state, exportPassword: e.target.value })} /> <br /> <button class="settingButton" id="exportBtn" onClick={() => exportFileHandler()}>Export</button> </div> </div> </div> </div> ); }
import * as React from 'react'; import { SpreadSheets, Worksheet } from '@mescius/spread-sheets-react'; import GC from '@mescius/spread-sheets'; import '@mescius/spread-sheets-io'; import '@mescius/spread-sheets-shapes'; import '@mescius/spread-sheets-charts'; import '@mescius/spread-sheets-slicers'; import '@mescius/spread-sheets-pivot-addon'; import '@mescius/spread-sheets-reportsheet-addon'; import "@mescius/spread-sheets-tablesheet"; import "@mescius/spread-sheets-ganttsheet"; import './styles.css'; const Component = React.Component; export class App extends Component { constructor(props) { super(props); this.spread = null; this.state = { selectedFile: null, importPassword: '', importDisabled: true, shakeAnimation: '', showWarning: false, warningMessage: '', exportPassword: '', }; } render() { return <div class="sample-tutorial"> <div class="sample-container"> <div class="sample-spreadsheets"> <SpreadSheets workbookInitialized={spread => this.initSpread(spread)}> <Worksheet> </Worksheet> </SpreadSheets> </div> <div id="statusBar"></div> </div> <div className="options-container"> <div className="option-row"> <div class="inputContainer"> <div class="options-title">Import:</div> <input class={"passwordIpt " + (this.state.showWarning ? 'warning' : '')} id="importPassword" type="password" placeholder="Password" name="importPassword" value={this.state.importPassword} disabled={this.state.importDisabled} style={{animation: this.state.shakeAnimation}} onFocus={() => {this.initPassword()}} onChange={(e) => this.setState({importPassword: e.target.value})} /> <br/> <div id="warningBox">{this.state.warningMessage}</div> <input id="selectedFile" type="file" accept=".xlsx" onChange={(e)=>this.selectedFileChange(e)} ref={(el) => this.selectedFileBtn = el}/> <button class="settingButton" id="selectBtn" onClick={()=>this.selectFileHandler()}>Select</button> <button class="settingButton" id="importBtn" onClick={()=>this.importFileHandler()} disabled={this.state.importDisabled}>Import</button> </div> <div class="inputContainer"> <div class="options-title">Export:</div> <input class="passwordIpt" id="exportPassword" type="password" placeholder="Password" name="exportPassword" value={this.state.exportPassword} onChange={(e) => this.setState({exportPassword: e.target.value})}/> <br/> <button class="settingButton" id="exportBtn" onClick={()=>this.exportFileHandler()}>Export</button> </div> </div> </div> </div>; } initSpread(spread) { this.spread = spread; } selectedFileChange(e) { let selectedFile = e.target.files[0]; this.setState({selectedFile, importDisabled: false}); } selectFileHandler() { this.selectedFileBtn.click(); } importFileHandler () { const wrongPasswordHandler = message => { this.setState({ showWarning: true, shakeAnimation: "shake 0.5s", warningMessage: message, importPassword: '' }); setTimeout(() => this.setState({shakeAnimation: ''}), 500); }; this.spread.import(this.state.selectedFile, console.log, error => { if (error.errorCode === GC.Spread.Sheets.IO.ErrorCode.noPassword || error.errorCode === GC.Spread.Sheets.IO.ErrorCode.invalidPassword ) { wrongPasswordHandler(error.errorMessage); } }, { fileType: GC.Spread.Sheets.FileType.excel, password: this.state.importPassword }); } exportFileHandler () { let password = this.state.exportPassword; this.spread.export(blob => saveAs(blob, (password ? 'encrypted-' : '') + 'export.xlsx'), console.log, { fileType: GC.Spread.Sheets.FileType.excel, password: password }); } initPassword() { this.setState({ showWarning: false, warningMessage: '' }); } }
<!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/js/FileSaver.js" type="text/javascript"></script> <!-- 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>
body { position: absolute; top: 0; bottom: 0; left: 0; right: 0; } #app { height: 100%; } .sample-tutorial { position: relative; height: 100%; overflow: hidden; } .sample-container { width: calc(100% - 280px); height: 100%; float: left; } .sample-spreadsheets { width: 100%; height: calc(100% - 25px); overflow: hidden; } .options-container { float: right; width: 280px; height: 100%; box-sizing: border-box; background: #fbfbfb; overflow: auto; } .sample-options { z-index: 1000; } .inputContainer { width: 100%; height: auto; border: 1px solid #eee; padding: 6px 12px; margin-bottom: 10px; box-sizing: border-box; } .settingButton { color: #fff; background: #82bc00; outline: 0; line-height: 1.5715; position: relative; display: inline-block; font-weight: 400; white-space: nowrap; text-align: center; height: 32px; padding: 4px 15px; font-size: 14px; border-radius: 2px; user-select: none; cursor: pointer; border: 1px solid #82bc00; box-sizing: border-box; margin-bottom: 10px; margin-top: 10px; margin-right: 5px; } .settingButton:hover { color: #fff; border-color: #88b031; background: #88b031; } .settingButton:disabled { background: #e2dfdf; border-color: #ffffff; } .options-title { font-weight: bold; margin: 4px 2px; } #selectedFile { display: none; } select, input[type="text"], input[type="number"] { display: inline-block; margin-left: auto; width: 120px; font-weight: 400; outline: 0; line-height: 1.5715; border-radius: 2px; border: 1px solid #F4F8EB; box-sizing: border-box; } .passwordIpt { margin-top: 10px; height: 25px; } .passwordIpt.warning { border-color: red; } .passwordIpt.warning::placeholder { color: red; opacity: 0.8; } @keyframes shake { 0% { transform: translate(1px, 1px) rotate(0deg); } 10% { transform: translate(-1px, -2px) rotate(-1deg); } 20% { transform: translate(-3px, 0px) rotate(1deg); } 30% { transform: translate(3px, 2px) rotate(0deg); } 40% { transform: translate(1px, -1px) rotate(1deg); } 50% { transform: translate(-1px, 2px) rotate(-1deg); } 60% { transform: translate(-3px, 1px) rotate(0deg); } 70% { transform: translate(3px, 1px) rotate(-1deg); } 80% { transform: translate(-1px, -1px) rotate(1deg); } 90% { transform: translate(1px, 2px) rotate(0deg); } 100% { transform: translate(1px, 1px) rotate(0deg); } } #warningBox { color: red; }
(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-react': 'npm:@mescius/spread-sheets-react/index.js', '@mescius/spread-sheets-io': 'npm:@mescius/spread-sheets-io/index.js', '@mescius/spread-sheets-charts': 'npm:@mescius/spread-sheets-charts/index.js', '@mescius/spread-sheets-shapes': 'npm:@mescius/spread-sheets-shapes/index.js', '@mescius/spread-sheets-slicers': 'npm:@mescius/spread-sheets-slicers/index.js', '@mescius/spread-sheets-pivot-addon': 'npm:@mescius/spread-sheets-pivot-addon/index.js', '@mescius/spread-sheets-reportsheet-addon': 'npm:@mescius/spread-sheets-reportsheet-addon/index.js', '@mescius/spread-sheets-tablesheet': 'npm:@mescius/spread-sheets-tablesheet/index.js', '@mescius/spread-sheets-ganttsheet': 'npm:@mescius/spread-sheets-ganttsheet/index.js', '@grapecity/jsob-test-dependency-package/react-components': 'npm:@grapecity/jsob-test-dependency-package/react-components/index.js', 'react': 'npm:react/umd/react.production.min.js', 'react-dom': 'npm:react-dom/umd/react-dom.production.min.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);