From 6cdae2f69c071d999164805926362660976ffb54 Mon Sep 17 00:00:00 2001 From: iqudoo Date: Sat, 13 Jun 2026 13:51:02 +0800 Subject: [PATCH] =?UTF-8?q?=E8=A1=A8=E6=A0=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 129 +++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 123 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 2cf9238..1a61c3e 100644 --- a/README.md +++ b/README.md @@ -62,6 +62,8 @@ npm run preview # 预览构建结果 在元素的 `content` 中使用 `{变量名}` 引用数据。导出时由 Excel 列映射或默认值填充。 +表格元素的变量写在各单元格的 `tableCells["行,列"].content` 中(见下文 **表格** 一节),同样参与变量汇总与数据映射。 + | 占位符 | 说明 | |--------|------| | `{变量名}` | 普通变量,如 `{货位编号}`、`{物料名称}` | @@ -71,7 +73,7 @@ npm run preview # 预览构建结果 - 写在花括号内,不含 `}` - `#INDEX` reserved,不要作为自定义变量名 -- 可在 `variableList` 中预先声明;也会从 `content` 与显示条件中自动汇总 +- 可在 `variableList` 中预先声明;也会从 `content`、**表格单元格 content** 与显示条件中自动汇总 ### 导出时的变量映射(非模板字段) @@ -96,7 +98,7 @@ npm run preview # 预览构建结果 | 字段 | 类型 | 说明 | |------|------|------| | `id` | string | 元素唯一 ID | -| `type` | `'text' \| 'barcode' \| 'qrcode' \| 'image'` | 元素类型 | +| `type` | `'text' \| 'barcode' \| 'qrcode' \| 'image' \| 'table'` | 元素类型 | | `name` | string | 图层名称(设计器显示用) | | `x`, `y` | number | 位置 (mm) | | `width`, `height` | number | 尺寸 (mm) | @@ -116,7 +118,7 @@ npm run preview # 预览构建结果 | `borderRadiusCorners` | object | 指定哪些角圆角,如 `{ "tl": true, "tr": true }` | | `locked` | boolean | 锁定后设计器不可拖动 | -### 值提取(`text` / `barcode` / `qrcode` / `image` 均有效) +### 值提取(`text` / `barcode` / `qrcode` / `image` / 表格单元格 均有效) 对 **变量替换完成后的完整 `content` 字符串** 做提取(先替换 `{变量}`,再提取)。 @@ -223,6 +225,118 @@ npm run preview # 预览构建结果 --- +### 表格 `type: "table"` + +表格由行数、列数及各行高、各列宽定义网格;单元格可单独设置内容与文本样式,支持合并。 + +元素级 `content` 对表格通常留空;**单元格内容默认为空**,在 `tableCells` 中按坐标单独设置。 + +#### 表格结构字段 + +| 字段 | 类型 | 默认值 | 说明 | +|------|------|--------|------| +| `tableRows` | number | `3` | 行数 (1–50) | +| `tableCols` | number | `3` | 列数 (1–50) | +| `tableRowHeights` | number[] | — | 各行高度 (mm),长度须等于 `tableRows` | +| `tableColWidths` | number[] | — | 各列宽度 (mm),长度须等于 `tableCols` | +| `tableBorderWidth` | number | `0.2` | 单元格网格线宽 (mm);`0` 时不绘制网格线 | +| `tableBorderColor` | string | `#374151` | 网格线颜色 | +| `tableCells` | Record | — | 单元格数据,键为 `"行,列"`(**从 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` 控制标签如何排列到 PDF 页面上(每模板独立保存)。 @@ -410,11 +524,13 @@ PDF 中标签之间的裁切参考线(预览与导出一致)。 对单个元素,最终显示值按以下顺序计算: -1. 将 `content` 中的 `{变量}` 替换为数据行值(文本元素可对每个变量做数值格式化) +1. 将 `content` 中的 `{变量}` 替换为数据行值(文本元素可对每个变量做数值格式化;**表格**对每格 `tableCells[*].content` 同样处理) 2. 对完整字符串做 **值提取**(trim → 分隔符 / 前 N / 后 N) -3. 文本元素追加 **显示前后缀**(`textDisplayPrefix` / `textDisplaySuffix`) +3. 文本元素及 **表格单元格** 追加 **显示前后缀**(`textDisplayPrefix` / `textDisplaySuffix`) 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`。