一:场景
通过Word模板来实现动态的word生成
二: 基本要求
1:替换文本中的内容
2:替换表格中的内容(不用动态生成表格)
3:替换后的内容应该与替换前的内容格式相同
4:模板修改方便
5:效果如下:
模板:
结果:
三:poi分析
使用方法:直接读取word文件,替换里面各个部分的内容
优点:直接使用word文件作为模板
缺点:本身的替换逻辑无法保留格式
四:为什么选择封装POI
1:因为时间和学习成本(懒)的问题,没有研究docx的xml规则,因此决定直接对现有的工具进行封装,来实现需求.
2:freeMarker本身只是对通用的模板进行处理,底层并不能直接解析word文件.
而poi本身就是对word文件进行操作的,因此可以对直接在poi的api上进一步的封装.
五:可行性分析
1.POI使用XWPFDocument对象来解析docx的文件,通过在构造时传入docx文件的读取流完成解析过程,将解析后将信息分门别类的存储在不同的对象中.并提供write(OutputStream stream)方法将这些对象重新转换为xml写入到文件中.
2.XWPFDocument中的对象存储有文本和格式等信息,能够拿到或修改这些信息
3.结合上述1,2两点,表示了POI存在修改word文本并保留格式的可能,通过编写Demo修改了XWPFDocument中的一个XWPFParagraph对象中的XWPFRun文本内容后证明了这一点.
XWPFDocument docx = new XWPFDocument(InputStream);
XWPFRun run = docx.getParagraphs().get(0).getRuns().get(0);
run.setText("modify");
docx.write(OutputStream);
六: 实现原理
1.文本内容和表格内容分别可以通过 getParagraphs() 和 getTables() 两个方法得到
XWPFDocument docx = new XWPFDocument(InputStream);
//文本内容
List<XWPFParagraph> allXWPFParagraphs = docx.getParagraphs();
//表格内容
List<XWPFTable> xwpfTables = docx.getTables();
2.查看XWPFTable发现,最后表格中的文本内容还是用XWPFParagraph对象存储
//获得每行
List<XWPFTableRow> xwpfTableRows = = xwpfTable.getRows();
List<XWPFTableCell> xwpfTableCells = new ArrayList<XWPFTableCell>();
for(int i = 0 ; i < xwpfTableRows.size() ; i++){
//获得一行的所有单元
xwpfTableCells.addAll(getCells(i));
}
List<XWPFParagraph> xw