Files

239 lines
10 KiB
Markdown
Raw Permalink Normal View History

2026-05-23 14:05:22 +08:00
# 打印模板技术方案
## 1. 方案概述
### 1.1 目标
- **设计态**:提供控件区、工具栏、画布(类 Excel 网格)、属性区四块区域的可视化模板编辑;支持主表/子表/流程等字段拖放、单元格样式与表格绘制、多 Sheet、多页、页眉页脚与背景图、全局水印等。
- **运行态**:将模板 `content` + `settings` 与业务数据 `RuntimeFormData` 合并,完成预览与浏览器打印(iframe 输出,可降级为新窗口)。
- **工程目标**:与平台「打印管理」融合;模板以 JSON 持久化;内核与 UI 分层,便于维护与扩展。
### 1.2 技术栈(与代码一致)
| 层级 | 技术 |
| --- | --- |
| 设计器 UI | Vue 3`H3PrintDesigner` 等) |
| 画布与渲染内核 | `excellit`:Lit HTML 模板 + 数据仓库(DataStore+ 工厂(factory |
| 打印运行时 | `runtime``H3PrintRuntime`,封装预览/打印与数据过滤 |
| 条码/二维码 | `jsbarcode``qrcode` |
| 样式 | SCSS,独立 `style` 出口 |
SDK 通过 `package.json``exports` 暴露 `./designer``./runtime``./excellit` 与统一样式 `./style`
---
## 2. 整体架构
### 2.1 分层
```text
平台宿主(打印管理 / 表单)
↓ 元数据 metaData + 模板 templateData
print-webapp / designerH3PrintDesigner
↓ 产出 PageDatacontent[] + settings
持久化 API(如 /api/v1/print/tpl/detail/:id
print-webapp / runtimeH3PrintRuntime
↓ PageData + RuntimeFormData[]
excellitExcelLitApi / ExcelLitCore
↓ Lit 渲染 + parse-cell 数据绑定
浏览器预览 / window.printruntime/print
```
### 2.2 包职责
| 包 | 职责 |
| --- | --- |
| **designer** | 设计器壳层:`metaData`(字段树)、`templateData`content/settings 字符串需 JSON 解析)、`ExcelLit` 单例驱动画布;提供控件区、设置区、在线 Excel 工具条等。 |
| **excellit** | 表格画布:行列、合并单元格、浮动层、子表/流程日志区域、水印与背景层、单元格内容解析(含富文本、条码、图片等)。 |
| **runtime** | 无设计器 UI:加载模板与表单数据,创建 `ExcelLitApi` 实例执行 `printPreview`,处理默认模板、加载态、生命周期回调与字段占用分析等。 |
### 2.3 设计器与内核连接要点
- 设计器 `provide``$excelLit``ExcelLit` 实例)、`fileUploader`
- 模板变更时销毁并重建 `excelLitInstance`,避免状态污染。
- `PageData``content`**Sheet 数组**,支持多 Sheet`settings` 为全局页面设置(纸张、边距、打印类型等)。
---
## 3. 数据模型
### 3.1 顶层:`PageData`
`packages/excellit/src/types/page-data/index.d.ts` 一致:
```ts
interface PageData {
id?: string
templateName: string
content: SheetContent[] // 多 Sheet,每页一块 sheet 数据
settings: PageSetting
metaData?: any[]
language?: string
}
```
### 3.2 单 Sheet`SheetContent`
包含列宽 `cols`、行高 `rows`、单元格矩阵 `cells`、浮动块 `floatLayer`、子表范围 `subTableRanges`、流程日志范围 `workflowLogRanges` 等,支撑需求中的子表循环体、流程日志多行打印等。
### 3.3 页面设置:`PageSetting`
`page-setting.d.ts``DefaultPageSetting``const/page-setting.ts`)对齐,核心字段包括:
| 概念 | 代码字段 | 说明 |
| --- | --- | --- |
| 文档类 / 套打类 | `printType``PrintType.Document` / `PrintType.TemplatePrint` | 控制行高自适应 vs 固定区域截断、子表分页策略等(业务规则在解析与布局层实现) |
| 分页 / 连续 | `pageMode``'break'` / `'continuity'` | 对应需求「分页打印」「连续打印」 |
| 纸张 | `sizeType``size`(宽×高,单位与 UI 一致) | A4/A5/B3/B4/B5/自定义 |
| 方向 | `orientation``portrait` / `landscape` | |
| 边距 | `margin`left/right/top/bottommm | 画布可打印区 = 纸张 − 边距 |
| 页眉页脚 | `pageHeader``pageFooter` | 左/中/右三块配置 |
| 背景 | `background``backgroundArr``checkPrintBgArr` | 支持多背景与是否打印 |
| 水印 | `watermarkEnabled``watermarkSetting` | 内容、字号、颜色、透明度、角度、密度、排列方式 |
| 多页索引 | `pageNumberArr``sheetIndex` | 与多 Sheet、多页删除图标等联动 |
### 3.4 运行时数据:`RuntimeFormData`
```ts
type RuntimeFormData = { [fieldCode: string]: any }
```
为单条或批量记录字段值的扁平字典;子表、流程日志等多行数据由内核在 `compositionCellsDataBySubTableForm` 等工具中展开到网格。
---
## 4. 设计态实现要点
### 4.1 四块区域
| 区域 | 实现落点 |
| --- | --- |
| 控件区 | `controls-section.vue` 等,按 `metaData.fields` 分类展示业务字段、流程字段、系统字段、其他字段(图片、富文本、二维码、条形码等) |
| 工具栏 | `online-excel/excel-toolbar`:字体、对齐、边框、合并单元格;含「富文本」入口(`setRichText` 写入 `fieldType: 'RichText'` |
| 画布 | `OnlineExcel` + excellit `DesignerLayout`:白底可印区、灰底非印区、行列标题拖拽 |
| 属性区 | `settings-section`:全局页面属性 + 选中单元格/控件属性(子表列、流程日志节点等) |
### 4.2 画布内核(excellit
- **入口**`ExcelLitCore.initExcelData` 依次提交 `setPageSetting``initSheetData`,注册 Lit 模板与工厂,订阅 action/mutation。
- **布局**`template/layout/designer.ts` 组合表体、边框层、浮动层、背景层、水印层、子表层、流程层、分页删除图标等。
- **交互**selection、shortcuts、context menu、拖拽虚拟展示(`dragger-virtual-dom`)等由 factory 注入。
### 4.3 子表 / 流程日志
- 子表、流程日志在数据结构中占用 `subTableRanges` / `workflowLogRanges`,渲染由 `subTableRender``workflowLogRender` 等承担。
- **文档类**:子表循环体下方内容随数据下移。
- **套打类**:需配置每页子表(或流程日志)行数并预留空白行,避免叠字;主表在每页重复——与 `printType` 及分页算法一致。
---
## 5. 富文本在打印模板中的技术衔接
表单侧富文本编辑器能力(KindEditor、HTML 存储、上传、DOMPurify 等)同模型内富文本组件。在**打印模板**中:
### 5.1 设计态
- 工具栏可将单元格设为 **打印富文本**`FieldType.RichText`),打开表格弹窗编辑(`tableDialog` 等对 `RichText` 分支)。
- 设计态拖拽预览使用 `TextVirtualDom` 等轻量展示。
### 5.2 数据形态
- 单元格 `content` 携带 `fieldType: 'RichText'``text`HTML 字符串)。
- HTML 内可嵌入带 `fieldCode` 的占位 `span`,运行时用 `runtimeFormData[fieldCode]` 替换为实际值(可能仍是 HTML)。
### 5.3 运行态渲染
- `parse-cell.ts``parseRichText`:运行态下构建 `.xlt__runtime-richtext` 容器,解析占位节点并注入数据;可对高度相关样式过滤以配合分页高度预计算(`prefetch-cell-height.ts` 等对 `RichText` 的特殊处理)。
- 企微等特殊环境可走 `EngineEntryType.WECOMESTANDARD` 分支。
---
## 6. 运行态与打印链路
### 6.1 `H3PrintRuntime` 主流程
1. `renderData(templateData, runtimeFormData)` 合并模板与数据。
2. `printPreview` 中创建 `ExcelLitApi``isParse` 等参数控制是否解析为打印视图)。
3. 内核在存在 `formData``setFormData` 并走打印渲染路径。
### 6.2 物理打印
- `excellit/src/runtime/print.ts``runtimePrint` 收集 DOM `outerHTML`,写入隐藏 iframe,复制当前页 `style/link/meta`,再触发打印;失败时降级 `printContentInNewWindow`
- 打印样式含对粗体等类的补偿,保证与屏幕一致。
### 6.3 前台调用
- **列表批量打印**、**表单打印**:由宿主传入多条或单条 `RuntimeFormData` 与模板 `PageData`;连续模式依赖 `pageMode: 'continuity'` 与排版结果。
---
## 7. 与平台融合
### 7.1 API 约定(designer/services
待确定...
### 7.2 设计器入参校验(`designer-index.vue`
- `metaData` 需包含 `fields``workflowField`(或 workflow 配置)等。
- `templateData` 需包含 `content``settings``templateName`
### 7.3 与旧模板
新模板入口与旧模板入口相同,通过增加配置项区分。
技术方案待确定。
---
## 8. 非功能需求
### 8.1 性能
- 大表分页与行高预计算:`prefetch-cell-height` 等避免一次性撑破布局。
- 富文本避免频繁整段 `innerHTML` 回灌导致光标问题属表单编辑器范畴;打印侧关注分页前高度预估一致性。
### 8.2 国际化
- `ExcelLit.I18n` 与设计器 `$prt_Lng``language` 变更时重置语言与表格。
### 8.3 可测试性
- 单元测试:`parse-cell` 中各 `fieldType`、水印与页边距计算、toolbar 映射。
- 集成测试:设计器保存 → runtime 预览 → 打印 DOM 结构。
---
## 9. 交付拆分与里程碑建议
| 阶段 | 内容 |
| --- | --- |
| M1 | `PageData` 协议与宿主联调;列表/表单打开设计器、保存接口 |
| M2 | 文档类/套打类、分页/连续、纸张边距、页眉页脚、背景图 |
| M3 | 子表与流程日志循环、套打行数与换页、主表每页重复 |
| M4 | 全局水印、二维码/条形码/图片等控件闭环 |
| M5 | 富文本占位与运行态替换、高度与分页联调;与《富文本方案》安全策略对齐 |
| M6 | 批量打印、性能与浏览器打印回归 |
---
## 10. 附录:关键文件索引
| 模块 | 路径(相对于 `packages/print-webapp` |
| --- | --- |
| 设计器入口 | `packages/designer/src/views/designer-index.vue` |
| 设计器导出 | `packages/designer/src/index.js` |
| Runtime | `packages/runtime/src/index.ts` |
| 画布核心 | `packages/excellit/src/core/main.ts` |
| 表格 API | `packages/excellit/src/api/table.ts` |
| 页面默认设置 | `packages/excellit/src/const/page-setting.ts` |
| 类型定义 | `packages/excellit/src/types/page-data/*.d.ts``sheet-content/*.d.ts` |
| 单元格解析 | `packages/excellit/src/utils/parse-cell.ts` |
| 打印执行 | `packages/excellit/src/runtime/print.ts` |
| SDK 聚合导出 | `src/index.ts` |
---
*文档版本与代码库同步维护;若实现与本文不一致,以 `packages/print-webapp` 源码为准。*