- 前端
- UI组件
【免费下载链接】ce
Jspreadsheet is a lightweight JavaScript data grid component for creating interactive data grids with advanced spreadsheet controls.
Jspreadsheet 是一个轻量级的 JavaScript 数据网格组件,其核心能力之一便是"列类型(column types)"系统:通过为每一列声明一个type,即可让单元格获得对应的渲染方式与编辑交互,覆盖文本、数值、下拉、日期、图片、颜色、富文本等常见场景。本篇指南基于仓库中的 column-types 官方示例 展开,并结合 src/utils/internal.js、src/utils/editor.js、src/utils/columns.js 的源码实现,系统讲解 11 种内置列类型的使用方法、关键配置参数、底层渲染与编辑原理,并完整演示如何基于第三方插件(如 clockpicker)创建自定义列类型。读完本篇,你将能够在自己的项目中熟练配置各类列、自定义列渲染与编辑器,并理解 Jspreadsheet 列类型体系的工作机制。
内置列类型总览
Jspreadsheet 原生支持以下 11 种列类型:
text:纯文本列,默认类型numeric:数值列,支持掩码(mask)与小数点符号配置hidden:隐藏列,不参与显示但仍保留数据dropdown:下拉选择列autocomplete:带自动补全搜索的下拉列(基于 dropdown 的autocomplete选项)checkbox:复选框列radio:单选按钮列calendar:日期/时间选择列image:图片列(基于 data URL)color:颜色列html:富文本 HTML 列
这些类型在源码中均有对应的渲染与编辑分支。以单元格创建为例,src/utils/internal.js 中的createCell函数会根据列定义分派渲染逻辑:checkbox/radio 会生成<input>元素、calendar 会调用jSuites.calendar格式化日期、dropdown 会通过getDropDownValue将存储的键值映射为可读文本、color 会根据render选项渲染色块或文字、image 会识别data:image前缀生成<img>标签、html 则会剥离<script>后再写入innerHTML。这说明列类型不仅仅影响"长得什么样",也决定了数据在单元格中的呈现与存取方式。
除了type本身,列类型还接受若干通用属性来改变行为,例如title(表头标题)、width(列宽)、align(对齐方式)、readOnly(只读)、wordWrap(自动换行)等。其中width、align在 src/utils/columns.js 的createCellHeader中会作为默认值兜底:未显式配置时使用defaultColWidth(默认 100)与defaultColAlign(默认center)。
一次展示 7 种内置类型:入门示例
官方示例在一个表格中同时演示了text、dropdown、calendar、image、checkbox、numeric、color七种类型的组合使用,是理解列类型最直观的起点:
<html> <script src="https://bossanova.uk/jspreadsheet/v4/jspreadsheet.js"></script> <script src="https://jsuites.net/v5/jsuites.js"></script> <link rel="stylesheet" href="https://bossanova.uk/jspreadsheet/v4/jspreadsheet.css" type="text/css" /> <link rel="stylesheet" href="https://jsuites.net/v5/jsuites.css" type="text/css" /> <div id="spreadsheet"></div> <script> var data = [ ['Jazz', 'Honda', '2019-02-12', '', true, '$ 2.000,00', '#777700'], ['Civic', 'Honda', '2018-07-11', '', true, '$ 4.000,01', '#007777'], ]; jspreadsheet(document.getElementById('spreadsheet'), { data:data, columns: [ { type: 'text', title:'Car', width:120 }, { type: 'dropdown', title:'Make', width:200, source:[ "Alfa Romeo", "Audi", "Bmw" ] }, { type: 'calendar', title:'Available', width:200 }, { type: 'image', title:'Photo', width:120 }, { type: 'checkbox', title:'Stock', width:80 }, { type: 'numeric', title:'Price', width:100, mask:'$ #.##,00', decimal:',' }, { type: 'color', width:100, render:'square', } ] }); </script> </html>逐列解读这个配置:
- Car(text):普通文本列,
title定义表头文字,width定义列宽。 - Make(dropdown):下拉列,
source传入字符串数组即生成下拉选项;编辑时点击单元格会弹出 jSuites dropdown。 - Available(calendar):日历列,直接渲染
YYYY-MM-DD格式的日期,点击后弹出日期选择器。 - Photo(image):图片列,数据需为
data:image/...形式的 base64 URL,渲染时自动生成<img>标签。 - Stock(checkbox):复选框列,数据中
true/1对应勾选状态。 - Price(numeric):数值列,
mask:'$ #.##,00'定义显示掩码(千分位用.、小数位用,),decimal:','指定小数分隔符,因此数据2000会显示为$ 2.000,00。 - color:颜色列,
render:'square'表示以纯色方块形式展示颜色值(十六进制字符串);省略该选项时则直接以该颜色渲染文字。
关于数值掩码的底层处理
numeric列的掩码并非只在展示层生效。src/utils/internal.js 的parseValue会调用jSuites.mask.render对数值进行掩码渲染;而 src/utils/editor.js 的closeEditor在保存numeric列时做了特殊处理:若输入为空且未设置allowEmpty,则落库为0。此外 src/utils/internal.js 的parseNumber会根据列的decimal配置解析带掩码的字符串为真正的数值,供公式计算使用。也就是说,掩码只负责"显示",底层数据仍是可计算的纯数字。
其他内置类型的进阶配置
官方文档指出,dropdown与calendar两种类型拥有更多高级配置,下面分别补充说明。
dropdown / autocomplete:从简单数组到条件联动
下拉列并不局限于简单的字符串数组,dropdown-and-autocomplete 示例 展示了多种进阶用法:
- autocomplete + multiple:同时设置
autocomplete:true, multiple:true后,下拉框支持输入搜索与多选,多选值以;分隔存储(如'CA;US;UK')。 - url 远程数据:
url:'/jspreadsheet/countries'可从外部 JSON 接口动态加载选项。 - 键值对对象:
source:[ {'id':'1', 'name':'Fruits'} ]形式的数据,单元格存储id、显示name——src/utils/internal.js 的getDropDownValue正是负责这一映射(还兼容数组键值、;分隔的多值)。 - 条件联动 dropdown:通过
filter:function(instance, cell, c, r, source)回调,根据同列或前列的值动态返回候选集。在 src/utils/editor.js 中,打开编辑器时会优先使用该filter回调的返回结果作为下拉数据源。 - 分组与图片选项:
source对象支持image、title、group字段,配合options:{ type:'picker' }可渲染出带分组和头像的响应式选择器。
从源码看,dropdown 列的编辑由 src/utils/editor.js 的openEditor实现:它会基于列的multiple、autocomplete选项调用jSuites.dropdown(editor, options)创建下拉组件,并在关闭时通过cell.children[0].dropdown.close(true)取回值(见 closeEditor)。
calendar:日期格式与时间选择
日历列通过options对象透传 jSuites 日历插件的配置(详见 date-and-datetime-picker 示例),常用项包括:
options : { // 日期格式 format:'DD/MM/YYYY', // 允许键盘输入日期 readonly:0, // 默认今天 today:0, // 显示时间选择器 time:0, // 显示重置按钮 resetButton:true, // 占位文本 placeholder:'', // 月份与星期文案(可用于国际化) months:['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'], weekdays:['Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday'], weekdays_short:['S', 'M', 'T', 'W', 'T', 'F', 'S'], // 初始值 value:null, // 事件 onclose:null, onchange:null, // 全屏模式(屏幕宽度小于 800 时自动开启) fullscreen:false, };例如options: { format:'DD/MM/YYYY HH24:MI', time:1 }即可在日历列中加入时间选择。日期格式与解析同样有源码依据:createCell 中会先尝试用jSuites.calendar.extractDateFromString解析非标准格式的日期,再用jSuites.calendar.getDateString按列的options.format(默认YYYY-MM-DD)格式化显示;openEditor 中未显式给出format时也会默认补上YYYY-MM-DD。
checkbox / radio:布尔型交互
两者都会在单元格内创建对应类型的<input>元素(见 createCell),value == 1 || value == true视为勾选;点击即通过setValue写回数据。区别在于radio具有互斥语义:updateCell 在更新某行 radio 时会先把整列其他行置为false。另外,checkbox/radio 列在 openEditor 中的"编辑"行为就是直接切换值,无需弹出编辑器。
image:base64 图片展示
image 列只接受data:image开头的 data URL 作为有效值(见 createCell),编辑时使用jSuites.image组件完成上传/选择(见 openEditor),关闭编辑器后取回<img>的src作为单元格值(见 closeEditor)。
color:色块或着色文字
color 列的数据为十六进制颜色字符串。render:'square'时渲染为纯色方块;否则以该颜色直接着色单元格文字。更新逻辑见 updateCell,编辑交互由jSuites.color提供(见 openEditor)。
html:富文本内容
html 列允许单元格承载富文本,编辑时启用jSuites.editor富文本编辑器(见 openEditor),保存时通过editor.getData()取回 HTML(见 closeEditor)。渲染时 stripScript 会移除 HTML 中的<script>标签以防止脚本注入。
自定义列类型:基于外部插件创建 time 列
Jspreadsheet 的列类型体系是可扩展的,你可以基于任意第三方插件构建自定义列类型。官方示例以 clockpicker 时间选择插件为例,创建了一个 time 自定义列。
完整源码
<html> <script src="https://bossanova.uk/jspreadsheet/v4/jspreadsheet.js"></script> <script src="https://jsuites.net/v5/jsuites.js"></script> <link rel="stylesheet" href="https://bossanova.uk/jspreadsheet/v4/jspreadsheet.css" type="text/css" /> <link rel="stylesheet" href="https://jsuites.net/v5/jsuites.css" type="text/css" /> <link rel="stylesheet" type="text/css" href="http://weareoutman.github.io/clockpicker/dist/jquery-clockpicker.min.css" /> <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script> <script src="http://weareoutman.github.io/clockpicker/dist/jquery-clockpicker.min.js"></script> <div id="custom"></div> <script> var data2 = [ ['PHP', '14:00'], ['Javascript', '16:30'], ]; var customColumn = { // Methods closeEditor : function(cell, save) { var value = cell.children[0].value; cell.innerHTML = value; return value; }, openEditor : function(cell) { // Create input var element = document.createElement('input'); element.value = cell.innerHTML; // Update cell cell.classList.add('editor'); cell.innerHTML = ''; cell.appendChild(element); $(element).clockpicker({ afterHide:function() { setTimeout(function() { // To avoid double call if (cell.children[0]) { spreadsheet.closeEditor(cell, true); } }); } }); // Focus on the element element.focus(); }, getValue : function(cell) { return cell.innerHTML; }, setValue : function(cell, value) { cell.innerHTML = value; } } spreadsheet = jspreadsheet(document.getElementById('custom'), { data:data2, columns: [ { type: 'text', title:'Course Title', width:300 }, { type: 'text', title:'Time', width:100, editor:customColumn }, ] }); </script> </html>自定义列类型的接口契约
自定义列类型本质上是一个提供若干方法的对象,通过columns[].editor属性挂载到列上(示例中列仍声明为type:'text',但用editor:customColumn覆盖了编辑与渲染行为)。从源码可以确认其方法调用点:
| 方法 | 源码调用位置 | 职责 |
|---|---|---|
openEditor(cell, value, x, y, instance, options, e) | src/utils/editor.js | 进入编辑态:清空单元格、插入输入控件、聚焦 |
closeEditor(cell, save, x, y, instance, options) | src/utils/editor.js 与 L348-L350 | 结束编辑:save为true时返回新值并写回,否则恢复原值 |
getValue(cell) | 单元格取值场景 | 返回单元格当前显示值 |
setValue(cell, value) | src/utils/internal.js(updateCell分支) | 将值写入单元格 DOM |
此外,自定义类型对象还可以(非必须)提供两个渲染相关方法,源码在typeof ... .type === 'object'分支中按需调用:
createCell(td, value, x, y, instance, options):首次创建单元格时的自定义渲染(见 createCell)。updateCell(element, value, x, y, instance, options):更新单元格值时的自定义处理,若返回非undefined的值会覆盖新值(见 updateCell)。
需要注意的是:当列定义中type为对象时,其渲染走自定义分支(createCell 的typeof type === 'object'判断),因此示例中把自定义列声明为editor:customColumn而非type:customColumn,可以继续沿用 text 类型的默认渲染,仅替换编辑交互——这体现了editor与type两个挂载点的分工。
示例执行流程拆解
- 表格初始化时,
data2两行数据分别写入Course Title与Time列,Time列初始显示14:00、16:30。 - 用户双击
Time单元格,openEditor被调用:创建<input>、填入当前时间文本、加上editor样式类,随后初始化 clockpicker;afterHide回调中通过setTimeout延迟调用spreadsheet.closeEditor(cell, true)以"避免双重调用",即防止时间选择器关闭与失焦事件重复触发保存。 - 用户选好时间或按下 Enter/失焦后,
closeEditor被调用,cell.children[0].value取得输入框的新值,写回单元格文本并返回该值,Jspreadsheet 将其同步到数据层。
从渲染到编辑:列类型在源码中的完整生命周期
将以上内容串联起来,一个列类型的完整生命周期可以概括为三条关键路径,全部可在仓库源码中找到对应实现:
- 渲染路径:createCell 在表格初始化、插入列、更新值时被调用,根据列
type分派到各内置分支或自定义createCell。 - 编辑路径:openEditor 在用户激活单元格时按类型创建对应编辑器(input / textarea / jSuites.dropdown / jSuites.calendar / jSuites.color / jSuites.editor / jSuites.image / 自定义
openEditor),随后 closeEditor 按类型取回值并交由setValue写回。 - 数据路径:单元格 DOM 与
options.data双向同步——checkbox通过element.checked、dropdown通过getDropDownValue的键值映射、numeric通过掩码解析后的纯数字,保证"显示形态"与"底层数据"解耦。
理解了这三条路径,你就掌握了扩展新列类型的全部挂钩点:任何插件(时钟、评分、滑块、地图等)都可以通过实现openEditor/closeEditor/getValue/setValue(按需加上createCell/updateCell)无缝接入 Jspreadsheet 的列类型体系。
延伸阅读
- Dropdown 与 Autocomplete 列进阶用法:多选、远程数据、条件联动、分组图片选项
- Calendar 日期与时间选择列:日期格式、时间选择与国际化配置
- 列定义与列操作源码:列宽、列隐藏、列插入/删除/移动
- 单元格渲染与取值源码:
createCell、updateCell、掩码解析 - 编辑器分发源码:
openEditor/closeEditor各类型分支
- 前端
- UI组件
【免费下载链接】ce
Jspreadsheet is a lightweight JavaScript data grid component for creating interactive data grids with advanced spreadsheet controls.
相关推荐
Jspreadsheet(jExcel)v2 列类型实战指南:内置列类型、日历与下拉配置、自定义编辑器扩展
Jspreadsheet(jExcel)v2 列类型实战指南:内置列类型、日历与下拉配置、自定义编辑器扩展 jExcel(Jspreadsheet v2)是轻量
前端UI组件Lightweight Charts 系列类型(Series Types)完整指南:内置图表类型、配置项与自定义系列扩展
Lightweight Charts 系列类型(Series Types)完整指南:内置图表类型、配置项与自定义系列扩展 本文是 Lightweight Cha
前端图表库金融科技数据可视化Doctrine DBAL 数据类型(Types)完全指南:从内置类型到自定义映射类型
Doctrine DBAL 数据类型(Types)完全指南:从内置类型到自定义映射类型 导读 本文围绕 Doctrine Database Abstractio
数据库后端
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考