自定义 Ribbon 布局

SpreadJS Designer 支持灵活自定义 Ribbon 工具栏布局,您可以根据业务需求隐藏不需要的选项卡和按钮组,禁用特定功能,甚至自定义界面文本。这使您能够创建精简、专注的表格编辑界面,提升用户操作效率。

概述 本 Demo 展示了如何自定义 SpreadJS Designer 的 Ribbon 工具栏布局。通过修改 Designer 配置,实现了隐藏特定选项卡和按钮组、禁用功能按钮、自定义本地化文本以及移除右键菜单项等功能。 实现思路 获取 Designer 的默认配置对象 DefaultConfig 通过数组过滤方法隐藏不需要的 Ribbon 选项卡(仅保留 home、data、view) 在保留的选项卡中进一步过滤按钮组,只显示必要的功能区域 使用 commandMap 的 enableContext 属性禁用特定按钮 使用 getResources() 和 setResources() 方法自定义界面文本 从 contextMenu 数组中移除不需要的右键菜单项 使用自定义配置初始化 Designer 实例 代码解析 隐藏 Ribbon 选项卡 这段代码从默认配置中获取 ribbon 数组,使用 filter 方法移除 id 为 'insert'、'pageLayout'、'formulas' 和 'settings' 的选项卡,仅保留 home、data 和 view 选项卡。 隐藏按钮组 每个 Ribbon 选项卡包含多个 buttonGroups(按钮组)。这段代码先找到 home 选项卡,然后过滤掉标签为'数字'、'样式'和'编辑'的按钮组。 禁用按钮 通过在 commandMap 中设置命令的 enableContext 为字符串 'false',可以永久禁用这些按钮。decreaseIndent 和 increaseIndent 是减少缩进和增加缩进按钮,orientationList 是文字方向下拉列表。 自定义本地化文本 使用 getResources() 获取资源对象,修改选项卡名称、按钮文本等内容,然后通过 setResources() 设置回去。这里将主要选项卡的文本改为英文大写形式,同时修改了确定和取消按钮的文本。 移除右键菜单项 config.contextMenu 是一个包含所有右键菜单命令名称的数组。通过遍历数组并使用 splice 方法,可以移除不需要的菜单项。commandNames 对象包含了所有命令的名称常量。 运行效果 Designer 启动后只显示 3 个选项卡:HOME、DATA、VIEW 每个选项卡中只包含特定的按钮组,界面更加简洁 缩进按钮和文字方向下拉列表处于禁用状态,无法点击 选项卡名称和部分按钮文本显示为英文大写形式 右键菜单中不显示富文本、插入批注、定义名称等菜单项 API 参考 GC.Spread.Sheets.Designer.DefaultConfig 获取 Designer 的默认配置对象,包含 ribbon 选项卡、contextMenu 右键菜单等完整配置信息。 config.ribbon Ribbon 选项卡数组,每个选项卡包含: id: 选项卡唯一标识 text: 显示文本 buttonGroups: 按钮组数组 config.commandMap 命令映射对象,用于自定义命令行为: enableContext: 控制按钮是否可用,设置为字符串 'false' 可永久禁用 visibleContext: 控制按钮是否可见 GC.Spread.Sheets.Designer.getResources() 返回当前的资源对象,包含所有界面文本的本地化字符串。 GC.Spread.Sheets.Designer.setResources(resources) 设置自定义的资源对象: resources: 包含修改后的本地化字符串的对象 config.contextMenu 右键菜单命令名称数组,移除数组中的项即可隐藏对应的右键菜单项。
window.onload = function () { initRibbon(); }; function initRibbon() { var config = GC.Spread.Sheets.Designer.DefaultConfig, commandNames = GC.Spread.Sheets.Designer.CommandNames; // Hide tabs except "Insert", "Page Layout", "Formula" and "Settings" config.ribbon = config.ribbon.filter( (rb) => rb.id !== 'insert' && rb.id !== 'pageLayout' && rb.id !== 'formulas' && rb.id !== 'settings' ); // Hide button except groups "Number", "Style" and "Edit" on Home tab let homeTab = config.ribbon.find((r) => r.id === 'home'); homeTab.buttonGroups = homeTab.buttonGroups.filter( (bg) => bg.label !== '数字' && bg.label !== '样式' && bg.label !== '编辑' ); // Hide button except groups "Data Binding", "Query and Connection", "Outline" in Data tab let dataTab = config.ribbon.find((r) => r.id === 'data'); dataTab.buttonGroups = dataTab.buttonGroups.filter( (bg) => bg.label !== '数据绑定' && bg.label !== '查询和连接' && bg.label !== '分级显示' ); // Hide button except groups "Zoom", "Viewport" and "Pane" in View tab let viewTab = config.ribbon.find((r) => r.id === 'view'); viewTab.buttonGroups = viewTab.buttonGroups.filter( (bg) => bg.label !== '显示比例' && bg.label !== '窗口' && bg.label !== '窗格' ); // Hide "Format" except button in cell button group let cellButtonGroup = homeTab.buttonGroups.find((bg) => bg.label === 'Cells'); if (cellButtonGroup) { cellButtonGroup.commandGroup.children = cellButtonGroup.commandGroup.children.filter( (cg) => cg.command !== 'cellsFormat' ); } // Disable some buttons config.commandMap = { // disable decreaseIndent decreaseIndent: { enableContext: 'false', }, // disable increaseIndent increaseIndent: { enableContext: 'false', }, // Disable orientationList orientationList: { enableContext: 'false', }, }; // Customizing the localization of the ribbon container var resources = GC.Spread.Sheets.Designer.getResources(); resources.ribbon.home.home = 'HOME'; resources.ribbon.data.data = 'DATA'; resources.ribbon.view.view = 'VIEW'; resources.ok = 'OK'; resources.cancel = 'CANCEL'; resources.formatDialog.title = 'FORMAT DIALOG'; resources.ribbon.home.wrapText = 'WRAP TEXT'; resources.ribbon.home.insert = 'INSERT'; resources.ribbon.home.Delete = 'DELETE'; GC.Spread.Sheets.Designer.setResources(resources); // Remove unnecessary context menu if (config.contextMenu) { const deleteMenu = [ commandNames.RichText, // RichText commandNames.InsertComment, // InsertComment commandNames.DefineName, // DefineName commandNames.CellTag, // CellTag commandNames.RowTag, // RowTag commandNames.ContextMenuOutlineColumn, // ContextMenuOutlineColumn commandNames.DesignerPasteFormulaFormatting, // DesignerPasteFormulaFormatting ]; for (let i = 0; i < config.contextMenu.length; i++) { var item = config.contextMenu[i]; if (deleteMenu.includes(item)) { config.contextMenu.splice(i, 1); } } } new GC.Spread.Sheets.Designer.Designer('ribbonHost', config); }
<!doctype html> <html style="height:100%;font-size:14px;"> <head> <meta name="spreadjs culture" content="zh-cn" /> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <link rel="stylesheet" type="text/css" href="$DEMOROOT$/zh/purejs/node_modules/@grapecity-software/spread-sheets/styles/gc.spread.sheets.excel2013white.css"> <link rel="stylesheet" type="text/css" href="$DEMOROOT$/zh/purejs/node_modules/@grapecity-software/spread-sheets-designer/styles/gc.spread.sheets.designer.light.min.css"> <script src="$DEMOROOT$/zh/purejs/node_modules/@grapecity-software/spread-sheets/dist/gc.spread.sheets.all.min.js" type="text/javascript"></script> <script src="$DEMOROOT$/zh/purejs/node_modules/@grapecity-software/spread-sheets-shapes/dist/gc.spread.sheets.shapes.min.js" type="text/javascript"></script> <script src="$DEMOROOT$/zh/purejs/node_modules/@grapecity-software/spread-sheets-charts/dist/gc.spread.sheets.charts.min.js" type="text/javascript"></script> <script src="$DEMOROOT$/zh/purejs/node_modules/@grapecity-software/spread-sheets-print/dist/gc.spread.sheets.print.min.js" type="text/javascript"></script> <script src="$DEMOROOT$/zh/purejs/node_modules/@grapecity-software/spread-sheets-barcode/dist/gc.spread.sheets.barcode.min.js" type="text/javascript"></script> <script src="$DEMOROOT$/zh/purejs/node_modules/@grapecity-software/spread-sheets-pdf/dist/gc.spread.sheets.pdf.min.js" type="text/javascript"></script> <script src="$DEMOROOT$/zh/purejs/node_modules/@grapecity-software/spread-sheets-languagepackages/dist/gc.spread.calcengine.languagepackages.min.js" type="text/javascript"></script> <script src="$DEMOROOT$/zh/purejs/node_modules/@grapecity-software/spread-sheets-pivot-addon/dist/gc.spread.pivot.pivottables.min.js" type="text/javascript"></script> <script src="$DEMOROOT$/zh/purejs/node_modules/@grapecity-software/spread-sheets-tablesheet/dist/gc.spread.sheets.tablesheet.min.js" type="text/javascript"></script> <script src="$DEMOROOT$/zh/purejs/node_modules/@grapecity-software/spread-sheets-formula-panel/dist/gc.spread.sheets.formulapanel.min.js" type="text/javascript"></script> <script src="$DEMOROOT$/zh/purejs/node_modules/@grapecity-software/spread-sheets-io/dist/gc.spread.sheets.io.min.js" type="text/javascript"></script> <script src="$DEMOROOT$/zh/purejs/node_modules/@grapecity-software/spread-sheets-resources-zh/dist/gc.spread.sheets.resources.zh.min.js" type="text/javascript"></script> <script src="$DEMOROOT$/zh/purejs/node_modules/@grapecity-software/spread-sheets-designer-resources-cn/dist/gc.spread.sheets.designer.resource.cn.min.js" type="text/javascript"></script> <script src="$DEMOROOT$/zh/purejs/node_modules/@grapecity-software/spread-sheets-designer/dist/gc.spread.sheets.designer.all.min.js" type="text/javascript"></script> <script src="$DEMOROOT$/spread/source/js/license.js" type="text/javascript"></script> <script src="$DEMOROOT$/spread/source/js/designer/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="ribbonHost"></div> <div id="ss"></div> </div> </body> </html>
.sample-tutorial { position: relative; height: 97vh; overflow: hidden; } body { position: absolute; top: 0; bottom: 0; left: 0; right: 0; } #ribbonHost { height: 100%; } .description { margin: 10px; width: 40%; } table { font-family: arial, sans-serif; border-collapse: collapse; width: 100%; } td, th { border: 1px solid #dddddd; text-align: left; padding: 8px; } th { background-color: #dcdcdc; } tr:nth-child(even) { background-color: #f5f5f5; }