以上委托单的模板。
大概的需求是:
  1. 在本地编辑好一个docx文件模板,上传到服务器。
  2. 在浏览器中编辑或新键打印模板。
  3. 创建数据源
  4. 把数据源中的数据填充到docx模板中,并打印
其中有几个不好处理的点:
  1. 数据源是一个动态数据,并有查询条件,多表的关联条件
    千变万化的查询条件应该是这一章最困难的部分了。(ConfigStore)
  2. 样品信息部分是多行数
    就是是判断哪一部分需要根据数据重复多行,判断比较简单,
    判断完成后主要实现 table定位,插入行,以及保持模板中的字体及样式,比较困难的是在内容中有html标签和css样式,如换行,颜色等
    css比较好处理,html标签比较困难,因为word标签并不支持html那样复杂嵌套的格式
  3. 模板中有复选框
  4. 表格中有需要合并的行列,也有需要斜线拆分的单元格
    合并单元格注意,并不是值相同就合并,还要参考前一列或者前几列,如班级相同,但学校不同不应该合并。
    这个场景下操作word.table或拼接table是不可想像的,一般是先创建html.table再转换成word.table会比较简单,参考【excel操作】其中生成的table与word通用
  5. 列(表头)有动态生成的部分,比如每个个样品占一列,
    传统的拖拽用户希望的是拖拽表头,根据表头生成数,而现在是希望拖拽数据(这显示是不可能实现的,制作模板时还没有数据呢,需要二级映射+约定规则)
    对于操作用户来说,这部分应该最不容易理解的(文末列举了几个示例)
  6. 公章是动态数据,根据不同场景添加不同的公章
    有可能需要计算偏移量,以及末页内容高度。
  7. 字体字号等样式要求严格,同一单元格中根据中西文不同可能出现多种字体。
    因为是最终的检测报告,效力相当于法律文书、资质证书等,所在格式要求非常严格。编辑工具需要能够操作word元素尺寸,word板面横向分5000点,比像素分辨率要高。
  8. 数据定位问题,可以用占位符或书签
    占位符容易被拆开、书签操作繁琐。无论用什么都需要来自动态数据源。
    变量少的如只有三五个,可以用word自带书签,这样可以避免占位符被拆分的问题
    变量多的,大部分情况都是很多,会来自不同的数据源,每个数据源十列甚至几十列。
    需要保持变量(占位符)与word模板文件显示在一个页面最好一屏中,不能让用户到处找占位符。并有中英文对照,或者让用户只需要针对中文操作。
  9. 多层循环约定方式
    如有多个样品,每个样品下有多个检测项,第一层需要遍历样品,第二层需要遍历当前样品下手检测项

大概的实现过程:
  1. 上传文件到minio文件 
  2. 预览或编辑时由minio提供文件给onlyoffice实现在线编辑
  3. 编辑时由用户指定参数创建动态数据源,根据数据源返回值,设置模板文件的书签或占位符
  4. 编辑完成后把新版本文件返回给minio
  5. 打印时,由anyline service解析数据源参数并查询数据,返回一个动态结构
  6. 由anyline office根据模板与动态数据生成最终的docx文件
  7. 最后一步将anyline office生成的文件通过minio提供给only office预览打印
具体实现
以下是几个检测报告的表格示例,会在后面章节中实现
原数据:
主键 样品编号 检测项 点位名称 日期 时间 频次 属性名 检测值 参考值 判断结果
ID SAMPLE_CODE ITEM_NAME POINT_NAME YMD HMS RT FIELD_NAME VAL REF CHK
1 SAMP001 A 2022-1-1 10:10:00 第1次 深度 1 1 合格
2 SAMP001 A 2022-1-1 10:10:00 第1次 含量 2 2 合格
3 SAMP001 CO2 A 2022-1-2 12:10:00 第1次 浓度 1% 5% 合格
4 SAMP001 CO2 B 2022-1-2 15:30:00 第1次 含量 6 1 不合格
5 SAMP001 CO2 C 2022-1-2 16:30:00 第1次 深度 300 300 合格
6 SAMP001 硫化氢 A 2022-1-2 10:10:00 第1次 含量 200 200 合格
7 SAMP001 硫化氢 C 2022-1-2 12:10:00 第1次 浓度 100 100 合格
8 SAMP001 A 2022-1-1 10:10:00 第2次 深度 11 11 合格
根据原始数据生成以下表格:
检测项 频次 浓度-检测值 浓度-参考值 浓度-判定结果 含量-检测值 含量-参考值 含量-判定结果 深度-检测值 深度-参考值 深度-判定结果
CO2 第1次 1% 5% 合格 6 1 不合格 300 300 合格
第2次 11% 2% 不合格 31 20 不合格 3001 3001 合格
第3次 11% 2% 不合格 31 20 不合格 33 22 合格
第4次 11% 2% 不合格 31 20 不合格 77 3001 合格
第5次 15% 2% 不合格 5 20 不合格 301 3001 合格
硫化氢 第1次 100 100 合格 200 200 合格 # # #
第2次 # # # 2001 2001 合格 # # #
第4次 # # # 99 2001 合格 # # #
第5次 # # # 55 2001 合格 # # #
第1次 # # # 2 2 合格 1 1 合格
第2次 # # # 21 21 合格 11 11 合格
第3次 # # # 21 21 合格 11 11 合格
第4次 # # # 21 21 合格 11 11 合格
第5次 # # # 6 21 合格 11 11 合格


第1页
检测项 属性 第1次-检测值 第1次-参考值 第1次-判定结果 第2次-检测值 第2次-参考值 第2次-判定结果
CO2 浓度 1% 5% 合格 11% 2% 不合格
含量 6 1 不合格 31 20 不合格
深度 300 300 合格 3001 3001 合格
硫化氢 含量 200 200 合格 2001 2001 合格
浓度 100 100 合格 # # #
深度 1 1 合格 11 11 合格
含量 2 2 合格 21 21 合格
第2页
检测项 属性 第3次-检测值 第3次-参考值 第3次-判定结果 第4次-检测值 第4次-参考值 第4次-判定结果
CO2 浓度 11% 2% 不合格 11% 2% 不合格
含量 31 20 不合格 31 20 不合格
深度 33 22 合格 77 3001 合格
硫化氢 含量 # # # 99 2001 合格
深度 11 11 合格 11 11 合格
含量 21 21 合格 21 21 合格
第3页
检测项 属性 第5次-检测值 第5次-参考值 第5次-判定结果
CO2 浓度 15% 2% 不合格
含量 5 20 不合格
深度 301 3001 合格
硫化氢 含量 55 2001 合格
检测项 属性 第1次-检测值 第1次-参考值 第1次-判定结果 第2次-检测值 第2次-参考值 第2次-判定结果 第3次-检测值 第3次-参考值 第3次-判定结果 第4次-检测值 第4次-参考值 第4次-判定结果 第5次-检测值 第5次-参考值 第5次-判定结果
CO2 浓度 1% 5% 合格 11% 2% 不合格 11% 2% 不合格 11% 2% 不合格 15% 2% 不合格
含量 6 1 不合格 31 20 不合格 31 20 不合格 31 20 不合格 5 20 不合格
深度 300 300 合格 3001 3001 合格 33 22 合格 77 3001 合格 301 3001 合格
硫化氢 含量 200 200 合格 2001 2001 合格 # # # 99 2001 合格 55 2001 合格
浓度 100 100 合格 # # # # # # # # # # # #
深度 1 1 合格 11 11 合格 11 11 合格 11 11 合格 11 11 合格
含量 2 2 合格 21 21 合格 21 21 合格 21 21 合格 6 21 合格
检测项 频次 浓度 含量 深度
CO2 第1次 1% 6 300
第2次 11% 31 3001
第3次 11% 31 33
第4次 11% 31 77
第5次 15% 5 301
硫化氢 第1次 100 200 #
第2次 # 2001 #
第4次 # 99 #
第5次 # 55 #
第1次 # 2 1
第2次 # 21 11
第3次 # 21 11
第4次 # 21 11
第5次 # 6 11
检测项 属性 第1次 第2次 第3次 第4次 第5次
深度 1 11 11 11 11
含量 2 21 21 21 6
CO2 浓度 1% 11% 11% 11% 15%
含量 6 31 31 31 5
深度 300 3001 33 77 301
硫化氢 含量 200 2001 # 99 55
浓度 100 # # # #