700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > java Apache poi 操作word生成word目录(根据word模板生成word文件)

java Apache poi 操作word生成word目录(根据word模板生成word文件)

时间:2020-08-01 01:12:52

相关推荐

java Apache poi 操作word生成word目录(根据word模板生成word文件)

在项目需求中,需要对于一个word模板文档生成相对应的word文件,而此word模板是多页的并且需要在最终文件中生成相应的目录,由于项目环境是Linux,所以舍弃了jacob(windows环境)。然后主要是研究了Apache poi 进行word操作以及如何生成目录。

主要分两个部分介绍:

Apache poi 操作word:主要是通过XWPFDocument对象进行操作,api 地址:/apidocs/dev/

//读取word文件InputStream is = new FileInputStream(path); XWPFDocument doc = new XWPFDocument(is); List<IBodyElement> elements= doc.getBodyElements();//获取所有元素(段落和表格)int pIndex =0;int tIndex =0;for(int i=0 ; i< elements.size(); i++) {IBodyElement e = elements.get(i);//判断元素类型:段落/ 表格if(BodyElementType.PARAGRAPH.equals(e.getElementType())) {XWPFParagraph pa = e.getBody().getParagraphArray(pIndex); //获取段落List<XWPFRun> runs = paragraph.getRuns(); //获取段落文本for (XWPFRun run : runs) {...替换文本}}else if(BodyElementType.TABLE.equals(e.getElementType())){//表格XWPFTable ta = e.getBody().getTableArray(tIndex);List<XWPFTableRow> rows = ta.getRows(); //获取所有行for (XWPFTableRow row : rows) { 遍历每行List<XWPFTableCell> cells = row.getTableCells(); //获取每行单元格for (XWPFTableCell cell : cells) { //遍历单元格List<XWPFParagraph> paragraphs = cell.getParagraphs(); //获取单元格段落for (XWPFParagraph paragraph : paragraphs) {List<XWPFRun> runs = paragraph.getRuns();//获取单元格文本for (XWPFRun run : runs) {...替换文本}}}}}}

操作word方面还是很方便,可以参考一些更详细的:

/eye9093/article/details/77368703

/u012775558/article/details/79678701

主要是介绍一下目录如何生成

2. .Apache poi 生成word目录: 需要了解ooxml(Office Open XML)的大体结构,参考:/sc/ooxml/s-wml.xsd.html,主要是通过xml标签进行识别分页。

之前在网上也查阅了很多,发现目录的页数问题始终没有一个好的解决方案,之前看的可以通过转成pdf计算页数,但是这个耗时太长,特别是对于我们项目word页数较多的时候转换再重写消耗的时间很长。所以选择再去研究一下word对应的xml文件是否有思路去解决这一问题。

我们选择的是xxx.docx 文件,通过word另存为xml

获取到此word文件的xml文件,xml文件结构如下:

其实大体看一下可以大致理清xml的结构,而我们主要是关注这一个标签

这个标签就是分页之后产生的标签(经测试插入空白页不会产生这个标签,如果是遇到表格处于分页那么分页后的表格的第一个单元格必须有文本,不然也不会产生这个标签,而且文档必须有页码),而通过获取这个标签就可以计算出页数,可以看出这个标签位置是<w:p>下的<w:r>下,可以通过poi判断这个标签是否存在:

主要代码如下:

.//承接上面的获取的段落int num =1;//页数XWPFParagraph pa = e.getBody().getParagraphArray(pIndex); //获取段落List<CTR> ctrlist = pa.getCTP().getRList();//获取<w:p>标签下的<w:r>listfor(int j=0; j < ctrlist.size(); j++) { .//遍历rCTR r = ctrlist.get(j); List<CTEmpty> breaklist = r.getLastRenderedPageBreakList();//判断是否存在此标签if(breaklist.size() > 0) {num++; //页数添加}}

由此可以高效率的获取到页码,生成目录的代码可以参考:/p/0a32d8bd6878

所以大体功能实现思路如下:

POI读取word模板文件(模板必须有页码并且目录位置先用标签标记),然后进行模板内容替换。内容替换完毕后,再整体遍历所有段落和表格,在添加目录项时将对应的目录标题和页码作为参数传入,生成目录。全部生成完毕后,将文档输出到目标文件。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。