10 KiB
10 KiB
打印模板技术方案
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 分层
平台宿主(打印管理 / 表单)
↓ 元数据 metaData + 模板 templateData
print-webapp / designer(H3PrintDesigner)
↓ 产出 PageData:content[] + settings
持久化 API(如 /api/v1/print/tpl/detail/:id)
↓
print-webapp / runtime(H3PrintRuntime)
↓ PageData + RuntimeFormData[]
excellit(ExcelLitApi / ExcelLitCore)
↓ Lit 渲染 + parse-cell 数据绑定
浏览器预览 / window.print(runtime/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 一致:
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/bottom(mm) |
画布可打印区 = 纸张 − 边距 |
| 页眉页脚 | pageHeader、pageFooter |
左/中/右三块配置 |
| 背景 | background、backgroundArr、checkPrintBgArr |
支持多背景与是否打印 |
| 水印 | watermarkEnabled、watermarkSetting |
内容、字号、颜色、透明度、角度、密度、排列方式 |
| 多页索引 | pageNumberArr、sheetIndex |
与多 Sheet、多页删除图标等联动 |
3.4 运行时数据:RuntimeFormData
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 主流程
renderData(templateData, runtimeFormData)合并模板与数据。printPreview中创建ExcelLitApi(isParse等参数控制是否解析为打印视图)。- 内核在存在
formData时setFormData并走打印渲染路径。
6.2 物理打印
excellit/src/runtime/print.ts:runtimePrint收集 DOMouterHTML,写入隐藏 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 源码为准。