当前位置: 首页 > news >正文

我如何开发 Doc Java工具,简化文档模板生成

在开发 Excel 模板填充工具 之后,我发现 Word 文档的填充需求同样广泛。许多业务场景需要基于固定模板动态生成文档,例如合同、报表、出口贸易文件等。手动填充这些文档效率低下,且容易出错,因此我决定开发一个 doc 工具,简化 Word 文档模板的生成过程。


核心思路:基于标签解析和数据替换

doc 工具的核心理念是 将模板中的数据用 Map 封装后传入,再解析 Word 模板中的标签并替换数据

在 Word 模板(.docx)文件中,我们可以使用类似 #{Map.TradeMode}#{Table.CNYSalesAmount} 这样的标签作为占位符,来标识需要填充的数据。例如,Word 文档模板可能包含以下内容:

贸易模式:#{Map.TradeMode}  
销售金额:#{Table.CNYSalesAmount}  

而在代码中,我设计了 DocUtil.replaceContent 方法来自动填充这些占位符,调用方式如下:

​
DocUtil.replaceContent(response.getOutputStream(), map, 
new ClassPathResource("report/ExportXXXXXXX.docx").getInputStream());

​

其中,map 是封装后的数据结构,例如:

map.put("#{Map.HSCode}", exportXXXXXXDTO.getHSCode());
map.put("Table", exportXXXXXXXXXXDTOList);
  • #{Map.HSCode} 这样的标签会被 exportXXXXXXDTO.getHSCode() 的值替换。
  • "Table" 代表一组数据,适用于表格填充的情况。

解析 Word 表格中的占位符并替换数据

在 Word 文档中,表格是一个常见的结构,我们需要检查表格中的每一行是否包含 #{Map 这样的标签,并进行替换。以下是核心代码示例:

for (int i = 0; i < xwpfTable.getRows().size(); i++) {
    if (checkRowCell(xwpfTable.getRows().get(i), "#{Map")) { 
        // 遍历该行的所有单元格
        for (XWPFTableCell xwpfTableCell : xwpfTable.getRows().get(i).getTableCells()) {
            for (XWPFParagraph cellParagraph : xwpfTableCell.getParagraphs()) {
                // 替换单元格中的占位符
                updateRuns(cellParagraph.getRuns(), replaceMap, "#{Map");
            }
        }
    }
}

代码解析:

  1. 遍历 Word 文档中的表格行 xwpfTable.getRows().get(i)
  2. checkRowCell() 方法检查该行是否包含 #{Map 作为占位符。
  3. 如果包含,则遍历该行的每个单元格 xwpfTableCell.getParagraphs()
  4. updateRuns() 方法用于替换占位符,将 #{Map.xxx} 替换成 replaceMap 里的数据。

为什么要用 Map 结构?

  1. 灵活性Map 结构可以动态存储任意类型的数据,不需要预定义字段。
  2. 解耦模板和数据:模板可以自由调整,不影响代码逻辑。
  3. 支持表格和列表:不仅能填充单个值,还能处理数据表格的动态填充。

doc 工具的应用场景

  • 自动生成合同、协议:比如贸易合同、租赁协议等
  • 报表填充:如销售数据报表、财务报表等
  • 出口贸易文件:如报关单、发票、提单等

最终的优化效果

减少手动填充工作量,提升开发效率
支持不同模板切换,只需调整 Word 文件,无需改动代码
更易维护,模板逻辑和数据分离,后期扩展更方便

通过 doc 工具,我成功实现了 Word 文档的自动填充,大幅提升了开发效率,也为业务系统带来了极大的便利。 🚀

相关文章:

  • Hi3516DV300——Taurus开发环境搭建
  • About HP.FocusMode
  • 清华大学DeepSeek使用手册:6本502页大合集PDF下载
  • LLM - Attention Is All You Need 的理解
  • 推荐1款OCR的扫描仪软件,无需安装,打开即用!
  • 智能化、数字化的智慧工地云平台源码,PC端+移动端+大屏端,开箱就能上项目
  • 解决windows npm无法下载electron包的问题
  • Biomamba劝学
  • 分布式中间件:环境准备
  • 3dsmax烘焙光照贴图然后在unity中使用
  • YOLOv12:目标检测新时代的破局者
  • DeepSeek vs Grok vs ChatGPT:大模型三强争霸,谁将引领AI未来?
  • OpenCV计算摄影学(12)色调映射(Tone Mapping)的一个类cv::TonemapMantiuk
  • 模型推理增强微调
  • C++核心指导原则: 标准库
  • UE5设置打开新窗口默认停靠在主窗口
  • 【分享】网间数据摆渡系统,如何打破传输瓶颈,实现安全流转?
  • Redis的主要数据类型及其应用场景
  • 制服小程序的“滑手”:禁用页面左右滑动全攻略
  • mybatis热点面试题第五弹
  • 巴菲特第60次股东大会开场点赞库克:他为伯克希尔赚的钱比我还多
  • 客场不敌蓉城遭遇联赛首败,申花争冠需要提升外援能力
  • 向左繁华都市,向右和美乡村,嘉兴如何打造城乡融合发展样本
  • 澎湃读报丨央媒头版集中刊发社论,庆祝“五一”国际劳动节
  • 网警查处编造传播“登顶泰山最高可得3万奖金”网络谣言者
  • 夜读丨春天要去动物园