解决 apache poi 转换 word(docx) 文件到 html 文件表格没边框的问题

2021-06-07 16:04

阅读:660

标签:process   包含   ttext   word   google   lines   结构   tca   开始   

一、起因
  这几天在做电子签章问题,要通过替换docx文件中的占位符生成包含业务数据的合同数据,再转换成html文件,转换成pdf文件。遇到的问题是:通过apache poi转换docx到html时,原生的表格文件可以正常显示,但是我通过代码生成的表格只有数据,而不展示边框。

 

二、问题分析
  google了一下发现有人碰到过类似问题,但是没有找到解决方法。现成的没有只能自己研究。

  贴上简单的填充表格内容的java代码

 1 private void replaceTable(XWPFDocument xdoc, List> lines, int pos) {
 2         if (CollectionUtils.isEmpty(lines)) {
 3             List th = new ArrayList();
 4             th.add("姓名");
 5             th.add("身份证");
 6             th.add("金额");
 7             lines.add(th);
 8         }
 9         XWPFTable replace = xdoc.createTable(lines.size(), lines.get(0).size());
10         CTTbl cttbl = replace.getCTTbl();
11         cttbl.addNewTblPr().addNewTblW().setW(BigInteger.valueOf(8800));
12         CTTblGrid cg = cttbl.addNewTblGrid();
13         cg.addNewGridCol().setW(BigInteger.valueOf(2500));
14         cg.addNewGridCol().setW(BigInteger.valueOf(3800));
15         cg.addNewGridCol().setW(BigInteger.valueOf(2500));
16         if (CollectionUtils.isNotEmpty(lines)) {
17             for (int i = 0; i ) {
18                 List line = lines.get(i);
19                 for (int j = 0; j ) {
20                     XWPFTableCell cell = replace.getRow(i).getCell(j);
21                     cell.setText(line.get(j));
22                     cell.getCTTc().addNewTcPr().addNewTcBorders().addNewTop();
23                 }
24             }
25         }
26         xdoc.setTable(pos, replace);
27         xdoc.removeBodyElement(xdoc.getPosOfTable(replace));
28     }

  逻辑很简单,通过生成一个新的表格来替换原来的表格。


  然后看一下可正常显示的表格的doc xml代码

 1 xml-fragment xmlns:wpc="http://schemas.microsoft.com/office/word/2010/wordprocessingCanvas" xmlns:mo="http://schemas.microsoft.com/office/mac/office/2008/main" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mv="urn:schemas-microsoft-com:mac:vml" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:m="http://schemas.openxmlformats.org/officeDocument/2006/math" xmlns:v="urn:schemas-microsoft-com:vml" xmlns:wp14="http://schemas.microsoft.com/office/word/2010/wordprocessingDrawing" xmlns:wp="http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing" xmlns:w10="urn:schemas-microsoft-com:office:word" xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" xmlns:w14="http://schemas.microsoft.com/office/word/2010/wordml" xmlns:wpg="http://schemas.microsoft.com/office/word/2010/wordprocessingGroup" xmlns:wpi="http://schemas.microsoft.com/office/word/2010/wordprocessingInk" xmlns:wne="http://schemas.microsoft.com/office/word/2006/wordml" xmlns:wps="http://schemas.microsoft.com/office/word/2010/wordprocessingShape">
 2   w:tblPr>
 3     w:tblW w:w="0" w:type="auto"/>
 4     w:tblBorders>
 5       w:top w:val="single" w:sz="4" w:space="0" w:color="auto"/>
 6       w:left w:val="single" w:sz="4" w:space="0" w:color="auto"/>
 7       w:bottom w:val="single" w:sz="4" w:space="0" w:color="auto"/>
 8       w:right w:val="single" w:sz="4" w:space="0" w:color="auto"/>
 9       w:insideH w:val="single" w:sz="4" w:space="0" w:color="auto"/>
10       w:insideV w:val="single" w:sz="4" w:space="0" w:color="auto"/>
11     w:tblBorders>
12     w:tblLook w:val="04A0" w:firstRow="1" w:lastRow="0" w:firstColumn="1" w:lastColumn="0" w:noHBand="0" w:noVBand="1"/>
13   w:tblPr>
14   w:tblGrid>
15     w:gridCol w:w="1984"/>
16     w:gridCol w:w="2694"/>
17     w:gridCol w:w="2885"/>
18   w:tblGrid>
19   w:tr w:rsidR="00D347DE" w:rsidRPr="00A709A0" w14:paraId="47BBA15B" w14:textId="77777777" w:rsidTr="00146A0B">
20     w:tc>
21       w:tcPr>
22         w:tcW w:w="1984" w:type="dxa"/>
23       w:tcPr>
24       w:p>
25         w:pPr>
26           w:jc w:val="center"/>
27         w:pPr>
28         w:r>
29           w:t>${表格匹配信息}w:t>
30         w:r>
31       w:p>
32     w:tc>
33     w:tc>
34       w:tcPr>
35         w:tcW w:w="2694" w:type="dxa"/>
36       w:tcPr>
37       w:p>
38         w:pPr>
39           w:jc w:val="center"/>
40         w:pPr>
41         w:r>
42           w:t xml:space="preserve">w:t>
43         w:r>
44       w:p>
45     w:tc>
46     w:tc>
47       w:tcPr>
48         w:tcW w:w="2885" w:type="dxa"/>
49       w:tcPr>
50       w:p>
51         w:pPr>
52           w:jc w:val="center"/>
53         w:pPr>
54         w:r>
55           w:t xml:space="preserve">w:t>
56         w:r>
57       w:p>
58     w:tc>
59   w:tr>
60 xml-fragment>

 

  然后看一下我们自己生成的替换表格

 1 xml-fragment xmlns:wpc="http://schemas.microsoft.com/office/word/2010/wordprocessingCanvas" xmlns:mo="http://schemas.microsoft.com/office/mac/office/2008/main" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mv="urn:schemas-microsoft-com:mac:vml" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:m="http://schemas.openxmlformats.org/officeDocument/2006/math" xmlns:v="urn:schemas-microsoft-com:vml" xmlns:wp14="http://schemas.microsoft.com/office/word/2010/wordprocessingDrawing" xmlns:wp="http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing" xmlns:w10="urn:schemas-microsoft-com:office:word" xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" xmlns:w14="http://schemas.microsoft.com/office/word/2010/wordml" xmlns:wpg="http://schemas.microsoft.com/office/word/2010/wordprocessingGroup" xmlns:wpi="http://schemas.microsoft.com/office/word/2010/wordprocessingInk" xmlns:wne="http://schemas.microsoft.com/office/word/2006/wordml" xmlns:wps="http://schemas.microsoft.com/office/word/2010/wordprocessingShape">
 2   w:tblGrid>
 3     w:gridCol w:w="2500"/>
 4     w:gridCol w:w="3800"/>
 5     w:gridCol w:w="2500"/>
 6   w:tblGrid>
 7   w:tr>
 8     w:tc>
 9       w:p>
10         w:r>
11           w:t>姓名w:t>
12         w:r>
13       w:p>
14     w:tc>
15     w:tc>
16       w:p>
17         w:r>
18           w:t>身份证w:t>
19         w:r>
20       w:p>
21     w:tc>
22     w:tc>
23       w:p>
24         w:r>
25           w:t>金额w:t>
26         w:r>
27       w:p>
28     w:tc>
29   w:tr>
30   w:tr>
31     w:tc>
32       w:p>
33         w:r>
34           w:t>小七w:t>
35         w:r>
36       w:p>
37     w:tc>
38     w:tc>
39       w:p>
40         w:r>
41           w:t>12345w:t>
42         w:r>
43       w:p>
44     w:tc>
45     w:tc>
46       w:p>
47         w:r>
48           w:t>888888.00w:t>
49         w:r>
50       w:p>
51     w:tc>
52   w:tr>
53   w:tr>
54     w:tc>
55       w:p>
56         w:r>
57           w:t>合计笔数:1w:t>
58         w:r>
59       w:p>
60     w:tc>
61     w:tc>
62       w:p>
63         w:r>
64           w:t/>
65         w:r>
66       w:p>
67     w:tc>
68     w:tc>
69       w:p>
70         w:r>
71           w:t>合计:888888.00w:t>
72         w:r>
73       w:p>
74     w:tc>
75   w:tr>
76 xml-fragment>

 

  可以很明显的看出,我们自己生成的表格在属性和元素数量上都比正常表格少了很多。

 

三、解决方法

  好在apache的代码设计结构清晰,十分优美,弥补了资料较少的不足。刚开始我是想参考正常表格手动补全缺少的内容,后来发现这样的工作量大不说,补出来的东西多多少少还是和正常结构有差,还是没法正常显示,后来发现了XMLObject这个类有一个set方法,可以通过这个方法直接复制正常表格的内容。

  最终的代码就是这样

 1     private void replaceTable(XWPFDocument xdoc, List> lines, int pos, XWPFTable table) throws XmlException {
 2         if (CollectionUtils.isEmpty(lines)) {
 3             List th = new ArrayList();
 4             th.add("姓名");
 5             th.add("身份证");
 6             th.add("金额");
 7             if (lines == null) {
 8                 lines = new ArrayList>();
 9             }
10             lines.add(th);
11         }
12         XWPFTable replace = xdoc.createTable(lines.size(), lines.get(0).size());
13         CTTbl cttbl = replace.getCTTbl();
14 
15         cttbl.getTblPr().set(table.getCTTbl().getTblPr());
16 
17         CTTblGrid cg = cttbl.addNewTblGrid();
18         cg.addNewGridCol().setW(BigInteger.valueOf(2500));
19         cg.addNewGridCol().setW(BigInteger.valueOf(3800));
20         cg.addNewGridCol().setW(BigInteger.valueOf(2500));
21 
22         CTRow originalRow = table.getCTTbl().getTrArray(0);
23         if (CollectionUtils.isNotEmpty(lines)) {
24             for (int i = 0; i ) {
25                 List line = lines.get(i);
26                 CTRow ctRow = cttbl.getTrArray(i);
27                 ctRow.set(originalRow);
28                 for (int j = 0; j ) {
29                     CTTc ctTc = ctRow.getTcArray(j);
30                     ctTc.removeP(0);
31                     CTText text = ctTc.addNewP().addNewR().addNewT();
32                     text.setStringValue(line.get(j));
33 
34                 }
35             }
36         }
37         xdoc.setTable(pos, replace);
38         xdoc.removeBodyElement(xdoc.getPosOfTable(replace));
39     }

 

解决 apache poi 转换 word(docx) 文件到 html 文件表格没边框的问题

标签:process   包含   ttext   word   google   lines   结构   tca   开始   

原文地址:http://www.cnblogs.com/verlen11/p/7325108.html


评论


亲,登录后才可以留言!