This commit is contained in:
iqudoo
2026-06-13 13:51:02 +08:00
parent 38b17c7589
commit 6cdae2f69c

129
README.md
View File

@@ -62,6 +62,8 @@ npm run preview # 预览构建结果
在元素的 `content` 中使用 `{变量名}` 引用数据。导出时由 Excel 列映射或默认值填充。 在元素的 `content` 中使用 `{变量名}` 引用数据。导出时由 Excel 列映射或默认值填充。
表格元素的变量写在各单元格的 `tableCells["行,列"].content` 中(见下文 **表格** 一节),同样参与变量汇总与数据映射。
| 占位符 | 说明 | | 占位符 | 说明 |
|--------|------| |--------|------|
| `{变量名}` | 普通变量,如 `{货位编号}``{物料名称}` | | `{变量名}` | 普通变量,如 `{货位编号}``{物料名称}` |
@@ -71,7 +73,7 @@ npm run preview # 预览构建结果
- 写在花括号内,不含 `}` - 写在花括号内,不含 `}`
- `#INDEX` reserved不要作为自定义变量名 - `#INDEX` reserved不要作为自定义变量名
- 可在 `variableList` 中预先声明;也会从 `content` 与显示条件中自动汇总 - 可在 `variableList` 中预先声明;也会从 `content`、**表格单元格 content** 与显示条件中自动汇总
### 导出时的变量映射(非模板字段) ### 导出时的变量映射(非模板字段)
@@ -96,7 +98,7 @@ npm run preview # 预览构建结果
| 字段 | 类型 | 说明 | | 字段 | 类型 | 说明 |
|------|------|------| |------|------|------|
| `id` | string | 元素唯一 ID | | `id` | string | 元素唯一 ID |
| `type` | `'text' \| 'barcode' \| 'qrcode' \| 'image'` | 元素类型 | | `type` | `'text' \| 'barcode' \| 'qrcode' \| 'image' \| 'table'` | 元素类型 |
| `name` | string | 图层名称(设计器显示用) | | `name` | string | 图层名称(设计器显示用) |
| `x`, `y` | number | 位置 (mm) | | `x`, `y` | number | 位置 (mm) |
| `width`, `height` | number | 尺寸 (mm) | | `width`, `height` | number | 尺寸 (mm) |
@@ -116,7 +118,7 @@ npm run preview # 预览构建结果
| `borderRadiusCorners` | object | 指定哪些角圆角,如 `{ "tl": true, "tr": true }` | | `borderRadiusCorners` | object | 指定哪些角圆角,如 `{ "tl": true, "tr": true }` |
| `locked` | boolean | 锁定后设计器不可拖动 | | `locked` | boolean | 锁定后设计器不可拖动 |
### 值提取(`text` / `barcode` / `qrcode` / `image` 均有效) ### 值提取(`text` / `barcode` / `qrcode` / `image` / 表格单元格 均有效)
**变量替换完成后的完整 `content` 字符串** 做提取(先替换 `{变量}`,再提取)。 **变量替换完成后的完整 `content` 字符串** 做提取(先替换 `{变量}`,再提取)。
@@ -223,6 +225,118 @@ npm run preview # 预览构建结果
--- ---
### 表格 `type: "table"`
表格由行数、列数及各行高、各列宽定义网格;单元格可单独设置内容与文本样式,支持合并。
元素级 `content` 对表格通常留空;**单元格内容默认为空**,在 `tableCells` 中按坐标单独设置。
#### 表格结构字段
| 字段 | 类型 | 默认值 | 说明 |
|------|------|--------|------|
| `tableRows` | number | `3` | 行数 (150) |
| `tableCols` | number | `3` | 列数 (150) |
| `tableRowHeights` | number[] | — | 各行高度 (mm),长度须等于 `tableRows` |
| `tableColWidths` | number[] | — | 各列宽度 (mm),长度须等于 `tableCols` |
| `tableBorderWidth` | number | `0.2` | 单元格网格线宽 (mm)`0` 时不绘制网格线 |
| `tableBorderColor` | string | `#374151` | 网格线颜色 |
| `tableCells` | Record<string, TableCellData> | — | 单元格数据,键为 `"行,列"`**从 0 开始** |
**尺寸关系**
- 内容区(网格区域)= 元素宽高减去 `padding`
- `sum(tableRowHeights)` = 内容区高度
- `sum(tableColWidths)` = 内容区宽度
- 增大内边距时,元素宽高会自动增大以保持行高/列宽不变
拖拽缩放表格四角时,各行高、各列宽会 **等比缩放**
#### `TableCellData``tableCells` 的值)
| 字段 | 类型 | 说明 |
|------|------|------|
| `content` | string | 单元格文本或 `{变量}`;缺省为空 |
| `mergeAnchor` | `{ row, col }` | 被合并单元格指向主单元格坐标 |
| `rowSpan` | number | 主单元格合并行数,默认 `1` |
| `colSpan` | number | 主单元格合并列数,默认 `1` |
| `fontSize` | number | 字号 (pt),缺省继承元素级 |
| `fontFamily` | `'sans' \| 'serif' \| 'mono'` | 字体 |
| `textAlign` | `'left' \| 'center' \| 'right'` | 水平对齐 |
| `verticalAlign` | `'top' \| 'middle' \| 'bottom'` | 垂直对齐 |
| `fontWeight` | `'normal' \| 'bold'` | 粗体 |
| `fontStyle` | `'normal' \| 'italic'` | 斜体 |
| `textUnderline` | boolean | 下划线 |
| `textLineThrough` | boolean | 删除线 |
| `textScaleX`, `textScaleY` | number | 水平/垂直拉伸 |
| `letterSpacing` | number | 字间距 (mm) |
| `textWritingMode` | `'horizontal' \| 'vertical'` | 排列方向 |
| `textColor` | string | 文字颜色 |
| `backgroundColor` | string | 单元格背景色 |
| `wordWrap` | boolean | 自动换行 |
| `textFormat` | 同文本元素 | 显示格式 |
| `decimalPlaces` | number | 小数位数 |
| `numberPartDisplay` | 同文本元素 | 数值拆分显示 |
| `textExtractMode` 等 | 同值提取字段 | 对该单元格 `content` 生效 |
| `textDisplayPrefix` / `textDisplaySuffix` | string | 显示前后缀 |
未在 `tableCells` 中声明的坐标视为空白单元格,使用元素级默认字体/对齐等绘制属性。
#### 合并单元格
- 主单元格(左上角)存 `rowSpan` / `colSpan`
- 被合并的从属单元格存 `mergeAnchor: { row, col }` 指向主单元格
- 合并区域内仅主单元格参与内容与样式;渲染时内部网格线自动省略
#### 表格示例片段
```json
{
"id": "el_table",
"type": "table",
"name": "明细表",
"x": 2,
"y": 2,
"width": 66,
"height": 20,
"content": "",
"fontSize": 9,
"textAlign": "center",
"verticalAlign": "middle",
"fontWeight": "normal",
"fontFamily": "sans",
"barcodeFormat": "CODE128",
"showText": false,
"tableRows": 2,
"tableCols": 3,
"tableRowHeights": [6, 6],
"tableColWidths": [22, 22, 22],
"tableBorderWidth": 0.2,
"tableBorderColor": "#374151",
"tableCells": {
"0,0": { "content": "物料", "fontWeight": "bold" },
"0,1": { "content": "数量", "fontWeight": "bold" },
"0,2": { "content": "货位", "fontWeight": "bold" },
"1,0": { "content": "{物料名称}" },
"1,1": { "content": "{数量}" },
"1,2": { "content": "{货位编号}" }
}
}
```
合并 2×2 区域示例(主单元格 `"0,0"``rowSpan: 2``colSpan: 2`
```json
"tableCells": {
"0,0": { "content": "标题", "rowSpan": 2, "colSpan": 2 },
"0,1": { "mergeAnchor": { "row": 0, "col": 0 } },
"1,0": { "mergeAnchor": { "row": 0, "col": 0 } },
"1,1": { "mergeAnchor": { "row": 0, "col": 0 } }
}
```
---
## 纸张排版 `PaperConfig` ## 纸张排版 `PaperConfig`
控制标签如何排列到 PDF 页面上(每模板独立保存)。 控制标签如何排列到 PDF 页面上(每模板独立保存)。
@@ -410,11 +524,13 @@ PDF 中标签之间的裁切参考线(预览与导出一致)。
对单个元素,最终显示值按以下顺序计算: 对单个元素,最终显示值按以下顺序计算:
1.`content` 中的 `{变量}` 替换为数据行值(文本元素可对每个变量做数值格式化) 1.`content` 中的 `{变量}` 替换为数据行值(文本元素可对每个变量做数值格式化**表格**对每格 `tableCells[*].content` 同样处理
2. 对完整字符串做 **值提取**trim → 分隔符 / 前 N / 后 N 2. 对完整字符串做 **值提取**trim → 分隔符 / 前 N / 后 N
3. 文本元素追加 **显示前后缀**`textDisplayPrefix` / `textDisplaySuffix` 3. 文本元素**表格单元格** 追加 **显示前后缀**`textDisplayPrefix` / `textDisplaySuffix`
4. 根据 **显示控制** 决定是否绘制该元素 4. 根据 **显示控制** 决定是否绘制该元素
表格单元格 `content` 为空时不绘制该格文字;网格线仍按 `tableBorderWidth` 绘制(为 `0` 时不显示)。
--- ---
## 导入 / 导出模板 ## 导入 / 导出模板
@@ -442,5 +558,6 @@ PDF 每页按 `paper` 网格排列标签,裁切线可选,标签图由 Canvas
## 类型定义源码 ## 类型定义源码
完整 TypeScript 类型见 [`src/types.ts`](src/types.ts)。 完整 TypeScript 类型见 [`src/types.ts`](src/types.ts)(含 `TableCellData`
表格工具函数见 [`src/tableUtils.ts`](src/tableUtils.ts)。
模板规范化逻辑见 [`src/utils.ts`](src/utils.ts) 中的 `normalizeTemplate` 模板规范化逻辑见 [`src/utils.ts`](src/utils.ts) 中的 `normalizeTemplate`