암호 지원

SpreadJS 파일 형식은 xlsx 파일을 가져오기/내보내기 위한 암호 사용을 지원합니다.

SpreadJS 파일 형식은 가져오기/내보내기 시 암호를 사용하여 암호화와 암호 해독을 지원합니다. 내보내기 예: 가져오기 예 에러 코드는 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="spreadjs culture" content="ko-kr" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <link rel="stylesheet" type="text/css" href="$DEMOROOT$/ko/purejs/node_modules/@mescius/spread-sheets/styles/gc.spread.sheets.excel2013white.css"> <script src="$DEMOROOT$/ko/purejs/node_modules/@mescius/spread-sheets/dist/gc.spread.sheets.all.min.js" type="text/javascript"></script> <script src="$DEMOROOT$/ko/purejs/node_modules/@mescius/spread-sheets-io/dist/gc.spread.sheets.io.min.js" type="text/javascript"></script> <script src="$DEMOROOT$/ko/purejs/node_modules/@mescius/spread-sheets-shapes/dist/gc.spread.sheets.shapes.min.js" type="text/javascript"></script> <script src="$DEMOROOT$/ko/purejs/node_modules/@mescius/spread-sheets-charts/dist/gc.spread.sheets.charts.min.js" type="text/javascript"></script> <script src="$DEMOROOT$/ko/purejs/node_modules/@mescius/spread-sheets-slicers/dist/gc.spread.sheets.slicers.min.js" type="text/javascript"></script> <script src="$DEMOROOT$/ko/purejs/node_modules/@mescius/spread-sheets-pivot-addon/dist/gc.spread.pivot.pivottables.min.js" type="text/javascript"></script> <script src="$DEMOROOT$/ko/purejs/node_modules/@mescius/spread-sheets-reportsheet-addon/dist/gc.spread.report.reportsheet.min.js" type="text/javascript"></script> <script src="$DEMOROOT$/ko/purejs/node_modules/@mescius/spread-sheets-tablesheet/dist/gc.spread.sheets.tablesheet.min.js" type="text/javascript"></script> <script src="$DEMOROOT$/ko/purejs/node_modules/@mescius/spread-sheets-ganttsheet/dist/gc.spread.sheets.ganttsheet.min.js" type="text/javascript"></script> <script src="$DEMOROOT$/ko/purejs/node_modules/@mescius/spread-sheets-resources-ko/dist/gc.spread.sheets.resources.ko.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; } }