前言 | 问题背景

本例是由一位用户提出的实际需求。在类似金额的票据中,一个单元格仅允许填写一位数字,每一个单元格都对应着一个数字位,例如千位、万位、百位等。

据此需求进行分析,可知需要实现以下几点基本操作:

  1. 需要把对应表格区域保护并锁定,不能直接允许用户编辑单元格内容,否则不能保证用户仅输入一位数字;
  2. 需要针对键盘事件进行监听,通过事件代码为单元格赋值,过滤掉除数字外的其它字符;
  3. 在一个单元格填写完毕后,活动单元格自动后移到下一个单元格上,不需要鼠标点选或键盘切换。

本文基于SpreadJS V12版本,下载请点击

示例代码分析

由以上分析可知,首先需要对表单进行保护设置,同时设置一下样式和表头,如下所示:

var spread = new GC.Spread.Sheets.Workbook(document.getElementById("ss"), { sheetCount : 1 });
var sheet = spread.getActiveSheet();
// 设置表单保护
sheet.options.isProtected = true;
sheet.setRowCount(5);
sheet.setColumnCount(9);
sheet.defaults.rowHeight = 60;
sheet.defaults.colWidth = 40;
var style = sheet.getDefaultStyle();
// 设置默认样式的边框
style.borderLeft =new GC.Spread.Sheets.LineBorder("black",GC.Spread.Sheets.LineStyle.thin);
style.borderTop = new GC.Spread.Sheets.LineBorder("black",GC.Spread.Sheets.LineStyle.thin);
style.borderRight = new GC.Spread.Sheets.LineBorder("black",GC.Spread.Sheets.LineStyle.thin);
style.borderBottom = new GC.Spread.Sheets.LineBorder("black",GC.Spread.Sheets.LineStyle.thin);
// 设置对齐方式
style.hAlign = GC.Spread.Sheets.HorizontalAlign.center;
style.vAlign = GC.Spread.Sheets.VerticalAlign.center;
sheet.setDefaultStyle(style);
var arr = ["百","十","万","千","百","十", "元", "角", "分"];
for(let i=0; i<arr.length; i++){
       sheet.setValue(0, i, arr[i], GC.Spread.Sheets.SheetArea.colHeader);
}
sheet.setRowHeight(0, 60, GC.Spread.Sheets.SheetArea.colHeader);

键盘事件需要绑定到div上,先进行字符过滤,再执行填值和移动单元格操作。如下所示:

$("#ss").keydown(function (event) {
    // 判断是否是键盘数字键
    var kc = event.keyCode;
    console.log(kc);
    var keyValue = -1;
    if(kc >= 48 && kc <= 57){
        keyValue = kc - 48;
    }else if(kc >= 96 && kc <= 105){
        keyValue = kc - 96;
    }
    if(keyValue >= 0){
        var sel = sheet.getSelections();
        if(sel && sel.length > 0){
            var row = sel[0].row;
            var col = sel[0].col;
            sheet.setValue(row, col, keyValue);
            // 调用命令向后移动一个单元格
            spread.commandManager().execute({
                cmd: "moveToNextCell",
                sheetName: sheet.name()
            });
        }
    }
});

需要完整示例,请点击此处下载

补充讨论

本例仅仅展示了最基础的实现思路,仍有很多没有完善的地方,由于篇幅因素,仅在此处进行讨论补充一下。例如:在用户填写错误时,如何撤销或删除?当页面上还有其他数据区域时,如何做到自动后移单元格不会超出金额区域?这些问题大家可以思考补充。