Files
wukuang/packages/print-webapp/打印模板技术方案.md
2026-05-23 14:05:22 +08:00

239 lines
10 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 打印模板技术方案
## 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` 源码为准。*