xiaodao-spreader 0.1.28 → 0.1.29
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 +73 -2
- package/README.md +73 -2
- package/dist/types/components/spreader/composables/core-state.d.ts +12 -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/number-format.d.ts +6 -0
- package/dist/xiaodao-spreader.es.js +5824 -5391
- package/dist/xiaodao-spreader.umd.js +9 -9
- package/package.json +1 -1
package/README.ZH.md
CHANGED
|
@@ -32,6 +32,7 @@
|
|
|
32
32
|
- **智能数据识别** — 输入 `100%`、`1,234`、`¥1,234.56` 等带符号数字文本时自动识别为数值并套用对应格式;常见日期时间文本自动识别为日期,与 Excel 输入语义一致
|
|
33
33
|
- **排序与排序提醒** — 工具栏与右键菜单按单元格**展示内容**对所有类型(数值 / 日期 / 文本)排序;排序只移动数据、不搬运样式;含合并单元格或公式的区域自动禁用排序;当选区外存在相邻数据时,弹出类 Excel 的「排序提醒」对话框,可选择「扩展选定区域」或「仅对选定区域排序」
|
|
34
34
|
- **查找与替换** — 工具栏查找按钮或 `Ctrl/Cmd+F`(含 `Ctrl/Cmd+H`)打开;支持「当前工作表 / 整个工作簿 / 当前选区」三种范围,区分大小写、匹配整个单元格;高亮全部匹配并定位当前项、循环查找;单次与全部替换均接入撤销/重做,仅修改单元格原始 `value`(始终保持字符串),不改动格式 / 边框 / 合并
|
|
35
|
+
- **自动填充(填充柄)** — 类 Excel 的活动选区右下角填充柄,按住向上/下/左/右拖拽即可填充单元格:单值复制、数字/日期/文本数字自动续序列(如 `1,2 → 3,4,5`)、公式引用按相对/绝对/混合规则平移(如 `=A1*2 → =A2*2`)、源 `styleId` 经样式池复用。拖拽期间实时预览、边缘自动滚动、动态扩展工作表、冻结窗格兼容、单次拖拽仅产生一个撤销步骤——*见 [自动填充](#自动填充)*
|
|
35
36
|
|
|
36
37
|
### 交互体验
|
|
37
38
|
|
|
@@ -236,6 +237,7 @@ src/
|
|
|
236
237
|
├── border-resolve.ts # 公共边冲突解析(resolveSharedBorder)
|
|
237
238
|
├── formula.ts # 公式引擎(解析、计算、依赖、缓存)
|
|
238
239
|
├── find-replace-core.ts # 查找替换纯算法(零 Vue 依赖,可单测)
|
|
240
|
+
├── autofill.ts # 自动填充纯引擎(模式推断、填充柄逻辑,零 Vue 依赖)
|
|
239
241
|
├── number-format.ts # 数字格式引擎(Excel 风格显示格式化)
|
|
240
242
|
├── theme.ts # 主题 CSS 变量构建
|
|
241
243
|
└── utils.ts # 纯工具函数(列标签、命中测试、尺寸解析)
|
|
@@ -361,6 +363,75 @@ src/
|
|
|
361
363
|
|
|
362
364
|
---
|
|
363
365
|
|
|
366
|
+
## 自动填充
|
|
367
|
+
|
|
368
|
+
一套类 Excel 的填充柄机制(`spreader/core/autofill.ts` 纯引擎 + `composables/interactions.ts` 画布/交互层)。拖动活动选区右下角的小方块即可填充单元格——无 DOM 句柄,全部在 Canvas 上绘制。
|
|
369
|
+
|
|
370
|
+
### 填充模式
|
|
371
|
+
|
|
372
|
+
| 源值 | 填充行为 | 示例 |
|
|
373
|
+
|------|----------|------|
|
|
374
|
+
| 单个数字 | 复制 | `42 → 42, 42, 42` |
|
|
375
|
+
| 单个文本 | 复制 | `foo → foo, foo, foo` |
|
|
376
|
+
| 单个日期 | +1 天 | `2026-01-01 → 2026-01-02, 2026-01-03` |
|
|
377
|
+
| 两个及以上数字,等差 | 线性序列 | `1,2 → 3,4,5` · `2,4 → 6,8,10` |
|
|
378
|
+
| 两个及以上日期,等差 | 日期序列 | `2026-01-01, 2026-01-03 → 2026-01-05, 2026-01-07` |
|
|
379
|
+
| 文本 + 数字,prefix 相同 | 文本数字序列 | `Item1,Item2 → Item3,Item4` |
|
|
380
|
+
| 两个单字母 | 字母序列 | `A,B → C,D,E` |
|
|
381
|
+
| 公式 | 引用平移 | `=A1*2 → =A2*2, =A3*2` |
|
|
382
|
+
| 多列 / 多行整块 | 按列独立推断模式 | `A1:B2=[[1,10],[2,20]] → [[3,30],[4,40]]` |
|
|
383
|
+
|
|
384
|
+
### 公式引用规则
|
|
385
|
+
|
|
386
|
+
填充柄平移复用既有 `shiftFormulaRefs()`——未新建第二套公式引擎:
|
|
387
|
+
|
|
388
|
+
| 引用类型 | 语法 | 填充行为 |
|
|
389
|
+
|----------|------|----------|
|
|
390
|
+
| 相对引用 | `=A1` | 行列随目标单元格偏移 |
|
|
391
|
+
| 绝对引用 | `=$A$1` | 保持不变 |
|
|
392
|
+
| 混合引用(列绝对) | `=$A1` | 行调整,列锁定 |
|
|
393
|
+
| 混合引用(行绝对) | `=A$1` | 列调整,行锁定 |
|
|
394
|
+
| 复合引用 | `=B1*$F$1` | `B1` 调整,`$F$1` 锁定 |
|
|
395
|
+
|
|
396
|
+
### 交互
|
|
397
|
+
|
|
398
|
+
- **填充柄**:活动选区右下角 6px 方块,主题主色;当选区与合并单元格部分相交时变灰(禁用填充)。
|
|
399
|
+
- **命中测试**:独立 `isFillHandleHit()` 在 resize 句柄之后、单元格点击之前判断;悬停显示 `crosshair` 光标。
|
|
400
|
+
- **状态机**:独立 `autofilling` 状态阻止选区拖拽 / 编辑器 / resize 启动;ESC 中途取消。
|
|
401
|
+
- **实时预览**:拖拽期间目标区域以半透明虚线矩形显示;源选区保持不变;`mouseup` 前不修改任何单元格数据。
|
|
402
|
+
- **边缘自动滚动**:拖到距视口边缘 30px 内时启动单一 `requestAnimationFrame` 循环滚动并更新目标区域;`mouseup` / ESC / pointercancel 即停止。
|
|
403
|
+
- **动态扩展**:填充超出当前 `rowCount`/`colCount` 时先触发 `ensureCapacity()`,折叠进同一撤销步骤。
|
|
404
|
+
- **填充后选区**:选区更新为源 + 目标的并集。
|
|
405
|
+
- **冻结窗格**:所有坐标统一走 `cellToScreenRect` / `screenToCell`,填充柄、命中测试、预览、最终填充在冻结与主体区域均正确。
|
|
406
|
+
- **合并兼容**:部分相交的合并禁用填充柄(第一版保守策略);整块合并可正确填充。
|
|
407
|
+
- **触摸**:与鼠标共用同一 `autoFillState` 与 `applyAutoFill` 路径——无独立实现。
|
|
408
|
+
|
|
409
|
+
### 架构
|
|
410
|
+
|
|
411
|
+
```
|
|
412
|
+
填充柄 UI (drawFillHandle)
|
|
413
|
+
↓
|
|
414
|
+
统一命中测试 (isFillHandleHit)
|
|
415
|
+
↓
|
|
416
|
+
AutoFill 拖拽状态 (autoFillState)
|
|
417
|
+
↓
|
|
418
|
+
目标区域计算 (computeTargetRange)
|
|
419
|
+
↓
|
|
420
|
+
纯 AutoFill 模式引擎 (core/autofill.ts)
|
|
421
|
+
↓
|
|
422
|
+
公式平移 (shiftFormulaRefs)
|
|
423
|
+
↓
|
|
424
|
+
样式 / 边框 / 单元格写入 (applyAutoFill)
|
|
425
|
+
↓
|
|
426
|
+
撤销快照 (saveUndo,每次拖拽仅一步)
|
|
427
|
+
↓
|
|
428
|
+
scheduleRender()
|
|
429
|
+
```
|
|
430
|
+
|
|
431
|
+
纯引擎(`core/autofill.ts`)零 Vue/Canvas 依赖,`test/autofill.test.ts` 中有 54 个用例完整单测覆盖,便于复用到 `Ctrl+D`/`Ctrl+R`、粘贴填充、右键填充、API 自动填充等场景。
|
|
432
|
+
|
|
433
|
+
---
|
|
434
|
+
|
|
364
435
|
## 边框系统
|
|
365
436
|
|
|
366
437
|
一套独立的边框存储与渲染机制(`spreader/core/border-pool.ts` + `border-resolve.ts`)。
|
|
@@ -463,10 +534,10 @@ pnpm build:demo
|
|
|
463
534
|
### 近期
|
|
464
535
|
|
|
465
536
|
- [x] 更多公式:`COUNT`、`IF`、`VLOOKUP`、`CONCATENATE`
|
|
466
|
-
- [
|
|
537
|
+
- [x] 单元格背景颜色选择器
|
|
467
538
|
- [x] 数字格式(货币、百分比、日期、小数位数)—— *见 [数字格式](#数字格式)*
|
|
468
539
|
- [ ] 条件格式规则
|
|
469
|
-
- [
|
|
540
|
+
- [x] 自动填充拖拽手柄 —— *见 [自动填充](#自动填充)*
|
|
470
541
|
- [x] 查找与替换 —— *见 [查找与替换](#查找与替换)*
|
|
471
542
|
|
|
472
543
|
### 中期
|
package/README.md
CHANGED
|
@@ -31,6 +31,7 @@ A high-performance, canvas-based spreadsheet component for Vue 3 — bringing an
|
|
|
31
31
|
- **Smart Data Recognition** — Typing `100%`, `1,234`, `¥1,234.56` auto-converts the text to a number and applies the matching format; common date/time text auto-converts to dates — matching Excel input behavior
|
|
32
32
|
- **Sorting & Sort Warning** — Sort any column by its **displayed content** (numbers / dates / text); sorting moves data only, never cell styles; ranges containing merged cells or formulas are auto-disabled; when adjacent data sits outside the selection, an Excel-style **Sort Warning** dialog lets you choose "Expand the selection" or "Sort the current selection only"
|
|
33
33
|
- **Find & Replace** — Open via the toolbar find button or `Ctrl/Cmd+F` (also `Ctrl/Cmd+H`); three scopes — current sheet / entire workbook / current selection; match case and match entire cell; highlights all matches and locates the active one with wrap-around navigation; single and replace-all both integrate with undo/redo, mutating only the raw `value` (always kept a string), never format / border / merge
|
|
34
|
+
- **Auto Fill (Fill Handle)** — Excel-style fill handle at the bottom-right corner of the active selection. Drag it up/down/left/right to fill cells: single values copy, number/date/text-number sequences auto-continue (e.g. `1,2 → 3,4,5`), formula references adjust per relative/absolute/mixed rules (e.g. `=A1*2` → `=A2*2`), and source `styleId` is reused via the style pool. Live preview during drag, edge auto-scroll, dynamic sheet expansion, freeze-pane compatibility, and a single undo step per operation — *see [Auto Fill](#auto-fill)*
|
|
34
35
|
|
|
35
36
|
### Interaction
|
|
36
37
|
- **Smart Selection** — Click, drag, Shift+Click, row/column header select, corner-cell select-all
|
|
@@ -233,6 +234,7 @@ src/
|
|
|
233
234
|
├── border-resolve.ts # Shared-border conflict resolution (resolveSharedBorder)
|
|
234
235
|
├── formula.ts # Formula engine (parse, evaluate, deps, cache)
|
|
235
236
|
├── find-replace-core.ts # Find/replace pure algorithms (zero Vue deps, unit-testable)
|
|
237
|
+
├── autofill.ts # Auto-fill pure engine (pattern inference, fill handle logic, zero Vue deps)
|
|
236
238
|
├── number-format.ts # Number format engine (Excel-style display formatting)
|
|
237
239
|
├── theme.ts # Theme CSS variable construction
|
|
238
240
|
└── utils.ts # Pure utilities (col label, hit test, resolve size)
|
|
@@ -358,6 +360,75 @@ An Excel-style number formatting engine (`spreader/core/number-format.ts`) that
|
|
|
358
360
|
|
|
359
361
|
---
|
|
360
362
|
|
|
363
|
+
## Auto Fill
|
|
364
|
+
|
|
365
|
+
An Excel-style fill-handle mechanism (`spreader/core/autofill.ts` pure engine + `composables/interactions.ts` canvas/interaction layer). Drag the small square at the bottom-right corner of the active selection to fill cells — no DOM handles, all drawn on Canvas.
|
|
366
|
+
|
|
367
|
+
### Fill Patterns
|
|
368
|
+
|
|
369
|
+
| Source values | Fill behavior | Example |
|
|
370
|
+
|---------------|---------------|---------|
|
|
371
|
+
| Single number | Copy | `42 → 42, 42, 42` |
|
|
372
|
+
| Single text | Copy | `foo → foo, foo, foo` |
|
|
373
|
+
| Single date | +1 day | `2026-01-01 → 2026-01-02, 2026-01-03` |
|
|
374
|
+
| Two+ numbers, constant diff | Linear series | `1,2 → 3,4,5` · `2,4 → 6,8,10` |
|
|
375
|
+
| Two+ dates, constant diff | Date series | `2026-01-01, 2026-01-03 → 2026-01-05, 2026-01-07` |
|
|
376
|
+
| Text + number, same prefix | Text-number series | `Item1,Item2 → Item3,Item4` |
|
|
377
|
+
| Two single letters | Alpha series | `A,B → C,D,E` |
|
|
378
|
+
| Formula | Reference translation | `=A1*2` → `=A2*2, =A3*2` |
|
|
379
|
+
| Multi-column / multi-row block | Per-column pattern inference | `A1:B2=[[1,10],[2,20]] → [[3,30],[4,40]]` |
|
|
380
|
+
|
|
381
|
+
### Formula Reference Rules
|
|
382
|
+
|
|
383
|
+
Fill-handle translation reuses the existing `shiftFormulaRefs()` — no second formula engine:
|
|
384
|
+
|
|
385
|
+
| Reference type | Syntax | Fill behavior |
|
|
386
|
+
|----------------|--------|---------------|
|
|
387
|
+
| Relative | `=A1` | Row/col offset with the target cell |
|
|
388
|
+
| Absolute | `=$A$1` | Stays unchanged |
|
|
389
|
+
| Mixed (col absolute) | `=$A1` | Row adjusts, column locked |
|
|
390
|
+
| Mixed (row absolute) | `=A$1` | Column adjusts, row locked |
|
|
391
|
+
| Composite | `=B1*$F$1` | `B1` adjusts, `$F$1` locked |
|
|
392
|
+
|
|
393
|
+
### Interaction
|
|
394
|
+
|
|
395
|
+
- **Fill handle**: 6px square at the selection's bottom-right corner, theme primary color; turns grey when the selection partially intersects a merge (fill disabled).
|
|
396
|
+
- **Hit-test**: independent `isFillHandleHit()` runs after resize handles and before cell click; hover shows `crosshair` cursor.
|
|
397
|
+
- **State machine**: a dedicated `autofilling` state prevents selection drag / editor / resize from starting; ESC cancels mid-drag.
|
|
398
|
+
- **Live preview**: the target range renders as a semi-transparent dashed rectangle during drag; the source selection stays put; no cell data is mutated until `mouseup`.
|
|
399
|
+
- **Edge auto-scroll**: dragging within 30px of the viewport edge starts a single `requestAnimationFrame` loop that scrolls and updates the target range; stopped on `mouseup` / ESC / pointercancel.
|
|
400
|
+
- **Dynamic expansion**: fills beyond the current `rowCount`/`colCount` trigger `ensureCapacity()` first, folded into the same undo step.
|
|
401
|
+
- **Selection after fill**: the selection updates to the union of source + target range.
|
|
402
|
+
- **Freeze panes**: all coordinates flow through `cellToScreenRect` / `screenToCell`, so the handle, hit-test, preview, and final fill work across frozen and body regions alike.
|
|
403
|
+
- **Merge compatibility**: partially intersecting merges disable the fill handle (conservative first version); whole-block merges fill correctly.
|
|
404
|
+
- **Touch**: shares the same `autoFillState` and `applyAutoFill` path as mouse — no separate implementation.
|
|
405
|
+
|
|
406
|
+
### Architecture
|
|
407
|
+
|
|
408
|
+
```
|
|
409
|
+
Fill Handle UI (drawFillHandle)
|
|
410
|
+
↓
|
|
411
|
+
Unified Hit-Test (isFillHandleHit)
|
|
412
|
+
↓
|
|
413
|
+
AutoFill Drag State (autoFillState)
|
|
414
|
+
↓
|
|
415
|
+
Target Range Calculation (computeTargetRange)
|
|
416
|
+
↓
|
|
417
|
+
Pure AutoFill Pattern Engine (core/autofill.ts)
|
|
418
|
+
↓
|
|
419
|
+
Formula Translation (shiftFormulaRefs)
|
|
420
|
+
↓
|
|
421
|
+
Style / Border / Cell Mutation (applyAutoFill)
|
|
422
|
+
↓
|
|
423
|
+
Undo Snapshot (saveUndo, one step per drag)
|
|
424
|
+
↓
|
|
425
|
+
scheduleRender()
|
|
426
|
+
```
|
|
427
|
+
|
|
428
|
+
The pure engine (`core/autofill.ts`) has zero Vue/Canvas dependencies and is fully unit-tested in `test/autofill.test.ts` (54 cases), making it reusable for `Ctrl+D`/`Ctrl+R`, paste-fill, right-click fill, and programmatic auto-fill.
|
|
429
|
+
|
|
430
|
+
---
|
|
431
|
+
|
|
361
432
|
## Border System
|
|
362
433
|
|
|
363
434
|
A dedicated border storage & rendering mechanism (`spreader/core/border-pool.ts` + `border-resolve.ts`).
|
|
@@ -460,10 +531,10 @@ The project includes a GitHub Actions workflow (`.github/workflows/publish.yml`)
|
|
|
460
531
|
### Near-term
|
|
461
532
|
|
|
462
533
|
- [x] More formulas: `COUNT`, `IF`, `VLOOKUP`, `CONCATENATE`
|
|
463
|
-
- [
|
|
534
|
+
- [x] Cell background color picker
|
|
464
535
|
- [x] Number format (currency, percentage, date, number of decimals) — *see [Number Format](#number-format)*
|
|
465
536
|
- [ ] Conditional formatting rules
|
|
466
|
-
- [
|
|
537
|
+
- [x] Auto-fill drag handle — *see [Auto Fill](#auto-fill)*
|
|
467
538
|
- [x] Find & Replace — *see [Find & Replace](#find--replace)*
|
|
468
539
|
|
|
469
540
|
### Mid-term
|
|
@@ -8,6 +8,14 @@ import type { CellCoord, CellData, CellStyle, SelectionRange, BorderStyle, Borde
|
|
|
8
8
|
* - 'all' :左上角全选按钮 → expandSelectionForMerges 行为
|
|
9
9
|
*/
|
|
10
10
|
export type SelectionMode = 'cell' | 'row' | 'col' | 'all';
|
|
11
|
+
/** AutoFill 拖拽状态 */
|
|
12
|
+
export interface AutoFillState {
|
|
13
|
+
active: boolean;
|
|
14
|
+
sourceRange: SelectionRange | null;
|
|
15
|
+
targetRange: SelectionRange | null;
|
|
16
|
+
direction: 'up' | 'down' | 'left' | 'right' | null;
|
|
17
|
+
preview: boolean;
|
|
18
|
+
}
|
|
11
19
|
export interface CoreState {
|
|
12
20
|
props: {
|
|
13
21
|
rowCount: number;
|
|
@@ -156,6 +164,10 @@ export interface CoreState {
|
|
|
156
164
|
clampScroll?: (sx: number | null, sy: number | null) => void;
|
|
157
165
|
/** 查找高亮钩子:返回某单元格当前的高亮类型(由 find-replace 模块注入) */
|
|
158
166
|
findHighlight?: (col: number, row: number) => 'active' | 'match' | null;
|
|
167
|
+
/** AutoFill 拖拽状态:active 时 render 绘制预览,mouseup 触发 applyAutoFill */
|
|
168
|
+
autoFillState: Ref<AutoFillState>;
|
|
169
|
+
/** 一次性提交 AutoFill:saveUndo → ensureCapacity → applyAutoFillPlan → 写入 cells + formulaDeps → selectRange → scheduleRender */
|
|
170
|
+
applyAutoFill: (sourceRange: SelectionRange, targetRange: SelectionRange, direction: 'up' | 'down' | 'left' | 'right') => void;
|
|
159
171
|
}
|
|
160
172
|
export declare function createCoreState(rawProps: {
|
|
161
173
|
rowCount?: number;
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import type { CellCoord, SelectionRange } from './types';
|
|
2
|
+
export type FillValue = {
|
|
3
|
+
kind: 'number';
|
|
4
|
+
num: number;
|
|
5
|
+
} | {
|
|
6
|
+
kind: 'text';
|
|
7
|
+
text: string;
|
|
8
|
+
} | {
|
|
9
|
+
kind: 'text-number';
|
|
10
|
+
prefix: string;
|
|
11
|
+
num: number;
|
|
12
|
+
digits: number;
|
|
13
|
+
} | {
|
|
14
|
+
kind: 'date';
|
|
15
|
+
serial: number;
|
|
16
|
+
} | {
|
|
17
|
+
kind: 'formula';
|
|
18
|
+
formula: string;
|
|
19
|
+
};
|
|
20
|
+
export type FillPattern = {
|
|
21
|
+
kind: 'copy';
|
|
22
|
+
sourceValues: FillValue[];
|
|
23
|
+
} | {
|
|
24
|
+
kind: 'linear';
|
|
25
|
+
step: number;
|
|
26
|
+
base: number;
|
|
27
|
+
sourceLen: number;
|
|
28
|
+
} | {
|
|
29
|
+
kind: 'text-number';
|
|
30
|
+
prefix: string;
|
|
31
|
+
step: number;
|
|
32
|
+
base: number;
|
|
33
|
+
digits: number;
|
|
34
|
+
sourceLen: number;
|
|
35
|
+
} | {
|
|
36
|
+
kind: 'date-linear';
|
|
37
|
+
step: number;
|
|
38
|
+
baseSerial: number;
|
|
39
|
+
sourceLen: number;
|
|
40
|
+
} | {
|
|
41
|
+
kind: 'text-series';
|
|
42
|
+
step: number;
|
|
43
|
+
baseCharCode: number;
|
|
44
|
+
sourceLen: number;
|
|
45
|
+
} | {
|
|
46
|
+
kind: 'formula';
|
|
47
|
+
};
|
|
48
|
+
export interface AutofillSheetLike {
|
|
49
|
+
cells: Record<string, {
|
|
50
|
+
value: string;
|
|
51
|
+
styleId?: number;
|
|
52
|
+
}>;
|
|
53
|
+
styles: ReadonlyArray<unknown>;
|
|
54
|
+
}
|
|
55
|
+
export interface FillResult {
|
|
56
|
+
cells: Record<string, {
|
|
57
|
+
value: string;
|
|
58
|
+
styleId?: number;
|
|
59
|
+
}>;
|
|
60
|
+
merges: Record<string, {
|
|
61
|
+
startCol: number;
|
|
62
|
+
startRow: number;
|
|
63
|
+
endCol: number;
|
|
64
|
+
endRow: number;
|
|
65
|
+
}>;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* 将单元格原始值解析为 FillValue。
|
|
69
|
+
* 优先级:公式 → 日期 → 文本+数字 → 纯数字 → 纯文本。
|
|
70
|
+
*/
|
|
71
|
+
export declare function parseFillValue(value: string, locale: string): FillValue;
|
|
72
|
+
/**
|
|
73
|
+
* 由源值序列推断填充模式。
|
|
74
|
+
* - 任一公式 → formula
|
|
75
|
+
* - 全为日期 → date-linear
|
|
76
|
+
* - 全为纯数字:单值 copy;多值等差 linear;非等差 copy
|
|
77
|
+
* - 全为文本+数字且 prefix 相同:单值 copy;多值等差 text-number;否则 copy
|
|
78
|
+
* - 全为单字符 ASCII 字母且 charCode 等差 → text-series
|
|
79
|
+
* - 其余 → copy
|
|
80
|
+
*/
|
|
81
|
+
export declare function inferFillPattern(sourceValues: FillValue[]): FillPattern;
|
|
82
|
+
/**
|
|
83
|
+
* 生成目标区域第 index 个(0-based,相对目标起点、靠近源的一端)的填充值(正向:下/右)。
|
|
84
|
+
* 目标第 index 个的逻辑索引为 sourceLen + index。
|
|
85
|
+
*/
|
|
86
|
+
export declare function generateFillValue(pattern: FillPattern, index: number, sourceLen: number): FillValue;
|
|
87
|
+
/**
|
|
88
|
+
* 将 FillValue 转为单元格数据(value + 透传源 styleId)。
|
|
89
|
+
* 日期存序列号字符串,渲染时由 numberFormat 格式化。
|
|
90
|
+
*/
|
|
91
|
+
export declare function fillValueToCellData(fv: FillValue, sourceStyleId?: number): {
|
|
92
|
+
value: string;
|
|
93
|
+
styleId?: number;
|
|
94
|
+
};
|
|
95
|
+
/**
|
|
96
|
+
* 根据源选区与拖拽目标格计算目标区域及方向。
|
|
97
|
+
* 落在源内返回 null。
|
|
98
|
+
*/
|
|
99
|
+
export declare function computeTargetRange(sourceRange: SelectionRange, draggedCell: CellCoord): {
|
|
100
|
+
targetRange: SelectionRange;
|
|
101
|
+
direction: 'up' | 'down' | 'left' | 'right';
|
|
102
|
+
} | null;
|
|
103
|
+
/**
|
|
104
|
+
* 平移公式引用以适配目标单元格($ 绝对引用由 shiftFormulaRefs 处理)。
|
|
105
|
+
*/
|
|
106
|
+
export declare function translateFormulaForTarget(sourceFormula: string, sourceCell: CellCoord, targetCell: CellCoord, colCount: number, rowCount: number, colToLabelFn: (col: number) => string): string;
|
|
107
|
+
/**
|
|
108
|
+
* 校验源/目标区域与已有合并的兼容性:
|
|
109
|
+
* - 源区域不能与任何 merge 部分相交(要么完全包含,要么不相交);
|
|
110
|
+
* - 目标区域不能与任何已有 merge 相交(会破坏 merge)。
|
|
111
|
+
*/
|
|
112
|
+
export declare function validateMergeCompatibility(sourceRange: SelectionRange, targetRange: SelectionRange, merges: Record<string, SelectionRange>): boolean;
|
|
113
|
+
/**
|
|
114
|
+
* 自动填充核心:根据源/目标区域与方向生成填充增量(纯函数,不 mutate sheet)。
|
|
115
|
+
* - down/right:正向延伸;up/left:反向延伸。
|
|
116
|
+
* - 公式按源位置循环并平移引用;其余按模式生成。
|
|
117
|
+
* - merges 暂返回空对象(merge 复制由后续任务决定)。
|
|
118
|
+
*/
|
|
119
|
+
export declare function applyAutoFillPlan(sourceRange: SelectionRange, targetRange: SelectionRange, sheet: {
|
|
120
|
+
cells: Record<string, {
|
|
121
|
+
value: string;
|
|
122
|
+
styleId?: number;
|
|
123
|
+
}>;
|
|
124
|
+
styles?: ReadonlyArray<unknown>;
|
|
125
|
+
}, direction: 'up' | 'down' | 'left' | 'right', locale: string, colCount: number, rowCount: number, colToLabelFn: (col: number) => string): FillResult;
|
|
@@ -10,6 +10,8 @@ export declare const MAX_ROW_HEIGHT = 500;
|
|
|
10
10
|
export declare const SB_SIZE = 11;
|
|
11
11
|
export declare const ARROW_SIZE = 11;
|
|
12
12
|
export declare const SCROLL_STEP = 50;
|
|
13
|
+
export declare const FILL_HANDLE_SIZE = 6;
|
|
14
|
+
export declare const FILL_HANDLE_HIT_PADDING = 4;
|
|
13
15
|
export declare const UNDO_MAX = 50;
|
|
14
16
|
export declare const i18n: Record<string, Record<string, string>>;
|
|
15
17
|
export declare function t(locale: string, key: string): string;
|
|
@@ -62,6 +62,7 @@ export interface NFOption {
|
|
|
62
62
|
export declare function parseNumberFormat(format: string): NFParsed;
|
|
63
63
|
/** 清空解析缓存(主要用于测试/资源释放) */
|
|
64
64
|
export declare function clearNumberFormatCache(): void;
|
|
65
|
+
export declare function serialToDate(serial: number): Date;
|
|
65
66
|
/**
|
|
66
67
|
* 将单元格原始字符串值按格式代码格式化为显示文本。
|
|
67
68
|
* 绝不修改传入的 value。
|
|
@@ -134,6 +135,11 @@ export interface DateTimeParseResult {
|
|
|
134
135
|
serial: number;
|
|
135
136
|
format: string;
|
|
136
137
|
}
|
|
138
|
+
/**
|
|
139
|
+
* 日期 → Excel 1900 系统序列号(与 serialToDate 互逆)。
|
|
140
|
+
* 1900-01-01 ~ 02-28 区间减 1,对齐 Excel 的 1900 虚构闰年(1900-02-29 = 60)。
|
|
141
|
+
*/
|
|
142
|
+
export declare function dateToSerial(y: number, m: number, d: number): number;
|
|
137
143
|
/**
|
|
138
144
|
* 对常规单元格的输入做常见日期/时间/日期时间字符串自动识别(对齐 Excel 输入语义):
|
|
139
145
|
* - 日期:yyyy-m-d、yyyy/m/d、yyyy年m月d日、m-d / m/d(年份补当前年)
|