xiaodao-spreader 0.1.28 → 0.1.30
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.ZH.md +168 -58
- package/README.md +168 -58
- package/dist/style.css +1 -1
- package/dist/types/components/spreader/components/filter-popup.vue.d.ts +30 -0
- package/dist/types/components/spreader/components/toolbar.vue.d.ts +6 -0
- package/dist/types/components/spreader/composables/core-state.d.ts +44 -1
- package/dist/types/components/spreader/composables/interactions.d.ts +8 -0
- package/dist/types/components/spreader/core/autofill.d.ts +125 -0
- package/dist/types/components/spreader/core/constants.d.ts +2 -0
- package/dist/types/components/spreader/core/filter-core.d.ts +29 -0
- package/dist/types/components/spreader/core/number-format.d.ts +6 -0
- package/dist/types/components/spreader/core/types.d.ts +32 -0
- package/dist/xiaodao-spreader.es.js +6902 -5450
- package/dist/xiaodao-spreader.umd.js +9 -9
- package/package.json +1 -1
package/README.ZH.md
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
[](https://www.typescriptlang.org/)
|
|
9
9
|
[](https://vitejs.dev/)
|
|
10
10
|
|
|
11
|
-
基于 Canvas 的高性能 Vue 3 电子表格组件,在网页中提供类 Excel
|
|
11
|
+
基于 Canvas 的高性能 Vue 3 电子表格组件,在网页中提供类 Excel 的编辑体验。支持完整的单元格编辑、公式计算(相对/绝对/混合引用)、剪切复制粘贴、合并单元格、冻结窗格、数字格式、边框、查找替换、排序与自动填充,全部在单一虚拟化 Canvas 上渲染,可流畅滚动数十万行。纯逻辑核心(公式引擎、排序、查找替换、自动填充)与 Vue/Canvas 完全解耦并具备完整单元测试,便于跨项目复用。
|
|
12
12
|
|
|
13
13
|

|
|
14
14
|
|
|
@@ -18,39 +18,41 @@
|
|
|
18
18
|
|
|
19
19
|
### 核心电子表格
|
|
20
20
|
|
|
21
|
-
-
|
|
22
|
-
- **Canvas 2D
|
|
23
|
-
- **多 Sheet
|
|
24
|
-
-
|
|
25
|
-
-
|
|
26
|
-
-
|
|
27
|
-
-
|
|
28
|
-
-
|
|
29
|
-
- **撤销 /
|
|
30
|
-
-
|
|
31
|
-
-
|
|
32
|
-
-
|
|
33
|
-
-
|
|
34
|
-
-
|
|
21
|
+
- **动态表格扩展**: Excel 风格动态行列扩展;默认 26 列(A-Z)× 200 行,当滚动接近边界、在边缘输入数据、粘贴超出当前范围、或插入行列会将数据挤出边界时,自动扩展行列数
|
|
22
|
+
- **Canvas 2D 渲染**: 高 DPI 自适应(DPR 缩放),虚拟视口渲染,支持动态大小的工作表
|
|
23
|
+
- **多 Sheet 工作簿**: 标签栏支持新建、重命名、复制、删除、拖拽排序
|
|
24
|
+
- **公式引擎**: 支持 `=SUM()`、`=AVERAGE()`、`=COUNT()`、`=IF()`、`=VLOOKUP()`、`=CONCATENATE()`,支持依赖追踪与循环引用检测;工具栏与右键菜单提供一键求和/平均值/计数
|
|
25
|
+
- **合并单元格**: 合并居中、跨列合并、取消合并;合并区域边框按锚点存储、公共边渲染时统一解析
|
|
26
|
+
- **冻结窗格**: 固定顶部行/左侧列,使其在主体滚动时保持可见。工具栏「冻结窗格」下拉提供「冻结窗格」(以当前选区/活动单元格左上角为冻结点,等同 Excel 的 Freeze Panes)、「冻结首行」、「冻结首列」以及「取消冻结」(仅在已冻结时显示,替换「冻结窗格」项)。冻结状态为按工作表的视图状态(`freeze: { rows, cols }`),通过 v-model 持久化;跨冻结线的合并单元格也能正确处理,仅冻结部分固定,非冻结部分随滚动移出
|
|
27
|
+
- **丰富单元格格式**: 字体、字号(5–72)、加粗、斜体、下划线、删除线、文字颜色、填充颜色、水平/垂直对齐、自动换行
|
|
28
|
+
- **边框**: 上/下/左/右/外边框/全部/无,5 种预设样式及自定义颜色;独立边框池存储、公共边渲染时统一解析
|
|
29
|
+
- **撤销 / 重做**: 单元格、列宽、行高的完整状态快照(50 步)
|
|
30
|
+
- **格式刷**: 复制并应用单元格格式到任意区域
|
|
31
|
+
- **数字格式**: Excel 风格数字格式(常规 / 文本 / 数值 / 货币 / 会计 / 百分比 / 科学计数 / 日期 / 时间 / 日期时间 / 持续时间),提供自定义格式对话框;仅影响显示,绝不修改底层单元格值
|
|
32
|
+
- **智能数据识别**: 输入 `100%`、`1,234`、`¥1,234.56` 等带符号数字文本时自动识别为数值并套用对应格式;常见日期时间文本自动识别为日期,与 Excel 输入语义一致
|
|
33
|
+
- **排序与排序提醒**: 工具栏与右键菜单按单元格**展示内容**对所有类型(数值 / 日期 / 文本)排序;排序只移动数据、不搬运样式;含合并单元格或公式的区域自动禁用排序;当选区外存在相邻数据时,弹出类 Excel 的「排序提醒」对话框,可选择「扩展选定区域」或「仅对选定区域排序」
|
|
34
|
+
- **自动筛选(AutoFilter)**: 类 Excel 的普通区域自动筛选。工具栏「数据 → 筛选」或 `Ctrl+Shift+L` 启用;选择一个数据单元格(或单行多列选区)后启用,即从该表头行向下智能探测连续数据区;各列表头显示筛选下箭头,点击箭头打开筛选面板(值 / 文本 / 数值 / 日期 / 搜索 / 空值 / 多列 AND)。清除某列条件只清该列、移除 AutoFilter 清全部;仅在 Filter Range 内的列拥有箭头;单选已合并单元格且无筛选态时禁用筛选按钮,*见 [自动筛选(AutoFilter)](#自动筛选autofilter)*
|
|
35
|
+
- **查找与替换**: 工具栏查找按钮或 `Ctrl/Cmd+F`(含 `Ctrl/Cmd+H`)打开;支持「当前工作表 / 整个工作簿 / 当前选区」三种范围,区分大小写、匹配整个单元格;高亮全部匹配并定位当前项、循环查找;单次与全部替换均接入撤销/重做,仅修改单元格原始 `value`(始终保持字符串),不改动格式 / 边框 / 合并
|
|
36
|
+
- **自动填充(填充柄)**: 类 Excel 的活动选区右下角填充柄,按住向上/下/左/右拖拽即可填充单元格:单值复制、数字/日期/文本数字自动续序列(如 `1,2 → 3,4,5`)、公式引用按相对/绝对/混合规则平移(如 `=A1*2 → =A2*2`)、源 `styleId` 经样式池复用。拖拽期间实时预览、边缘自动滚动、动态扩展工作表、冻结窗格兼容、单次拖拽仅产生一个撤销步骤,*见 [自动填充](#自动填充)*
|
|
35
37
|
|
|
36
38
|
### 交互体验
|
|
37
39
|
|
|
38
|
-
-
|
|
39
|
-
-
|
|
40
|
-
-
|
|
41
|
-
-
|
|
42
|
-
-
|
|
43
|
-
-
|
|
44
|
-
-
|
|
45
|
-
-
|
|
46
|
-
-
|
|
40
|
+
- **智能选区**: 点击、拖拽、Shift+点击、行/列标题选择、全选按钮
|
|
41
|
+
- **双击编辑**: 行内编辑器,使用 `<textarea>` 支持多行输入
|
|
42
|
+
- **编辑栏**: 专用编辑栏,带单元格地址标签及实时公式显示
|
|
43
|
+
- **完整键盘导航**: 方向键、Tab、Enter、Home、End、Ctrl+Home、Ctrl+End
|
|
44
|
+
- **上下文菜单**: 智能识别当前区域(单元格、行、列、Sheet 标签),支持多级子菜单
|
|
45
|
+
- **行/列操作**: 右键菜单插入、删除、剪切、复制、粘贴
|
|
46
|
+
- **列宽/行高**: 拖拽调整,实时预览,双击自动适配
|
|
47
|
+
- **触摸支持**: 滑动滚动,双击进入编辑模式
|
|
48
|
+
- **响应式**: ResizeObserver 监听容器尺寸变化
|
|
47
49
|
|
|
48
50
|
### 视觉体验
|
|
49
51
|
|
|
50
|
-
-
|
|
51
|
-
-
|
|
52
|
-
-
|
|
53
|
-
-
|
|
52
|
+
- **明/暗双主题**: 完整的调色板,50+ CSS 自定义属性
|
|
53
|
+
- **国际化**: 内置中文(zh-CN)与英文(en-US)
|
|
54
|
+
- **溢出工具栏**: 响应式工具栏,自动将溢出按钮折叠到下拉菜单
|
|
55
|
+
- **自定义滚动条**: 仿原生滚动条,带箭头按钮及可拖拽滑块
|
|
54
56
|
|
|
55
57
|
---
|
|
56
58
|
|
|
@@ -134,10 +136,10 @@ const myData = ref<SheetModelData[]>([
|
|
|
134
136
|
| `data` (v-model) | `SheetModelData[]` | `[]` | 多 Sheet 数据(双向绑定) |
|
|
135
137
|
| `rowCount` | `number` | `200` | 每个 Sheet 的初始行数(可动态扩展) |
|
|
136
138
|
| `colCount` | `number` | `26` | 每个 Sheet 的初始列数(可动态扩展) |
|
|
137
|
-
| `width` | `number \| string` |
|
|
138
|
-
| `height` | `number \| string` |
|
|
139
|
+
| `width` | `number \| string` | - | 组件宽度(像素;传 `string` 或省略则自适应) |
|
|
140
|
+
| `height` | `number \| string` | - | 组件高度(像素;传 `string` 或省略则自适应) |
|
|
139
141
|
| `theme` | `'light' \| 'dark'` | `'light'` | 主题模式 |
|
|
140
|
-
| `locale` | `string` | `'zh-CN'` |
|
|
142
|
+
| `locale` | `string` | `'zh-CN'` | 语言: `'zh-CN'` \| `'en-US'` |
|
|
141
143
|
|
|
142
144
|
---
|
|
143
145
|
|
|
@@ -167,12 +169,12 @@ interface SheetModelData {
|
|
|
167
169
|
}
|
|
168
170
|
```
|
|
169
171
|
|
|
170
|
-
- **`styles
|
|
171
|
-
- **`borders
|
|
172
|
+
- **`styles`**:样式池,`styles[0]` 始终为默认空样式 `{}`。单元格通过下标(`styleId`)引用样式。
|
|
173
|
+
- **`borders`**:边框池,`borders[0]` 始终为默认空边框 `{}`。样式通过下标(`borderId`)引用边框;省略时由旧版内联边框属性自动迁移。
|
|
172
174
|
- **`cells`**:键为 `"列,行"` 格式(如 `"0,0"` 代表 A1 单元格)。`styleId` 引用 `styles` 数组;`styleId=0` 或省略表示默认样式。
|
|
173
175
|
- **`merges`**:合并单元格定义,以合并锚点单元格为键。
|
|
174
|
-
- **`freeze
|
|
175
|
-
- **`colWidths` / `rowHeights
|
|
176
|
+
- **`freeze`**:冻结窗格的视图状态,`{ rows, cols }` 冻结顶部 `rows` 行与左侧 `cols` 列;`{ rows: 0, cols: 0 }` 表示无冻结。按工作表持久化,切换工作表时恢复。
|
|
177
|
+
- **`colWidths` / `rowHeights`**:稀疏映射,仅存储非默认值。
|
|
176
178
|
|
|
177
179
|
### 类型导出
|
|
178
180
|
|
|
@@ -206,21 +208,26 @@ import { StylePool, resolveStyle, migrateCells, cloneCells } from 'xiaodao-sprea
|
|
|
206
208
|
|
|
207
209
|
```
|
|
208
210
|
src/
|
|
209
|
-
├── index.ts #
|
|
211
|
+
├── index.ts # 库入口: 从 spreader/ 统一 re-export
|
|
210
212
|
├── App.vue # 演示应用
|
|
211
213
|
└── components/
|
|
212
214
|
└── spreader/
|
|
213
|
-
├── index.ts #
|
|
215
|
+
├── index.ts # 统一导出口: 组件 + 类型(barrel)
|
|
214
216
|
├── components/
|
|
215
|
-
│ ├── spreader.vue #
|
|
217
|
+
│ ├── spreader.vue # 入口组件: 模板 + 样式 + 组合
|
|
216
218
|
│ ├── toolbar.vue # 工具栏(含溢出下拉)
|
|
217
219
|
│ ├── tabbar.vue # Sheet 标签栏
|
|
218
220
|
│ ├── dropdown.vue # 通用下拉组件
|
|
221
|
+
│ ├── find-replace-bar.vue # 查找替换栏 UI
|
|
219
222
|
│ └── pickers/
|
|
220
|
-
│ ├── colorPicker.vue
|
|
221
|
-
│ ├── borderPicker.vue
|
|
222
|
-
│ ├── mergePicker.vue
|
|
223
|
-
│
|
|
223
|
+
│ ├── colorPicker.vue # 文字 / 填充颜色选择器
|
|
224
|
+
│ ├── borderPicker.vue # 边框选择器
|
|
225
|
+
│ ├── mergePicker.vue # 合并单元格选择器
|
|
226
|
+
│ ├── numberFormatDialog.vue # 数字格式自定义对话框
|
|
227
|
+
│ ├── sortPicker.vue # 排序下拉
|
|
228
|
+
│ ├── sortConfirmDialog.vue # Excel 风格排序提醒对话框
|
|
229
|
+
│ ├── calcPicker.vue # 求和 / 平均值 / 计数选择器
|
|
230
|
+
│ └── insertFunctionDialog.vue # 插入函数对话框
|
|
224
231
|
├── composables/
|
|
225
232
|
│ ├── core-state.ts # Props、cells/merges/selection、字体度量、导航
|
|
226
233
|
│ ├── undo-styles.ts # 撤销重做、格式刷、字体/对齐/颜色
|
|
@@ -236,6 +243,8 @@ src/
|
|
|
236
243
|
├── border-resolve.ts # 公共边冲突解析(resolveSharedBorder)
|
|
237
244
|
├── formula.ts # 公式引擎(解析、计算、依赖、缓存)
|
|
238
245
|
├── find-replace-core.ts # 查找替换纯算法(零 Vue 依赖,可单测)
|
|
246
|
+
├── sort-core.ts # 排序纯算法(零 Vue 依赖,可单测)
|
|
247
|
+
├── autofill.ts # 自动填充纯引擎(模式推断、填充柄逻辑,零 Vue 依赖)
|
|
239
248
|
├── number-format.ts # 数字格式引擎(Excel 风格显示格式化)
|
|
240
249
|
├── theme.ts # 主题 CSS 变量构建
|
|
241
250
|
└── utils.ts # 纯工具函数(列标签、命中测试、尺寸解析)
|
|
@@ -287,6 +296,7 @@ src/
|
|
|
287
296
|
| `Ctrl+C` / `Ctrl+X` / `Ctrl+V` | 复制 / 剪切 / 粘贴 |
|
|
288
297
|
| `Ctrl+Z` / `Ctrl+Y` | 撤销 / 重做 |
|
|
289
298
|
| `Ctrl+A` | 全选 |
|
|
299
|
+
| `Ctrl+Shift+L` | 切换自动筛选(AutoFilter) |
|
|
290
300
|
|
|
291
301
|
### 格式
|
|
292
302
|
|
|
@@ -317,8 +327,8 @@ src/
|
|
|
317
327
|
|
|
318
328
|
`FormulaDeps` 类维护双向依赖图:
|
|
319
329
|
|
|
320
|
-
- **正向**:`formulaKey` → `[depKey, ...]
|
|
321
|
-
- **反向**:`depKey` → `Set<formulaKey
|
|
330
|
+
- **正向**:`formulaKey` → `[depKey, ...]`: 公式引用了哪些单元格
|
|
331
|
+
- **反向**:`depKey` → `Set<formulaKey>`: 哪些公式依赖此单元格
|
|
322
332
|
|
|
323
333
|
单元格变更时,脏标记通过反向图传播。循环引用通过独立的 `inProgress` 集合检测,返回 `#ERROR`。
|
|
324
334
|
|
|
@@ -330,7 +340,7 @@ src/
|
|
|
330
340
|
|
|
331
341
|
## 数字格式
|
|
332
342
|
|
|
333
|
-
一套 Excel 风格的数字格式引擎(`spreader/core/number-format.ts
|
|
343
|
+
一套 Excel 风格的数字格式引擎(`spreader/core/number-format.ts`),控制**单元格值的显示方式**,绝不修改存储的 `value`(始终保持原始字符串)。
|
|
334
344
|
|
|
335
345
|
### 分类
|
|
336
346
|
|
|
@@ -349,24 +359,123 @@ src/
|
|
|
349
359
|
| 时间 Time | `13:45:30` | `h:mm:ss` |
|
|
350
360
|
| 日期时间 Date & Time | `2026年8月24日 13:45:30` | `yyyy"年"m"月"d"日" h:mm:ss` |
|
|
351
361
|
| 持续时间 Duration | `26:30:00` | `[h]:mm:ss` |
|
|
352
|
-
| 自定义 Custom | 用户自定义 Excel 风格代码 |
|
|
362
|
+
| 自定义 Custom | 用户自定义 Excel 风格代码 | - |
|
|
353
363
|
|
|
354
364
|
### 工作原理
|
|
355
365
|
|
|
356
366
|
- **存储**:格式代码按单元格存入解析后样式的 `numberFormat` 属性(字符串)。省略该属性(或空串)即常规格式。
|
|
357
367
|
- **界面**:工具栏数字格式下拉框将预设应用到当前选区;**「格式…」** 项打开 `numberFormatDialog.vue`,可自定义格式代码、小数位数与千位分隔符。
|
|
358
368
|
- **显示**:`formatNumber(value, format, locale)` 解析代码(带缓存),应用千位分隔 / 小数位 / 百分比缩放 / 日期序列号转换,返回显示字符串。非法的日期/持续时间序列号渲染为 `###`。
|
|
359
|
-
-
|
|
369
|
+
- **对齐**:数值类格式默认右对齐;文本及常规下的非数值保持左对齐,与 Excel 语义一致。
|
|
360
370
|
- **国际化**:货币符号(`¥` / `$`)、月份与星期名称随 `locale` 属性变化。
|
|
361
371
|
|
|
362
372
|
---
|
|
363
373
|
|
|
374
|
+
## 自动填充
|
|
375
|
+
|
|
376
|
+
一套类 Excel 的填充柄机制(`spreader/core/autofill.ts` 纯引擎 + `composables/interactions.ts` 画布/交互层)。拖动活动选区右下角的小方块即可填充单元格,无 DOM 句柄,全部在 Canvas 上绘制。
|
|
377
|
+
|
|
378
|
+
### 填充模式
|
|
379
|
+
|
|
380
|
+
| 源值 | 填充行为 | 示例 |
|
|
381
|
+
|------|----------|------|
|
|
382
|
+
| 单个数字 | 复制 | `42 → 42, 42, 42` |
|
|
383
|
+
| 单个文本 | 复制 | `foo → foo, foo, foo` |
|
|
384
|
+
| 单个日期 | +1 天 | `2026-01-01 → 2026-01-02, 2026-01-03` |
|
|
385
|
+
| 两个及以上数字,等差 | 线性序列 | `1,2 → 3,4,5` · `2,4 → 6,8,10` |
|
|
386
|
+
| 两个及以上日期,等差 | 日期序列 | `2026-01-01, 2026-01-03 → 2026-01-05, 2026-01-07` |
|
|
387
|
+
| 文本 + 数字,prefix 相同 | 文本数字序列 | `Item1,Item2 → Item3,Item4` |
|
|
388
|
+
| 两个单字母 | 字母序列 | `A,B → C,D,E` |
|
|
389
|
+
| 公式 | 引用平移 | `=A1*2 → =A2*2, =A3*2` |
|
|
390
|
+
| 多列 / 多行整块 | 按列独立推断模式 | `A1:B2=[[1,10],[2,20]] → [[3,30],[4,40]]` |
|
|
391
|
+
|
|
392
|
+
### 公式引用规则
|
|
393
|
+
|
|
394
|
+
填充柄平移复用既有 `shiftFormulaRefs()`,未新建第二套公式引擎:
|
|
395
|
+
|
|
396
|
+
| 引用类型 | 语法 | 填充行为 |
|
|
397
|
+
|----------|------|----------|
|
|
398
|
+
| 相对引用 | `=A1` | 行列随目标单元格偏移 |
|
|
399
|
+
| 绝对引用 | `=$A$1` | 保持不变 |
|
|
400
|
+
| 混合引用(列绝对) | `=$A1` | 行调整,列锁定 |
|
|
401
|
+
| 混合引用(行绝对) | `=A$1` | 列调整,行锁定 |
|
|
402
|
+
| 复合引用 | `=B1*$F$1` | `B1` 调整,`$F$1` 锁定 |
|
|
403
|
+
|
|
404
|
+
### 交互
|
|
405
|
+
|
|
406
|
+
- **填充柄**:活动选区右下角 6px 方块,主题主色;当选区与合并单元格部分相交时变灰(禁用填充)。
|
|
407
|
+
- **命中测试**:独立 `isFillHandleHit()` 在 resize 句柄之后、单元格点击之前判断;悬停显示 `crosshair` 光标。
|
|
408
|
+
- **状态机**:独立 `autofilling` 状态阻止选区拖拽 / 编辑器 / resize 启动;ESC 中途取消。
|
|
409
|
+
- **实时预览**:拖拽期间目标区域以半透明虚线矩形显示;源选区保持不变;`mouseup` 前不修改任何单元格数据。
|
|
410
|
+
- **边缘自动滚动**:拖到距视口边缘 30px 内时启动单一 `requestAnimationFrame` 循环滚动并更新目标区域;`mouseup` / ESC / pointercancel 即停止。
|
|
411
|
+
- **动态扩展**:填充超出当前 `rowCount`/`colCount` 时先触发 `ensureCapacity()`,折叠进同一撤销步骤。
|
|
412
|
+
- **填充后选区**:选区更新为源 + 目标的并集。
|
|
413
|
+
- **冻结窗格**:所有坐标统一走 `cellToScreenRect` / `screenToCell`,填充柄、命中测试、预览、最终填充在冻结与主体区域均正确。
|
|
414
|
+
- **合并兼容**:部分相交的合并禁用填充柄(第一版保守策略);整块合并可正确填充。
|
|
415
|
+
- **触摸**:与鼠标共用同一 `autoFillState` 与 `applyAutoFill` 路径,无独立实现。
|
|
416
|
+
|
|
417
|
+
### 架构
|
|
418
|
+
|
|
419
|
+
```
|
|
420
|
+
填充柄 UI (drawFillHandle)
|
|
421
|
+
↓
|
|
422
|
+
统一命中测试 (isFillHandleHit)
|
|
423
|
+
↓
|
|
424
|
+
AutoFill 拖拽状态 (autoFillState)
|
|
425
|
+
↓
|
|
426
|
+
目标区域计算 (computeTargetRange)
|
|
427
|
+
↓
|
|
428
|
+
纯 AutoFill 模式引擎 (core/autofill.ts)
|
|
429
|
+
↓
|
|
430
|
+
公式平移 (shiftFormulaRefs)
|
|
431
|
+
↓
|
|
432
|
+
样式 / 边框 / 单元格写入 (applyAutoFill)
|
|
433
|
+
↓
|
|
434
|
+
撤销快照 (saveUndo,每次拖拽仅一步)
|
|
435
|
+
↓
|
|
436
|
+
scheduleRender()
|
|
437
|
+
```
|
|
438
|
+
|
|
439
|
+
纯引擎(`core/autofill.ts`)零 Vue/Canvas 依赖,`test/autofill.test.ts` 中有 54 个用例完整单测覆盖,便于复用到 `Ctrl+D`/`Ctrl+R`、粘贴填充、右键填充、API 自动填充等场景。
|
|
440
|
+
|
|
441
|
+
---
|
|
442
|
+
|
|
443
|
+
## 自动筛选(AutoFilter)
|
|
444
|
+
|
|
445
|
+
一套类 Excel 的普通区域自动筛选:筛选是「作用于数据区域 Range 的 Sheet 功能」,而非「每个列头自带的筛选功能」。表头箭头在 Canvas 上绘制(无 DOM),筛选面板用 Vue DOM。
|
|
446
|
+
|
|
447
|
+
### 启用与切换
|
|
448
|
+
|
|
449
|
+
- 工具栏「数据 → 筛选」或 `Ctrl+Shift+L` 调用 `toggleAutoFilter()`。
|
|
450
|
+
- **未启用 → 创建**:选中数据单元格或单行多列选区后启用,即从该表头行**向下**智能探测连续数据区;完全空白表不创建无效筛选。
|
|
451
|
+
- **已启用 → 整体移除**:恢复隐藏行、清除全部列条件、移除表头箭头。工具栏按钮高亮态与点击行为严格一致。
|
|
452
|
+
- 单选已合并单元格(跨多格合并区域)且无筛选态时,筛选按钮禁用(合并单元格无法作为合法数据区域表头)。
|
|
453
|
+
|
|
454
|
+
### 表头箭头
|
|
455
|
+
|
|
456
|
+
- 仅 Filter Range 的表头行、且列落在范围内才显示;未启用 / 范围外不显示。
|
|
457
|
+
- 样式为「右边框带背景的下箭头按钮」:未筛选浅灰底 + 深灰箭头,已筛选蓝底 + 白箭头(区分「已启用」与「该列已筛选」)。
|
|
458
|
+
- 点击箭头只打开筛选面板,不触发普通选区;冻结窗格下箭头在冻结表头正确显示。
|
|
459
|
+
|
|
460
|
+
### 筛选面板
|
|
461
|
+
|
|
462
|
+
复用既有引擎:标题显示该列表头内容(非列字母);取消对勾仅在**点「确定」**时生效,即时不影响表格。支持值 / 文本 / 数值 / 日期筛选、搜索、空值、多列 AND;候选值来自 Filter Range 内对应列,其它列已筛选时基于过滤后行生成(Excel 级联行为)。
|
|
463
|
+
|
|
464
|
+
### 兼容性
|
|
465
|
+
|
|
466
|
+
- 隐藏行机制沿用既有 filteredOutRows + 可见行映射,**不删除、不复制**原始行。
|
|
467
|
+
- 行/列增删经 `adjustFilterRows` / `adjustFilterCols` 同步调整范围;删除整片筛选区域自动取消。
|
|
468
|
+
- 排序后重新计算filtered rows,原行索引不丢失。
|
|
469
|
+
- 经 v-model 序列化持久化,完整保留范围、箭头、条件与隐藏行。
|
|
470
|
+
|
|
471
|
+
---
|
|
472
|
+
|
|
364
473
|
## 边框系统
|
|
365
474
|
|
|
366
475
|
一套独立的边框存储与渲染机制(`spreader/core/border-pool.ts` + `border-resolve.ts`)。
|
|
367
476
|
|
|
368
477
|
- **独立边框池**:每个 Sheet 维护 `borders: BorderStyle[]` 池(`borders[0]` 恒为空边框 `{}`),样式通过 `borderId`(数组下标)引用边框,相同边框自动去重。
|
|
369
|
-
- **公共边统一解析**:相邻单元格的公共边在渲染时经 `resolveSharedBorder()`
|
|
478
|
+
- **公共边统一解析**:相邻单元格的公共边在渲染时经 `resolveSharedBorder()` 解析,宽者优先、同宽取先侧;设置边框**不再**同步修改相邻单元格。
|
|
370
479
|
- **合并单元格**:合并区域边框统一存储在锚点(左上角),内部边屏蔽,外边界按行/列分段与相邻区域解析,四角补齐角方块。
|
|
371
480
|
- **旧数据兼容**:旧版内联边框属性(`borderTopWidth` 等,已废弃)在加载时经 `migrateBordersInStyles()` 自动迁移。
|
|
372
481
|
|
|
@@ -463,18 +572,19 @@ pnpm build:demo
|
|
|
463
572
|
### 近期
|
|
464
573
|
|
|
465
574
|
- [x] 更多公式:`COUNT`、`IF`、`VLOOKUP`、`CONCATENATE`
|
|
466
|
-
- [
|
|
467
|
-
- [x]
|
|
575
|
+
- [x] 单元格背景颜色选择器
|
|
576
|
+
- [x] 数字格式(货币、百分比、日期、小数位数), *见 [数字格式](#数字格式)*
|
|
468
577
|
- [ ] 条件格式规则
|
|
469
|
-
- [ ]
|
|
470
|
-
- [x]
|
|
578
|
+
- [x] 自动填充拖拽手柄:*见 [自动填充](#自动填充)*
|
|
579
|
+
- [x] 查找与替换:*见 [查找与替换](#查找与替换)*
|
|
471
580
|
|
|
472
581
|
### 中期
|
|
473
582
|
|
|
474
|
-
- [x]
|
|
583
|
+
- [x] 冻结窗格(冻结行/列), *见 [冻结窗格](#功能特性)*
|
|
475
584
|
- [ ] 数据验证(下拉列表、输入约束)
|
|
476
585
|
- [ ] 行列分组与折叠
|
|
477
|
-
- [x]
|
|
586
|
+
- [x] 排序与筛选:按展示内容排序,含类 Excel「排序提醒」对话框(扩展选定区域 / 仅对选定区域排序);见 [排序与排序提醒](#功能特性)
|
|
587
|
+
- [x] 自动筛选(AutoFilter):工具栏「筛选」/`Ctrl+Shift+L` 启用,表头下箭头、智能向下探测数据区、值/文本/数值/日期多类型筛选、清除单列与整体移除分离;见 [自动筛选(AutoFilter)](#自动筛选autofilter)
|
|
478
588
|
- [ ] 单元格批注
|
|
479
589
|
- [ ] 打印布局
|
|
480
590
|
|
|
@@ -495,13 +605,13 @@ pnpm build:demo
|
|
|
495
605
|
| 框架 | Vue 3(Composition API + `<script setup>`) | ^3.4 |
|
|
496
606
|
| 构建 | Vite | ^5.0 |
|
|
497
607
|
| 语言 | TypeScript(严格模式) | ~5.4 |
|
|
498
|
-
| 渲染 | Canvas 2D API |
|
|
608
|
+
| 渲染 | Canvas 2D API | - |
|
|
499
609
|
| 类型检查 | vue-tsc | ^2.2 |
|
|
500
|
-
| 包管理 | pnpm |
|
|
501
|
-
| CSS | Scoped CSS + CSS 自定义属性 |
|
|
610
|
+
| 包管理 | pnpm | - |
|
|
611
|
+
| CSS | Scoped CSS + CSS 自定义属性 | - |
|
|
502
612
|
|
|
503
613
|
---
|
|
504
614
|
|
|
505
615
|
## 开源协议
|
|
506
616
|
|
|
507
|
-
本项目基于 MIT
|
|
617
|
+
本项目基于 MIT 协议,详见 [LICENSE](LICENSE) 文件。
|