オリジナルメニュー

このデモでは、リボンコンテナにおける全てのデフォルトタブを非表示に設定し、自分のニーズに合わせたオリジナルメニューを作成する方法を示しています。

リボンコンテナに追加されるカスタマイズメニューの一覧は以下の通りになります。 項目 説明 日付設定 日付と設定したセルと連動し、日付の設定と変更ができます。 計算 電卓ボタンを押下すると、ポップアップで電卓が表示されます。計算結果はセルの値と連動しています。 シート保護 ワークブックあるいはワークシートを保護します。保護されたシートは編集することができません。 保護解除 保護されたワークシートやワークブックの保護を解除し、編集可能に設定します。 進捗設定 「処理済み」をチェックした場合、選択行の背景色がグレーに設定されます。 高評価/低評価ボタン ボタンが押下されるとアラートが表示されます。 ステータスバー メールアドレスをクリックすると、メーラーが起動します。宛先と本文が設定済みです。 コンテキストメニュー コンテキストメニューに追加される「デフォルトスタイルの設定」をクリックするとセル選択ダイアログが表示されます。選択されたセル範囲の背景色が水色、フォント色が赤色に設定されます。また、ダイアログを開いてからのセル選択もできます。
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 GC from "@mescius/spread-sheets"; import "@mescius/spread-sheets-resources-ja"; import "@mescius/spread-sheets-designer-resources-ja"; import "@mescius/spread-sheets-pivot-addon"; GC.Spread.Common.CultureManager.culture("ja-jp"); import { Designer } from "@mescius/spread-sheets-designer-react"; import * as GC2 from "@mescius/inputman"; import {registerlic} from '$DEMOROOT$/spread/source/js/designer/react_vue/license.js'; registerlic(GC); const spreadNS = GC.Spread.Sheets; const InputMan = GC2.InputMan; const config = GC.Spread.Sheets.Designer.DefaultConfig; /* コンポーネントのクラス構造を定義 */ const defineDatePickerComponent = () => { let gcDateTime; function DatePicker() { GC.Spread.Sheets.Designer.AtomicComponentBase.call(this, ...arguments); } DatePicker.prototype = new GC.Spread.Sheets.Designer.AtomicComponentBase(); DatePicker.prototype.getTemplate = function () { return ` <div class="container" style="margin-top: 30px;"> <input style="width:150px" id="gcDateTime" class ='form_date'> </div> `; }; DatePicker.prototype.onMounted = function () { // InputManJS日付ピッカーを定義する gcDateTime = new InputMan.GcDateTime(document.getElementById("gcDateTime"), { displayFormatPattern: "yyy年M月d日", formatPattern: "yyyy/MM/dd", autoDropDown: true, }); gcDateTime.setValue(null); let picker = gcDateTime.addDropDown( InputMan.DropDownButtonAlignment.RightSide, InputMan.DateDropDownType.Calendar ); gcDateTime.setDropDownButtonVisible(false); gcDateTime.onValueChanged((sender, eArgs) => { this.raiseValueChanged(); }); }; DatePicker.prototype.onValueChanged = function (prevValue, nextValue, host) { if (nextValue != null && typeof nextValue === "object") { gcDateTime.setValue(nextValue); } else { gcDateTime.setValue(null); } }; DatePicker.prototype.updateValue = function () { if (gcDateTime.getValue() != null) { let value = gcDateTime.getValue().toLocaleDateString("ja-jp", { year: "numeric", month: "numeric", day: "numeric", }); return new Date(value); } }; return DatePicker; }; /* コンポーネントのクラス構造を定義 */ const defineCalculatorComponent = (spreadRef) => { let gcCalculator; function Calculator() { GC.Spread.Sheets.Designer.AtomicComponentBase.call(this, ...arguments); } Calculator.prototype = new GC.Spread.Sheets.Designer.AtomicComponentBase(); Calculator.prototype.getTemplate = function () { return ` <div class="container" style="margin-top: 30px;"> <input style="width:150px" id="calculator"> </div> `; }; Calculator.prototype.onMounted = function () { // InputManJSポップアップ電卓を定義する gcCalculator = new InputMan.GcNumber(document.getElementById("calculator"), { showCalculatorAsPopup: true, calculatorButtonPosition: InputMan.DropDownButtonAlignment.LeftSide, }); gcCalculator.onValueChanged((sender, eArgs) => { this.raiseValueChanged(); }); gcCalculator.onFocusOut(function (sender, args) { let dropdown = sender.getDropDownWindow(); if (dropdown && dropdown.isOpened()) { setTimeout(function () { spreadRef.spread.focus(false); sender.setFocus(); }); } }); }; Calculator.prototype.onValueChanged = function (prevValue, nextValue, host) { if (nextValue != null && typeof nextValue === "number") { gcCalculator.value = nextValue; } else { gcCalculator.value = 0; } }; Calculator.prototype.updateValue = function () { if (gcCalculator.value != null) { return Number(gcCalculator.value); } }; return Calculator; }; const initRibbon = (spreadRef) => { // 既存タブを非表示 for (let i = 0; i < config.ribbon.length; i++) { config.ribbon.shift(); } // 操作タブを追加 let newTab = { id: "operate", text: "オリジナル", buttonGroups: [], }; // 新しいタブ追加 config.ribbon.unshift(newTab); var newTab2 = { id: 'aboutSample', text: 'サンプルについて', iconClass: "ribbon-button-item-text", buttonGroups: [ { commandGroup: { children: [ { type: "textBlock", text: '本サンプルでは Bootstrap Icons を使用しています。\r\n\r\nCopyright (c) 2019-2023 The Bootstrap Authors', } ] } } ] }; config.ribbon.push(newTab2); // リボンコンテナのボタンを追加 let reactionGood = { label: "評価", thumbnailClass: "評価", commandGroup: { children: [ { commands: ["cmdReactionGood", "cmdReactionBad"], }, ], }, }; // チェックボックスの追加 let progressCheckbox = { label: "進捗設定", thumbnailClass: "", direction: "vertical", commandGroup: { children: [ { direction: "vertical", commands: ["cmdCompletionCheckbox"], }, ], }, }; // ドロップダウンリストを追加 let protectDropdownList = { label: "保護", thumbnailClass: "シートの保護", commandGroup: { children: [ { command: "cmdProtectDropdownList", type: "dropdown", children: ["cmdProtectSheet", "cmdProtectBook"], }, { command: "cmdUnProtect", children: ["cmdUnProtect"], }, ], }, }; // カスタムコンポーネント日付ピッカーを追加 let DatePicker = defineDatePickerComponent(); GC.Spread.Sheets.Designer.Designer.RegisterComponent("DatePicker", DatePicker); // カスタムコンポーネント電卓を追加 let Calculator = defineCalculatorComponent(spreadRef); GC.Spread.Sheets.Designer.Designer.RegisterComponent("Calculator", Calculator); // カスタムコンポーネントを追加 let customComponent = { label: "InputManJS コンポーネント", commandGroup: { children: [ { commands: ["cmdDatePicker"], }, { type: "separator", }, { commands: ["cmdCalculator"], }, ], }, }; // デフォルトスタイル設定メニュー let setDefaultStyle = { templateName: "setDefaultStyle ", title: "設定ダイアログ", content: [ { type: "FlexContainer", children: [ { type: "TextBlock", margin: "5px -4px", text: "設定範囲を選択します", }, { type: "RangeSelect", title: "範囲を選択します", absoluteReference: true, needSheetName: false, margin: "5px -5px", bindingPath: "range", }, ], }, ], }; // configコマンド作成 config.commandMap = { // 高評価ボタン cmdReactionGood: { title: "高評価", text: "高評価", iconClass: "cmdReactionGood", bigButton: "true", commandName: "cmdReactionGood", execute: async () => { alert("高評価!押しました。"); }, }, // 低評価ボタン cmdReactionBad: { title: "低評価", text: "低評価", iconClass: "cmdReactionBad", bigButton: "true", commandName: "cmdReactionBad", execute: async () => { alert("低評価!押しました。"); }, }, // 処理済みチェックボックス cmdCompletionCheckbox: { title: "処理済み", text: "処理済み", type: "checkbox", commandName: "cmdCompletionCheckbox", execute: async (context, propertyName) => { let state = context.getData("stateCompletionCheckbox"); context.setData("stateCompletionCheckbox", !state); let sheet = context.getWorkbook().getActiveSheet(); // 名前付きスタイルを設定 let rowStyle = new GC.Spread.Sheets.Style(); rowStyle.backColor = "#cccccc"; rowStyle.name = "rowStyle"; sheet.addNamedStyle(rowStyle); if (!state) { sheet.setStyle( sheet.getActiveRowIndex(), -1, sheet.getNamedStyle("rowStyle"), GC.Spread.Sheets.SheetArea.viewport ); } else { sheet.setStyle(sheet.getActiveRowIndex(), -1, null, GC.Spread.Sheets.SheetArea.viewport); } }, getState: (context) => { let sheet = context.getWorkbook().getActiveSheet(); let row = sheet.getActiveRowIndex(); if (sheet.getStyleName(row, -1, GC.Spread.Sheets.SheetArea.viewport) === "rowStyle") { context.setData("stateCompletionCheckbox", true); } else { context.setData("stateCompletionCheckbox", false); } return context.getData("stateCompletionCheckbox"); }, }, // カスタムコンポーネント(日付設定) cmdDatePicker: { title: "日付を設定する", text: "日付を設定する", commandName: "cmdDatePicker", type: "DatePicker", execute: async (context, propertyName, value) => { let sheet = context.getWorkbook().getActiveSheet(); //tips: valueをチェックしないと、入力以外の部分をクリックすると値クリアされる if (sheet && value) { let row = sheet.getActiveRowIndex(); let col = sheet.getActiveColumnIndex(); sheet.setValue(row, col, value); } }, getState: (designer) => { let spread = designer.getWorkbook(); let sheet = spread.getActiveSheet(); let row = sheet.getActiveRowIndex(); let col = sheet.getActiveColumnIndex(); let value = sheet.getValue(row, col); return value; }, }, // カスタムコンポーネント(電卓) cmdCalculator: { title: "計算", text: "計算", commandName: "cmdCalculator", type: "Calculator", execute: async (context, propertyName, value) => { let sheet = context.getWorkbook().getActiveSheet(); if (sheet && value) { let row = sheet.getActiveRowIndex(); let col = sheet.getActiveColumnIndex(); sheet.setValue(row, col, value); } }, getState: (designer) => { let spread = designer.getWorkbook(); let sheet = spread.getActiveSheet(); let row = sheet.getActiveRowIndex(); let col = sheet.getActiveColumnIndex(); let value = sheet.getValue(row, col); return value; }, }, // 保護解除ボタン cmdUnProtect: { iconClass: "cmdUnProtect", text: "保護解除", bigButton: "true", direction: '=IF(ribbonHeight>toolbarHeight, "vertical", "horizontal")', commandName: "cmdUnProtect", execute: async function (designer) { let workbook = designer.getWorkbook(); for (let i = 0; i < workbook.getSheetCount(); i++) { let sheet = workbook.getSheet(i); sheet.options.isProtected = false; } alert("保護を解除しました"); }, }, // シートの保護 cmdProtectDropdownList: { text: "シートの保護", iconClass: "cmdProtectSheet", commandName: "cmdProtectDropdownList", bigButton: "true", subCommands: ["cmdProtectSheet", "cmdProtectBook"], }, cmdProtectSheet: { iconClass: "cmdProtectSheets", bigButton: "=AND(ribbonHeight>toolbarHeight,NOT(inDropdown))", text: "ワークシートの保護", direction: '=IF(ribbonHeight>toolbarHeight, "vertical", "horizontal")', commandName: "cmdProtectSheet", execute: async function (designer) { let workbook = designer.getWorkbook(); let sheet = workbook.getActiveSheet(); sheet.options.isProtected = true; alert("ワークシートを保護しました"); }, }, cmdProtectBook: { iconClass: "cmdProtectBook", text: "ワークブックの保護", commandName: "cmdProtectBook", execute: async function (designer) { let workbook = designer.getWorkbook(); for (let i = 0; i < workbook.getSheetCount(); i++) { let sheet = workbook.getSheet(i); sheet.options.isProtected = true; } alert("ワークブックを保護しました"); }, }, // デフォルトスタイル設定ダイアログ cmdDefaultStyleDialog: { text: "デフォルトスタイルの設定", commandName: "cmdDefaultStyleDialog", // visibleContext:ClickRowHeader/ClickColHeader/ClickViewport visibleContext: "ClickViewport", execute: (context, propertyName) => { let sheet = context.getWorkbook().getActiveSheet(); let dialogOption = { range: GC.Spread.Sheets.CalcEngine.rangesToFormula(sheet.getSelections()), }; GC.Spread.Sheets.Designer.showDialog( "defaultStyleDialog", dialogOption, (result) => { if (!result) { return; } let selectedRange = GC.Spread.Sheets.CalcEngine.formulaToRanges(sheet, result.range); if ( selectedRange[0] && selectedRange[0].ranges && selectedRange[0].ranges[0] instanceof GC.Spread.Sheets.Range ) { selectedRange[0].ranges.forEach((element) => { let style = new GC.Spread.Sheets.Style(); style.hAlign = GC.Spread.Sheets.HorizontalAlign.center; style.backColor = "#ebf6f7"; style.foreColor = "red"; sheet .getRange(element.row, element.col, element.rowCount, element.colCount) .setStyle(style); }); } }, (error) => { console.error(error); } ); }, }, }; // リアクションボタン追加 config.ribbon[0].buttonGroups.unshift(reactionGood); // チェックボックス追加 config.ribbon[0].buttonGroups.unshift(progressCheckbox); // ドロップダウンリスト追加 config.ribbon[0].buttonGroups.unshift(protectDropdownList); // カスタムコンポーネント追加 config.ribbon[0].buttonGroups.unshift(customComponent); // コンテキストメニューを追加 if (config && config.contextMenu) { config.contextMenu.unshift("cmdDefaultStyleDialog"); } GC.Spread.Sheets.Designer.registerTemplate("defaultStyleDialog", setDefaultStyle); // リボンコンテナのローカライズのカスタマイズ let resources = GC.Spread.Sheets.Designer.getResources(); resources.ribbon.home.home = "home!"; resources.ok = "確定!"; resources.cancel = "キャンセル!"; resources.formatDialog.title = "書式設定ダイアログ!"; resources.ribbon.home.clear = "クリア!"; resources.ribbon.home.paste = "ペースト"; GC.Spread.Sheets.Designer.setResources(resources); return config; }; const initSheet = (spread) => { spread.suspendPaint(); let sheet = spread.getActiveSheet(); let salesData = [ ["種類", "製品名", "販売数(箱)", "売上(万円)", "利益(万円)", "販売日"], ["酒", "日本酒", 15, 290.4, 120.3], ["酒", "ワイン", 20, 549.3, 320.8], ["酒", "ビール", 150, 400.5, 210.5], ["酒", "焼酎", 21, 212.8, 60.4], ["飲料", "お茶", 100, 90.8, 10.4], ["飲料", "炭酸水", 90, 30.8, 9.5], ["飲料", "ジュース", 65, 103.5, 29.5], ]; sheet.setArray(0, 0, salesData); sheet.setColumnWidth(0, 120); sheet.setColumnWidth(1, 120); sheet.setColumnWidth(2, 100); sheet.setColumnWidth(3, 100); sheet.setColumnWidth(4, 100); sheet.setColumnWidth(5, 120); sheet.setRowHeight(0, 30); sheet.setValue(0, 6, "👈タイトルのスタイルはコンテキストメニューよりデフォルトスタイルで設定できます"); // コメント追加 sheet.comments.add(0, 5, "リボンコンテナの日付設定より簡単に設定できます"); sheet.comments.add(8, 3, "電卓を使って計算できます"); sheet.comments.add(8, 2, "電卓を使って計算できます"); spread.resumePaint(); setTimeout(initStatusBar, 1000); }; const initStatusBar = () => { // ステータスバー let statusBar = spreadNS.StatusBar.findControl(document.getElementsByClassName("gc-statusBar")); let StatusItem = GC.Spread.Sheets.StatusBar.StatusItem; function SendMail(name, options) { StatusItem.call(this, name, options); } SendMail.prototype = new StatusItem(); SendMail.prototype.onCreateItemView = function (container) { let item = document.createElement("div"); item.innerText = this.value; item.id = this.name; container.appendChild(item); container.addEventListener("click", function () { let address = item.id == "SendMailSales" ? "sales@sample-spreadjs.com" : "support@sample-spreadjs.com"; let subject = "SpreadJSについてのお問い合わせ"; let body = "お問い合わせ"; location.href = "mailto:" + address + "?subject=" + subject + "&body=" + body; }); }; let spanItem = new SendMail("SendMailSales", { menuContent: "セールス", value: "E-mail: sales@sample-spreadjs.com", tipText: "sales", }); let spanItem2 = new SendMail("SendMailSupport", { menuContent: "サポート", value: "E-mail: support@sample-spreadjs.com", tipText: "サポート", }); statusBar.add(spanItem); statusBar.add(spanItem2); } export function AppFunc() { let spreadRef = { spread: undefined } let config = initRibbon(spreadRef); const initDesigner = (designer) => { let workbook = designer.getWorkbook(); spreadRef.spread = workbook; initSheet(workbook); }; return ( <div class="sample-tutorial"> <Designer styleInfo={{ height: "100%" }} config={config} designerInitialized={(designer) => initDesigner(designer)} ></Designer> </div> ); }
import * as React from "react"; import GC from "@mescius/spread-sheets"; import "@mescius/spread-sheets-resources-ja"; import "@mescius/spread-sheets-designer-resources-ja"; import "@mescius/spread-sheets-pivot-addon"; GC.Spread.Common.CultureManager.culture("ja-jp"); import { Designer } from "@mescius/spread-sheets-designer-react"; import * as GC2 from "@mescius/inputman"; import {registerlic} from '$DEMOROOT$/spread/source/js/designer/react_vue/license.js'; registerlic(GC); const spreadNS = GC.Spread.Sheets; const InputMan = GC2.InputMan; const config = GC.Spread.Sheets.Designer.DefaultConfig; /* コンポーネントのクラス構造を定義 */ const defineDatePickerComponent = () => { let gcDateTime; function DatePicker() { GC.Spread.Sheets.Designer.AtomicComponentBase.call(this, ...arguments); } DatePicker.prototype = new GC.Spread.Sheets.Designer.AtomicComponentBase(); DatePicker.prototype.getTemplate = function () { return ` <div class="container" style="margin-top: 30px;"> <input style="width:150px" id="gcDateTime" class ='form_date'> </div> `; }; DatePicker.prototype.onMounted = function () { // InputManJS日付ピッカーを定義する gcDateTime = new InputMan.GcDateTime(document.getElementById("gcDateTime"), { displayFormatPattern: "yyy年M月d日", formatPattern: "yyyy/MM/dd", autoDropDown: true, }); gcDateTime.setValue(null); let picker = gcDateTime.addDropDown( InputMan.DropDownButtonAlignment.RightSide, InputMan.DateDropDownType.Calendar ); gcDateTime.setDropDownButtonVisible(false); gcDateTime.onValueChanged((sender, eArgs) => { this.raiseValueChanged(); }); }; DatePicker.prototype.onValueChanged = function (prevValue, nextValue, host) { if (nextValue != null && typeof nextValue === "object") { gcDateTime.setValue(nextValue); } else { gcDateTime.setValue(null); } }; DatePicker.prototype.updateValue = function () { if (gcDateTime.getValue() != null) { let value = gcDateTime.getValue().toLocaleDateString("ja-jp", { year: "numeric", month: "numeric", day: "numeric", }); return new Date(value); } }; return DatePicker; }; const initSheet = (spread) => { spread.suspendPaint(); let sheet = spread.getActiveSheet(); let salesData = [ ["種類", "製品名", "販売数(箱)", "売上(万円)", "利益(万円)", "販売日"], ["酒", "日本酒", 15, 290.4, 120.3], ["酒", "ワイン", 20, 549.3, 320.8], ["酒", "ビール", 150, 400.5, 210.5], ["酒", "焼酎", 21, 212.8, 60.4], ["飲料", "お茶", 100, 90.8, 10.4], ["飲料", "炭酸水", 90, 30.8, 9.5], ["飲料", "ジュース", 65, 103.5, 29.5], ]; sheet.setArray(0, 0, salesData); sheet.setColumnWidth(0, 120); sheet.setColumnWidth(1, 120); sheet.setColumnWidth(2, 100); sheet.setColumnWidth(3, 100); sheet.setColumnWidth(4, 100); sheet.setColumnWidth(5, 120); sheet.setRowHeight(0, 30); sheet.setValue(0, 6, "👈タイトルのスタイルはコンテキストメニューよりデフォルトスタイルで設定できます"); // コメント追加 sheet.comments.add(0, 5, "リボンコンテナの日付設定より簡単に設定できます"); sheet.comments.add(8, 3, "電卓を使って計算できます"); sheet.comments.add(8, 2, "電卓を使って計算できます"); spread.resumePaint(); setTimeout(initStatusBar, 1000); }; const initStatusBar = () => { // ステータスバー let statusBar = spreadNS.StatusBar.findControl(document.getElementsByClassName("gc-statusBar")); let StatusItem = GC.Spread.Sheets.StatusBar.StatusItem; function SendMail(name, options) { StatusItem.call(this, name, options); } SendMail.prototype = new StatusItem(); SendMail.prototype.onCreateItemView = function (container) { let item = document.createElement("div"); item.innerText = this.value; item.id = this.name; container.appendChild(item); container.addEventListener("click", function () { let address = item.id == "SendMailSales" ? "sales@sample-spreadjs.com" : "support@sample-spreadjs.com"; let subject = "SpreadJSについてのお問い合わせ"; let body = "お問い合わせ"; location.href = "mailto:" + address + "?subject=" + subject + "&body=" + body; }); }; let spanItem = new SendMail("SendMailSales", { menuContent: "セールス", value: "E-mail: sales@sample-spreadjs.com", tipText: "sales", }); let spanItem2 = new SendMail("SendMailSupport", { menuContent: "サポート", value: "E-mail: support@sample-spreadjs.com", tipText: "サポート", }); statusBar.add(spanItem); statusBar.add(spanItem2); } export class App extends React.Component { constructor(props) { super(props); this.spread = null; this.config = this.initRibbon(); } initDesigner(designer) { let workbook = designer.getWorkbook(); this.spread = workbook; initSheet(workbook); } render() { return ( <div class="sample-tutorial"> <Designer styleInfo={{ height: "100%" }} config={this.config} designerInitialized={(designer) => this.initDesigner(designer)} ></Designer> </div> ); } initRibbon() { // 既存タブを非表示 for (let i = 0; i < config.ribbon.length; i++) { config.ribbon.shift(); } // 操作タブを追加 let newTab = { id: "operate", text: "オリジナル", buttonGroups: [], }; // 新しいタブ追加 config.ribbon.unshift(newTab); var newTab2 = { id: 'aboutSample', text: 'サンプルについて', iconClass: "ribbon-button-item-text", buttonGroups: [ { commandGroup: { children: [ { type: "textBlock", text: '本サンプルでは Bootstrap Icons を使用しています。\r\n\r\nCopyright (c) 2019-2023 The Bootstrap Authors', } ] } } ] }; config.ribbon.push(newTab2); // リボンコンテナのボタンを追加 let reactionGood = { label: "評価", thumbnailClass: "評価", commandGroup: { children: [ { commands: ["cmdReactionGood", "cmdReactionBad"], }, ], }, }; // チェックボックスの追加 let progressCheckbox = { label: "進捗設定", thumbnailClass: "", direction: "vertical", commandGroup: { children: [ { direction: "vertical", commands: ["cmdCompletionCheckbox"], }, ], }, }; // ドロップダウンリストを追加 let protectDropdownList = { label: "保護", thumbnailClass: "シートの保護", commandGroup: { children: [ { command: "cmdProtectDropdownList", type: "dropdown", children: ["cmdProtectSheet", "cmdProtectBook"], }, { command: "cmdUnProtect", children: ["cmdUnProtect"], }, ], }, }; // カスタムコンポーネント日付ピッカーを追加 let DatePicker = defineDatePickerComponent(); GC.Spread.Sheets.Designer.Designer.RegisterComponent("DatePicker", DatePicker); // カスタムコンポーネント電卓を追加 let Calculator = this.defineCalculatorComponent(); GC.Spread.Sheets.Designer.Designer.RegisterComponent("Calculator", Calculator); // カスタムコンポーネントを追加 let customComponent = { label: "InputManJS コンポーネント", commandGroup: { children: [ { commands: ["cmdDatePicker"], }, { type: "separator", }, { commands: ["cmdCalculator"], }, ], }, }; // デフォルトスタイル設定メニュー let setDefaultStyle = { templateName: "setDefaultStyle ", title: "設定ダイアログ", content: [ { type: "FlexContainer", children: [ { type: "TextBlock", margin: "5px -4px", text: "設定範囲を選択します", }, { type: "RangeSelect", title: "範囲を選択します", absoluteReference: true, needSheetName: false, margin: "5px -5px", bindingPath: "range", }, ], }, ], }; // configコマンド作成 config.commandMap = { // 高評価ボタン cmdReactionGood: { title: "高評価", text: "高評価", iconClass: "cmdReactionGood", bigButton: "true", commandName: "cmdReactionGood", execute: async () => { alert("高評価!押しました。"); }, }, // 低評価ボタン cmdReactionBad: { title: "低評価", text: "低評価", iconClass: "cmdReactionBad", bigButton: "true", commandName: "cmdReactionBad", execute: async () => { alert("低評価!押しました。"); }, }, // 処理済みチェックボックス cmdCompletionCheckbox: { title: "処理済み", text: "処理済み", type: "checkbox", commandName: "cmdCompletionCheckbox", execute: async (context, propertyName) => { let state = context.getData("stateCompletionCheckbox"); context.setData("stateCompletionCheckbox", !state); let sheet = context.getWorkbook().getActiveSheet(); // 名前付きスタイルを設定 let rowStyle = new GC.Spread.Sheets.Style(); rowStyle.backColor = "#cccccc"; rowStyle.name = "rowStyle"; sheet.addNamedStyle(rowStyle); if (!state) { sheet.setStyle( sheet.getActiveRowIndex(), -1, sheet.getNamedStyle("rowStyle"), GC.Spread.Sheets.SheetArea.viewport ); } else { sheet.setStyle(sheet.getActiveRowIndex(), -1, null, GC.Spread.Sheets.SheetArea.viewport); } }, getState: (context) => { let sheet = context.getWorkbook().getActiveSheet(); let row = sheet.getActiveRowIndex(); if (sheet.getStyleName(row, -1, GC.Spread.Sheets.SheetArea.viewport) === "rowStyle") { context.setData("stateCompletionCheckbox", true); } else { context.setData("stateCompletionCheckbox", false); } return context.getData("stateCompletionCheckbox"); }, }, // カスタムコンポーネント(日付設定) cmdDatePicker: { title: "日付を設定する", text: "日付を設定する", commandName: "cmdDatePicker", type: "DatePicker", execute: async (context, propertyName, value) => { let sheet = context.getWorkbook().getActiveSheet(); //tips: valueをチェックしないと、入力以外の部分をクリックすると値クリアされる if (sheet && value) { let row = sheet.getActiveRowIndex(); let col = sheet.getActiveColumnIndex(); sheet.setValue(row, col, value); } }, getState: (designer) => { let spread = designer.getWorkbook(); let sheet = spread.getActiveSheet(); let row = sheet.getActiveRowIndex(); let col = sheet.getActiveColumnIndex(); let value = sheet.getValue(row, col); return value; }, }, // カスタムコンポーネント(電卓) cmdCalculator: { title: "計算", text: "計算", commandName: "cmdCalculator", type: "Calculator", execute: async (context, propertyName, value) => { let sheet = context.getWorkbook().getActiveSheet(); if (sheet && value) { let row = sheet.getActiveRowIndex(); let col = sheet.getActiveColumnIndex(); sheet.setValue(row, col, value); } }, getState: (designer) => { let spread = designer.getWorkbook(); let sheet = spread.getActiveSheet(); let row = sheet.getActiveRowIndex(); let col = sheet.getActiveColumnIndex(); let value = sheet.getValue(row, col); return value; }, }, // 保護解除ボタン cmdUnProtect: { iconClass: "cmdUnProtect", text: "保護解除", bigButton: "true", direction: '=IF(ribbonHeight>toolbarHeight, "vertical", "horizontal")', commandName: "cmdUnProtect", execute: async function (designer) { let workbook = designer.getWorkbook(); for (let i = 0; i < workbook.getSheetCount(); i++) { let sheet = workbook.getSheet(i); sheet.options.isProtected = false; } alert("保護を解除しました"); }, }, // シートの保護 cmdProtectDropdownList: { text: "シートの保護", iconClass: "cmdProtectSheet", commandName: "cmdProtectDropdownList", bigButton: "true", subCommands: ["cmdProtectSheet", "cmdProtectBook"], }, cmdProtectSheet: { iconClass: "cmdProtectSheets", bigButton: "=AND(ribbonHeight>toolbarHeight,NOT(inDropdown))", text: "ワークシートの保護", direction: '=IF(ribbonHeight>toolbarHeight, "vertical", "horizontal")', commandName: "cmdProtectSheet", execute: async function (designer) { let workbook = designer.getWorkbook(); let sheet = workbook.getActiveSheet(); sheet.options.isProtected = true; alert("ワークシートを保護しました"); }, }, cmdProtectBook: { iconClass: "cmdProtectBook", text: "ワークブックの保護", commandName: "cmdProtectBook", execute: async function (designer) { let workbook = designer.getWorkbook(); for (let i = 0; i < workbook.getSheetCount(); i++) { let sheet = workbook.getSheet(i); sheet.options.isProtected = true; } alert("ワークブックを保護しました"); }, }, // デフォルトスタイル設定ダイアログ cmdDefaultStyleDialog: { text: "デフォルトスタイルの設定", commandName: "cmdDefaultStyleDialog", // visibleContext:ClickRowHeader/ClickColHeader/ClickViewport visibleContext: "ClickViewport", execute: (context, propertyName) => { let sheet = context.getWorkbook().getActiveSheet(); let dialogOption = { range: GC.Spread.Sheets.CalcEngine.rangesToFormula(sheet.getSelections()), }; GC.Spread.Sheets.Designer.showDialog( "defaultStyleDialog", dialogOption, (result) => { if (!result) { return; } let selectedRange = GC.Spread.Sheets.CalcEngine.formulaToRanges(sheet, result.range); if ( selectedRange[0] && selectedRange[0].ranges && selectedRange[0].ranges[0] instanceof GC.Spread.Sheets.Range ) { selectedRange[0].ranges.forEach((element) => { let style = new GC.Spread.Sheets.Style(); style.hAlign = GC.Spread.Sheets.HorizontalAlign.center; style.backColor = "#ebf6f7"; style.foreColor = "red"; sheet .getRange(element.row, element.col, element.rowCount, element.colCount) .setStyle(style); }); } }, (error) => { console.error(error); } ); }, }, }; // リアクションボタン追加 config.ribbon[0].buttonGroups.unshift(reactionGood); // チェックボックス追加 config.ribbon[0].buttonGroups.unshift(progressCheckbox); // ドロップダウンリスト追加 config.ribbon[0].buttonGroups.unshift(protectDropdownList); // カスタムコンポーネント追加 config.ribbon[0].buttonGroups.unshift(customComponent); // コンテキストメニューを追加 if (config && config.contextMenu) { config.contextMenu.unshift("cmdDefaultStyleDialog"); } GC.Spread.Sheets.Designer.registerTemplate("defaultStyleDialog", setDefaultStyle); // リボンコンテナのローカライズのカスタマイズ let resources = GC.Spread.Sheets.Designer.getResources(); resources.ribbon.home.home = "home!"; resources.ok = "確定!"; resources.cancel = "キャンセル!"; resources.formatDialog.title = "書式設定ダイアログ!"; resources.ribbon.home.clear = "クリア!"; resources.ribbon.home.paste = "ペースト"; GC.Spread.Sheets.Designer.setResources(resources); return config; } /* コンポーネントのクラス構造を定義 */ defineCalculatorComponent() { let self = this; let gcCalculator; function Calculator() { GC.Spread.Sheets.Designer.AtomicComponentBase.call(this, ...arguments); } Calculator.prototype = new GC.Spread.Sheets.Designer.AtomicComponentBase(); Calculator.prototype.getTemplate = function () { return ` <div class="container" style="margin-top: 30px;"> <input style="width:150px" id="calculator"> </div> `; }; Calculator.prototype.onMounted = function () { // InputManJSポップアップ電卓を定義する gcCalculator = new InputMan.GcNumber(document.getElementById("calculator"), { showCalculatorAsPopup: true, calculatorButtonPosition: InputMan.DropDownButtonAlignment.LeftSide, }); gcCalculator.onValueChanged((sender, eArgs) => { this.raiseValueChanged(); }); gcCalculator.onFocusOut(function (sender, args) { let dropdown = sender.getDropDownWindow(); if (dropdown && dropdown.isOpened()) { setTimeout(function () { self.spread.focus(false); sender.setFocus(); }); } }); }; Calculator.prototype.onValueChanged = function (prevValue, nextValue, host) { if (nextValue != null && typeof nextValue === "number") { gcCalculator.value = nextValue; } else { gcCalculator.value = 0; } }; Calculator.prototype.updateValue = function () { if (gcCalculator.value != null) { return Number(gcCalculator.value); } }; return Calculator; } }
<!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$/ja/react/node_modules/@mescius/spread-sheets/styles/gc.spread.sheets.excel2013white.css"> <link rel="stylesheet" type="text/css" href="$DEMOROOT$/ja/react/node_modules/@mescius/spread-sheets-designer/styles/gc.spread.sheets.designer.min.css"> <link rel="stylesheet" type="text/css" href="$DEMOROOT$/ja/react/node_modules/@mescius/inputman/CSS/gc.inputman-js.css"> <!-- SystemJS --> <script src="$DEMOROOT$/ja/react/node_modules/systemjs/dist/system.src.js"></script> <script src="systemjs.config.js"></script> <script> System.import('$DEMOROOT$/ja/lib/react/license.js').then(function () { System.import('$DEMOROOT$/spread/source/js/inputman/react_vue/license.js').then(() => { System.import('./src/app'); }); }); </script> </head> <body> <div id="app"></div> </body> </html>
.sample-tutorial { position: relative; height: 98vh; overflow: hidden; } body { position: absolute; top: 0; bottom: 0; left: 0; right: 0; } #app { height: 100%; } .description { margin: 10px; width: 40%; } .gcim-dropdown table { font-family: arial, sans-serif; border-collapse: collapse; width: 100%; } .gcim-dropdown td, th { border: 1px solid #dddddd; text-align: left; padding: 8px; } .gcim-dropdown th { background-color: #dcdcdc; } .gcim-dropdown tr:nth-child(even) { background-color: #f5f5f5; } .cmdReactionGood { background-image: url("icons/hand-thumbs-up.svg"); } .cmdReactionBad { background-image: url("icons/hand-thumbs-down.svg"); } .cmdProtectSheet { background-image: url("icons/lock.svg"); background-size: 35px 35px; } .cmdUnProtect { background-image: url("icons/unlock.svg"); } .cmdProtectSheets { background-image: url("icons/file-earmark-spreadsheet.svg"); } .cmdProtectBook { background-image: url("icons/book.svg"); }
(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-resources-ja': 'npm:@mescius/spread-sheets-resources-ja/index.js', '@mescius/spread-sheets-react': 'npm:@mescius/spread-sheets-react/index.js', '@mescius/spread-excelio': 'npm:@mescius/spread-excelio/index.js', '@mescius/spread-sheets-barcode': 'npm:@mescius/spread-sheets-barcode/index.js', '@mescius/spread-sheets-charts': 'npm:@mescius/spread-sheets-charts/index.js', '@mescius/spread-sheets-languagepackages': 'npm:@mescius/spread-sheets-languagepackages/index.js', '@mescius/spread-sheets-print': 'npm:@mescius/spread-sheets-print/index.js', '@mescius/spread-sheets-pdf': 'npm:@mescius/spread-sheets-pdf/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-formula-panel': 'npm:@mescius/spread-sheets-formula-panel/index.js', '@mescius/spread-sheets-tablesheet': 'npm:@mescius/spread-sheets-tablesheet/index.js', '@mescius/spread-sheets-io': 'npm:@mescius/spread-sheets-io/index.js', '@mescius/spread-sheets-pivot-addon': 'npm:@mescius/spread-sheets-pivot-addon/index.js', '@mescius/spread-sheets-designer': 'npm:@mescius/spread-sheets-designer/index.js', '@mescius/spread-sheets-designer-react': 'npm:@mescius/spread-sheets-designer-react/index.js', '@mescius/spread-sheets-designer-resources-ja': 'npm:@mescius/spread-sheets-designer-resources-ja/index.js', '@grapecity/jsob-test-dependency-package/react-components': 'npm:@grapecity/jsob-test-dependency-package/react-components/index.js', '@mescius/inputman': 'npm:@mescius/inputman/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);