保護

SpreadJSでは、ワークブックに対するユーザー操作を制限できます。セルをロック/ロック解除したり、メニューを有効化/無効化したりすることで、ユーザーが編集できるかどうかを決定できます。

シート上の特定のセルに対し、その値を編集させたくない場合があります。isProtectedプロパティでシートを保護し編集を禁止することができます。 パスワード付きでシートを保護する場合、protect、unprotect および hasPasswordメソッドが使用できます。 protectionOptionを使用して、保護されたシート上でのユーザーアクションを制限できます。設定できるパラメータは以下のとおりです。 allowSelectLockedCells: ロックされたセルを選択できるかどうかを設定するBoolean値。 allowSelectUnlockedCells: ロックされていないセルを選択できるかどうかを設定するBoolean値。 allowSort: ソートを実行できるかどうかを設定するBoolean値。 allowFilter: フィルタを実行できるかどうかを設定するBoolean値。 allowEditObjects: フローティングオブジェクトを変更できるかどうかを設定するBoolean値。 allowResizeRows: 行をリサイズできるかどうかを設定するBoolean値。 allowResizeColumns: 列をリサイズできるかどうかを設定するBoolean値。 allowDragInsertRows: ユーザーが行をドラッグ挿入できるかどうかを設定するBoolean値。 allowDragInsertColumns: ユーザーが列をドラッグ挿入できるかどうかを設定するBoolean値。 allowInsertRows: ユーザーが行を挿入できるかどうかを設定するBoolean値。 allowInsertColumns: ユーザーが列を挿入できるかどうかを設定するBoolean値。 allowDeleteRows: ユーザーが行を削除できるかどうかを設定するBoolean値。 allowDeleteColumns: ユーザーが列を削除できるかどうかを設定するBoolean値。 allowOutlineRows: ユーザーが行のアウトラインを展開または折り畳みできるかどうかを設定するBoolean値。 allowOutlineColumns: ユーザーが列のアウトラインを展開または折り畳みできるかどうかを設定するBoolean値。 allowUsePivotTable: ユーザーがピボットテーブルを使用できるかどうかを設定するBoolean値。
window.onload = function() { var spread = new GC.Spread.Sheets.Workbook(_getElementById('ss'), { sheetCount: 1 }); initSpread(spread); }; const passwordWrongTip = 'パスワードが正しくありません。'; const alreadyProtect = 'ワークシートは既に保護されています。'; const unprotectImg = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAYAAABXAvmHAAAACXBIWXMAAAsTAAALEwEAmpwYAAAB0UlEQVR4nO2YzU7CQBDHNyae9A30qF6NNlFv7QzhqheukN1An4Mbnv14A70YwgERX0XiWRNBKl8eMDGuGWy0LopoS0tl/8kkZLMT/r+dmW1axrS0tAKTYRjziJgCgFNEvAKAR0Tsub9pLUV72DTKsqw9ALhGRDkqaA/tZdOifD4/h4j7PxlX4gURC5QbtX/2B/PeKERqnlrBPU1vi/QR8dCyrO1kMrlAYZrmDgAcAcCTWgkA2I3EPA2j2vMAcAMA69/lJBKJDQC4VWfCiGKw6UZRT36UeU/e5heVSLGw5V6LXhMHv8g9VuBPWNhCxJoCsDVuLs2EkltjYct9QL2bME1zcdxc2qsA9FjYUq/EsPN9SwOgrsD4yuVyy5zzIue8K4SQkwz+9h8lzvlqkOadSRsXwyBOJpNZ8g1AJx+2efEBcRYEQDdCgLZvgKjMCzc0gNAVELqFfGkmW8i2bXl5cS7bTkO2mnVZrZQHa7EBqFbKUj73PwWtxQag7TSGAGgtNgCtZn0I4OH+Lj4A1bi3kG3bA8NUiVgOsQgwmAYQugJSt9Cst1An7q+UpQgBir4B0un0mhCiGYF5J5vNrrAgRN9n6BNHSO3UoZMPzLyW1j/XK1zJDTLJ864hAAAAAElFTkSuQmCC'; const protectImg = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAYAAABXAvmHAAAACXBIWXMAAAsTAAALEwEAmpwYAAAB10lEQVR4nO2Yz0rDQBDGB0Ev+gZ6VK+iAfWWzJRe9dL3qfVQlWwR/7yBXqT0JepD2Nar0h4s2ERq3YArW4LGrdZq0qSx+8FACDvw/XZmNmQBtLS0IpNhGLNElEPESyK6QcQnInL9Z/kuJ9fAJMqyrF1EbBCRGBZyjVwLk6J8Pj9DRAc/GVfilYiKMjdp//AH88EoJmpetoK/m8EW6RHRqWVZW9lsdl6GaZrbiHiGiC9qJRBxJxHzchjVnkfEO0Rc+y4nk8msI+K9OhNGEoMtTxR154eZD+RtfFGJHMQt/1gMmjj5Re65An8BcYuIagrA5qi5ciaU3BrELf8D9W7CNM2FUXPlWgXAhbilHolx54eWBiBdgdElDmGJMyhzBo7HQIwzOAOHM6j0jmAlOvM2tMdt3FNBbGiLEiyGBpA7H7d576MaV1EAOAkCPIYGSMq854cG8HQFQLdQKE1nCx3Pie71vnBbDeE266JbLfTfpQagWy0Ix3E+RR8iLQBuqzEA4LZuUwTQrA8CNGtpb6G9lA1xtdCvRCqH2IswQAMwXQGhW2iqW4jb0En1LyVnUEkQoBwaoMdglTN4iN28De3nEixDFJL3M/KKI4524jZ05M5HZl5L65/rDc6nQtkkwmMVAAAAAElFTkSuQmCC'; function initSpread(spread) { var sheet = spread.getActiveSheet(); spread.suspendPaint(); var salesData = [ ['担当者', '地域', '売上'], ['ジョー', '北部', 3220], ['ロバート', '南部', 3214], ['ミシェル', '東部', 4233], ['エーリヒ', '西部', 1235], ['ダフナ', '北部', 3241], ['ロブ', '南部', 2135], ['ジョー', '北部', 2130], ['ロバート', '南部', 4510], ['ミシェル', '東部', 4550], ['エーリヒ', '西部', 3250], ['ダフナ', '北部', 3310], ['ロブ', '南部', 2350], ['ジョー', '北部', 2345], ['ロバート', '南部', 2370], ['ミシェル', '東部', 3980] ]; sheet.setArray(0, 0, salesData); sheet.setColumnWidth(0, 100); sheet.setColumnWidth(1, 100); sheet.setColumnWidth(2, 80); // ロック解除されたセル var style = new GC.Spread.Sheets.Style(); style.locked = false; style.backColor = '#C3C3C3'; sheet.setStyle(-1, 8, style); sheet.setStyle(-1, 9, style); sheet.setStyle(15, -1, style); sheet.setStyle(16, -1, style); sheet.setStyle(8, 2, style); // ロックされたセル var style2 = new GC.Spread.Sheets.Style(); style2.locked = true; style2.backColor = '#F4F8EB'; sheet.setStyle(13, -1, style2); sheet.setStyle(18, 8, style2); sheet.setStyle(0, 0, style2) sheet.setStyle(0, 1, style2); sheet.setStyle(0, 2, style2); let pivotTable = sheet.pivotTables.add("pivotTable1", 'Sheet1!A1:C16', 1, 11, GC.Spread.Pivot.PivotTableLayoutType.tabular, GC.Spread.Pivot.PivotTableThemes.medium8); pivotTable.suspendLayout(); pivotTable.add("salesperson", "担当者", GC.Spread.Pivot.PivotTableFieldType.rowField); pivotTable.add("region", "地域", GC.Spread.Pivot.PivotTableFieldType.columnField); pivotTable.add("sales", "売上", GC.Spread.Pivot.PivotTableFieldType.valueField, GC.Pivot.SubtotalType.sum); pivotTable.resumeLayout(); pivotTable.autoFitColumn(); var filter = new GC.Spread.Sheets.Filter.HideRowFilter(new GC.Spread.Sheets.Range(1, 0, 100, 3)); sheet.rowFilter(filter); sheet.comments.add(5, 4, 'ロックされたコメント'); sheet.comments.add(22, 4, 'ロック解除されたコメント'); sheet.comments.get(5, 4).locked(true).displayMode(1); sheet.comments.get(22, 4).locked(false).displayMode(1).lockText(false); var _commandManager = spread.commandManager(); _commandManager.execute({ cmd: "outlineColumn", sheetName: sheet.name(), index: 11, count: 3 }); _commandManager.execute({ cmd: "outlineRow", sheetName: sheet.name(), index: 18, count: 3 }); spread.resumePaint(); var option = { allowSelectLockedCells:true, allowSelectUnlockedCells:true, allowFilter: true, allowSort: false, allowResizeRows: true, allowResizeColumns: false, allowEditObjects: false, allowDragInsertRows: false, allowDragInsertColumns: false, allowInsertRows: false, allowInsertColumns: false, allowDeleteRows: false, allowDeleteColumns: false, allowOutlineColumns: false, allowOutlineRows: false, allowUsePivotTable: true, }; sheet.options.protectionOptions = option; sheet.options.isProtected = true; option = sheet.options.protectionOptions; _getElementById('chkSelectLockedCells').checked = option.allowSelectLockedCells; _getElementById('chkSelectUnlockedCells').checked = option.allowSelectUnlockedCells; _getElementById('chkAllowSort').checked = option.allowSort; _getElementById('chkAllowFilter').checked = option.allowFilter; _getElementById('chkAllowResizeRows').checked = option.allowResizeRows; _getElementById('chkAllowResizeColumns').checked = option.allowResizeColumns; _getElementById('chkAllowEditObjects').checked = option.allowEditObjects; _getElementById('chkAllowDragInsertRows').checked = option.allowDragInsertRows; _getElementById('chkAllowDragInsertColumns').checked = option.allowDragInsertColumns; _getElementById('chkAllowInsertRows').checked = option.allowInsertRows; _getElementById('chkAllowInsertColumns').checked = option.allowInsertColumns; _getElementById('chkAllowDeleteRows').checked = option.allowDeleteRows; _getElementById('chkAllowDeleteColumns').checked = option.allowDeleteColumns; _getElementById('chkallowOutlineColumns').checked = option.allowOutlineColumns; _getElementById('chkallowOutlineRows').checked = option.allowOutlineRows; _getElementById('chkAllowUsePivotTables').checked = option.allowUsePivotTable; const protectStatus = _getElementById('protectStatus'); const passwordInput = _getElementById('protectPassword') protectStatus.src = sheet.options.isProtected ? protectImg : unprotectImg; let protectBtn = _getElementById('protectBtn'), unprotectBtn = _getElementById('unprotectBtn'); protectBtn.disabled = true; protectBtn.addEventListener('click', function () { sheet = spread.getActiveSheet(); if (sheet.options.isProtected) { alert(alreadyProtect); return ; } const password = passwordInput.value; passwordInput.value = ''; sheet.protect(password); protectStatus.src = protectImg; protectBtn.disabled = true; unprotectBtn.disabled = false; }); unprotectBtn.addEventListener('click', function () { const password = passwordInput.value; sheet = spread.getActiveSheet(); if (sheet.hasPassword()) { let success = sheet.unprotect(password); if (!success) { alert(passwordWrongTip); return ; } } else { sheet.unprotect(); } passwordInput.value = ''; protectStatus.src = unprotectImg; protectBtn.disabled = false; unprotectBtn.disabled = true; }) _getElementById('setProtectionOptions').addEventListener('click', function() { var option = { allowSelectLockedCells: _getElementById('chkSelectLockedCells').checked, allowSelectUnlockedCells: _getElementById('chkSelectUnlockedCells').checked, allowSort: _getElementById('chkAllowSort').checked, allowFilter: _getElementById('chkAllowFilter').checked, allowResizeRows: _getElementById('chkAllowResizeRows').checked, allowResizeColumns: _getElementById('chkAllowResizeColumns').checked, allowEditObjects: _getElementById('chkAllowEditObjects').checked, allowDragInsertRows: _getElementById('chkAllowDragInsertRows').checked, allowDragInsertColumns: _getElementById('chkAllowDragInsertColumns').checked, allowInsertRows: _getElementById('chkAllowInsertRows').checked, allowInsertColumns: _getElementById('chkAllowInsertColumns').checked, allowDeleteRows: _getElementById('chkAllowDeleteRows').checked, allowDeleteColumns: _getElementById('chkAllowDeleteColumns').checked, allowOutlineColumns: _getElementById('chkallowOutlineColumns').checked, allowOutlineRows: _getElementById('chkallowOutlineRows').checked, allowUsePivotTable: _getElementById('chkAllowUsePivotTables').checked, }; var sheet = spread.getActiveSheet(); sheet.options.protectionOptions = option; }); } function _getElementById(id) { return document.getElementById(id); }
<!doctype html> <html style="height:100%;font-size:14px;"> <head> <meta name="spreadjs culture" content="ja-jp" /> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <link rel="stylesheet" type="text/css" href="$DEMOROOT$/ja/purejs/node_modules/@mescius/spread-sheets/styles/gc.spread.sheets.excel2013white.css"> <script src="$DEMOROOT$/ja/purejs/node_modules/@mescius/spread-sheets/dist/gc.spread.sheets.all.min.js" type="text/javascript"></script> <script src="$DEMOROOT$/ja/purejs/node_modules/@mescius/spread-sheets-resources-ja/dist/gc.spread.sheets.resources.ja.min.js" type="text/javascript"></script> <script src="$DEMOROOT$/ja/purejs/node_modules/@mescius/spread-sheets-shapes/dist/gc.spread.sheets.shapes.min.js" type="text/javascript"></script> <script src="$DEMOROOT$/ja/purejs/node_modules/@mescius/spread-sheets-pivot-addon/dist/gc.spread.pivot.pivottables.min.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 id="ss" class="sample-spreadsheets"></div> <aside class="options-container" aria-label="シート保護設定"> <div class="panel-header"> <div class="status-row"> <img id="protectStatus" class="status-icon" alt="" /> <div> <h1>シート保護</h1> <p class="panel-description">パスワードと操作権限を設定して、保護されたシートでユーザーに許可する編集操作を制御します。</p> </div> </div> </div> <section class="control-section"> <h2>保護状態</h2> <div class="field"> <label for="protectPassword">パスワード (オプション)</label> <input id="protectPassword" type="password" /> </div> <div class="button-row"> <input type="button" value="保護する" id="protectBtn" /> <input type="button" value="保護を解除する" id="unprotectBtn" /> </div> </section> <section class="control-section"> <h2>許可する操作</h2> <p class="hint">以下の保護オプションを使用して、シートの編集においてユーザーに許可する操作を制限します。</p> <div class="permission-list"> <label class="check-field" for="chkSelectLockedCells"> <input id="chkSelectLockedCells" type="checkbox" checked="checked" /> <span>ロックされたセルの選択</span> </label> <label class="check-field" for="chkSelectUnlockedCells"> <input id="chkSelectUnlockedCells" type="checkbox" checked="checked" /> <span>ロック解除されたセルの選択</span> </label> <label class="check-field" for="chkAllowSort"> <input id="chkAllowSort" type="checkbox" /> <span>並べ替え</span> </label> <label class="check-field" for="chkAllowFilter"> <input id="chkAllowFilter" type="checkbox" /> <span>フィルタ</span> </label> <label class="check-field" for="chkAllowResizeRows"> <input id="chkAllowResizeRows" type="checkbox" /> <span>行のサイズ変更</span> </label> <label class="check-field" for="chkAllowResizeColumns"> <input id="chkAllowResizeColumns" type="checkbox" /> <span>列のサイズ変更</span> </label> <label class="check-field" for="chkAllowEditObjects"> <input id="chkAllowEditObjects" type="checkbox" /> <span>フローティングオブジェクトの編集</span> </label> <label class="check-field" for="chkAllowDragInsertRows"> <input id="chkAllowDragInsertRows" type="checkbox" /> <span>ドラッグによる行の挿入</span> </label> <label class="check-field" for="chkAllowDragInsertColumns"> <input id="chkAllowDragInsertColumns" type="checkbox" /> <span>ドラッグによる列の挿入</span> </label> <label class="check-field" for="chkAllowInsertRows"> <input id="chkAllowInsertRows" type="checkbox" /> <span>行の挿入</span> </label> <label class="check-field" for="chkAllowInsertColumns"> <input id="chkAllowInsertColumns" type="checkbox" /> <span>列の挿入</span> </label> <label class="check-field" for="chkAllowDeleteRows"> <input id="chkAllowDeleteRows" type="checkbox" /> <span>行の削除</span> </label> <label class="check-field" for="chkAllowDeleteColumns"> <input id="chkAllowDeleteColumns" type="checkbox" /> <span>列の削除</span> </label> <label class="check-field" for="chkallowOutlineRows"> <input id="chkallowOutlineRows" type="checkbox" /> <span>アウトライン行の操作</span> </label> <label class="check-field" for="chkallowOutlineColumns"> <input id="chkallowOutlineColumns" type="checkbox" /> <span>アウトライン列の操作</span> </label> <label class="check-field" for="chkAllowUsePivotTables"> <input id="chkAllowUsePivotTables" type="checkbox" /> <span>ピボットテーブルの使用</span> </label> </div> <input type="button" value="設定" id="setProtectionOptions" class="primary-action" /> <p class="hint">保護オプションを選択して、[設定]をクリックします。</p> </section> </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-spreadsheets { flex: 1 1 auto; min-width: 0; height: 100%; overflow: hidden; } .options-container { flex: 0 0 340px; width: 340px; height: 100%; padding: 24px 20px; box-sizing: border-box; overflow: auto; background: #ffffff; border-left: 1px solid #e5e7eb; } .panel-header { padding-bottom: 20px; border-bottom: 1px solid #eef0f3; } .status-row { display: flex; gap: 12px; align-items: flex-start; } .status-icon { width: 32px; height: 32px; flex: 0 0 auto; } .panel-header h1 { margin: 0; font-size: 20px; font-weight: 650; line-height: 1.25; } .panel-description { margin: 8px 0 0; color: #6b7280; font-size: 13px; line-height: 1.55; } .control-section { padding: 20px 0; border-bottom: 1px solid #eef0f3; } .control-section:last-child { border-bottom: 0; } .control-section h2 { margin: 0 0 14px; color: #374151; font-size: 13px; font-weight: 700; line-height: 1.3; } .field { display: grid; gap: 7px; margin-bottom: 14px; } label { color: #374151; font-size: 13px; font-weight: 600; line-height: 1.35; } input[type="password"] { width: 100%; height: 34px; padding: 0 10px; box-sizing: border-box; color: #111827; font: inherit; background: #ffffff; border: 1px solid #d8dde5; border-radius: 6px; outline: none; transition: border-color .15s ease, box-shadow .15s ease; } input[type="password"]:focus { border-color: #2563eb; box-shadow: 0 0 0 3px rgba(37, 99, 235, .12); } .button-row { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; } input[type="button"] { min-height: 34px; padding: 0 12px; color: #1f2933; font: inherit; font-weight: 650; background: #f8fafc; border: 1px solid #d8dde5; border-radius: 6px; cursor: pointer; } input[type="button"]:hover:not(:disabled) { background: #eef2f7; } input[type="button"]:disabled { color: #9aa3af; cursor: not-allowed; background: #f3f4f6; } .primary-action { width: 100%; margin-top: 14px; color: #ffffff !important; background: #2563eb !important; border-color: #2563eb !important; } .primary-action:hover { background: #1d4ed8 !important; } .hint { margin: 0; color: #7a8492; font-size: 12px; line-height: 1.5; } .permission-list { display: grid; gap: 2px; margin-top: 12px; } .check-field { display: flex; gap: 10px; align-items: center; min-height: 30px; cursor: pointer; } .check-field input { width: 16px; height: 16px; margin: 0; accent-color: #2563eb; flex: 0 0 auto; } .check-field span { color: #1f2933; font-size: 13px; font-weight: 500; line-height: 1.35; } @media (max-width: 760px) { .sample-tutorial { flex-direction: column; } .sample-spreadsheets { min-height: 55%; } .options-container { flex: 0 0 auto; width: 100%; height: 45%; border-top: 1px solid #e5e7eb; border-left: 0; } }