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
const $ = selector => document.querySelector(selector); const listen = (host, type, handler) => host.addEventListener(type, handler); window.onload = function () { let spread = new GC.Spread.Sheets.Workbook(document.getElementById("ss")); const importPassword = $('#importPassword'); const selectBtn = $('#selectBtn'); const fileSelect = $('#selectedFile'); const importBtn = $('#importBtn'); const warningBox = $('#warningBox'); const exportPassword = $('#exportPassword'); const exportBtn = $('#exportBtn'); listen(selectBtn, "click", () => fileSelect.click()); const fileSelectedHandler = () => { importPassword.disabled = false; importBtn.disabled = false; } listen(fileSelect, 'change', fileSelectedHandler); const wrongPasswordHandler = message => { importPassword.setAttribute('warning', true); importPassword.style.animation = "shake 0.5s"; setTimeout(() => importPassword.style.animation = "", 500); warningBox.innerText = message; importPassword.value = ''; }; listen(importPassword, 'focus', () => { warningBox.innerText = ''; importPassword.removeAttribute('warning'); }); const importFileHandler = () => { let file = fileSelect.files[0]; if (!file) return ; spread.import(file, 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: importPassword.value }); }; listen(importBtn, 'click', importFileHandler); const exportFileHandler = () => { let password = exportPassword.value; spread.export(blob => saveAs(blob, (password ? 'encrypted-' : '') + 'export.xlsx'), console.log, { fileType: GC.Spread.Sheets.FileType.excel, password: password }); }; listen(exportBtn, 'click', exportFileHandler); };
<!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/purejs/node_modules/@mescius/spread-sheets/styles/gc.spread.sheets.excel2013white.css"> <script src="$DEMOROOT$/en/purejs/node_modules/@mescius/spread-sheets/dist/gc.spread.sheets.all.min.js" type="text/javascript"></script> <script src="$DEMOROOT$/en/purejs/node_modules/@mescius/spread-sheets-io/dist/gc.spread.sheets.io.min.js" type="text/javascript"></script> <script src="$DEMOROOT$/en/purejs/node_modules/@mescius/spread-sheets-shapes/dist/gc.spread.sheets.shapes.min.js" type="text/javascript"></script> <script src="$DEMOROOT$/en/purejs/node_modules/@mescius/spread-sheets-charts/dist/gc.spread.sheets.charts.min.js" type="text/javascript"></script> <script src="$DEMOROOT$/en/purejs/node_modules/@mescius/spread-sheets-slicers/dist/gc.spread.sheets.slicers.min.js" type="text/javascript"></script> <script src="$DEMOROOT$/en/purejs/node_modules/@mescius/spread-sheets-pivot-addon/dist/gc.spread.pivot.pivottables.min.js" type="text/javascript"></script> <script src="$DEMOROOT$/en/purejs/node_modules/@mescius/spread-sheets-reportsheet-addon/dist/gc.spread.report.reportsheet.min.js" type="text/javascript"></script> <script src="$DEMOROOT$/en/purejs/node_modules/@mescius/spread-sheets-tablesheet/dist/gc.spread.sheets.tablesheet.min.js" type="text/javascript"></script> <script src="$DEMOROOT$/en/purejs/node_modules/@mescius/spread-sheets-ganttsheet/dist/gc.spread.sheets.ganttsheet.min.js" type="text/javascript"></script> <script src="$DEMOROOT$/spread/source/js/FileSaver.js" type="text/javascript"></script> <script src="$DEMOROOT$/spread/source/js/license.js" type="text/javascript"></script> <script src="app.js" type="text/javascript"></script> <link rel="stylesheet" type="text/css" href="styles.css"> </head> <body> <div class="sample-tutorial"> <div class="sample-container"> <div id="ss" class="sample-spreadsheets"></div> <div id="statusBar"></div> </div> <aside class="options-container" aria-label="Password settings"> <div class="panel-header"> <h1>Password Settings</h1> <p class="panel-description">Import and export encrypted Excel files with optional passwords.</p> </div> <div class="option-row"> <div class="inputContainer"> <div class="options-title">Import File</div> <label for="importPassword">Password</label> <input class="passwordIpt" id="importPassword" type="password" placeholder="Password" disabled> <div id="warningBox"></div> <input id="selectedFile" type="file" accept=".xlsx" /> <div class="inline-actions"> <button class="settingButton" id="selectBtn">Select</button> <button class="settingButton" id="importBtn" disabled>Import</button> </div> </div> <div class="inputContainer"> <div class="options-title">Export File</div> <label for="exportPassword">Password</label> <input class="passwordIpt" id="exportPassword" type="password" placeholder="Password"> <div class="inline-actions"> <button class="settingButton" id="exportBtn">Export</button> </div> </div> </div> </aside> </div></body> </html>
html, body { height: 100%; margin: 0; } body { position: absolute; inset: 0; color: #1f2933; background: #f7f8fa; } .sample-tutorial { display: flex; height: 100%; overflow: hidden; } .sample-container { display: flex; flex: 1 1 auto; flex-direction: column; min-width: 0; height: 100%; } .sample-spreadsheets { flex: 1 1 auto; min-height: 0; overflow: hidden; } .options-container { flex: 0 0 320px; width: 320px; height: 100%; padding: 18px 16px; box-sizing: border-box; overflow: auto; overflow-x: hidden; background: #fff; border-left: 1px solid #e5e7eb; } .panel-header { padding-bottom: 14px; margin-bottom: 16px; border-bottom: 1px solid #edf0f3; } .panel-header h1 { margin: 0 0 6px; font-size: 18px; font-weight: 600; line-height: 1.25; } .panel-description { margin: 0; color: #5f6b7a; font-size: 12px; line-height: 1.4; } .option-row { display: grid; gap: 14px; } .inputContainer { display: grid; gap: 7px; width: 100%; min-width: 0; padding-bottom: 14px; border-bottom: 1px solid #edf0f3; box-sizing: border-box; } .inputContainer:last-child { border-bottom: 0; } .options-title { color: #111827; font-size: 13px; font-weight: 600; line-height: 1.35; } .options-container label { color: #4b5563; font-size: 12px; line-height: 1.35; } .passwordIpt { width: 100%; min-width: 0; height: 30px; padding: 0 8px; color: #1f2933; border: 1px solid #cfd6df; border-radius: 6px; box-sizing: border-box; outline: 0; } .passwordIpt:focus { border-color: #2f6fed; box-shadow: 0 0 0 2px rgba(47, 111, 237, 0.14); } .passwordIpt[warning="true"] { border-color: #dc2626; } .passwordIpt[warning="true"]::placeholder { color: #dc2626; opacity: 0.8; } #warningBox { min-height: 16px; color: #dc2626; font-size: 12px; line-height: 1.35; } #selectedFile { display: none; } .inline-actions { display: flex; gap: 8px; align-items: center; min-width: 0; } .settingButton { display: inline-flex; align-items: center; justify-content: center; min-width: 76px; height: 32px; padding: 0 12px; color: #1d4ed8; background: #fff; border: 1px solid #9db7f5; border-radius: 6px; box-sizing: border-box; font-size: 13px; font-weight: 500; line-height: 1; white-space: nowrap; cursor: pointer; } .settingButton:hover { color: #123f9d; border-color: #5f86e8; background: #f7faff; } .settingButton:disabled { color: #9aa4b2; background: #f3f5f7; border-color: #d8dee6; cursor: not-allowed; } @keyframes shake { 0% { transform: translate(1px, 1px) rotate(0deg); } 10% { transform: translate(-1px, -2px) rotate(-1deg); } 20% { transform: translate(-3px, 0) 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); } } @media (max-width: 760px) { .sample-tutorial { flex-direction: column; } .sample-container { flex: 1 1 55%; height: 55%; } .options-container { flex: 1 1 45%; width: 100%; height: 45%; border-top: 1px solid #e5e7eb; border-left: 0; } }