解决 apache poi 转换 word(docx) 文件到 html 文件表格没边框的问题
一、起因
这几天在做电子签章问题,要通过替换docx文件中的占位符生成包含业务数据的合同数据,再转换成html文件,转换成pdf文件。遇到的问题是:通过apache poi转换docx到html时,原生的表格文件可以正常显示,但是我通过代码生成的表格只有数据,而不展示边框。
二、问题分析
google了一下发现有人碰到过类似问题,但是没有找到解决方法。现成的没有只能自己研究。
贴上简单的填充表格内容的java代码
private void replaceTable(XWPFDocument xdoc, List<List<String>> lines, int pos) {
if (CollectionUtils.isEmpty(lines)) {
List<String> th = new ArrayList<String>();
th.add("姓名");
th.add("身份证");
th.add("金额");
lines.add(th);
}
XWPFTable replace = xdoc.createTable(lines.size(), lines.get(0).size());
CTTbl cttbl = replace.getCTTbl();
cttbl.addNewTblPr().addNewTblW().setW(BigInteger.valueOf(8800));
CTTblGrid cg = cttbl.addNewTblGrid();
cg.addNewGridCol().setW(BigInteger.valueOf(2500));
cg.addNewGridCol().setW(BigInteger.valueOf(3800));
cg.addNewGridCol().setW(BigInteger.valueOf(2500));
if (CollectionUtils.isNotEmpty(lines)) {
for (int i = 0; i < lines.size(); i++) {
List<String> line = lines.get(i);
for (int j = 0; j < line.size(); j++) {
XWPFTableCell cell = replace.getRow(i).getCell(j);
cell.setText(line.get(j));
cell.getCTTc().addNewTcPr().addNewTcBorders().addNewTop();
}
}
}
xdoc.setTable(pos, replace);
xdoc.removeBodyElement(xdoc.getPosOfTable(replace));
}
逻辑很简单,通过生成一个新的表格来替换原来的表格。
然后看一下可正常显示的表格的doc xml代码
<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">
<w:tblPr>
<w:tblW w:w="0" w:type="auto"/>
<w:tblBorders>
<w:top w:val="single" w:sz="4" w:space="0" w:color="auto"/>
<w:left w:val="single" w:sz="4" w:space="0" w:color="auto"/>
<w:bottom w:val="single" w:sz="4" w:space="0" w:color="auto"/>
<w:right w:val="single" w:sz="4" w:space="0" w:color="auto"/>
<w:insideH w:val="single" w:sz="4" w:space="0" w:color="auto"/>
<w:insideV w:val="single" w:sz="4" w:space="0" w:color="auto"/>
</w:tblBorders>
<w:tblLook w:val="04A0" w:firstRow="1" w:lastRow="0" w:firstColumn="1" w:lastColumn="0" w:noHBand="0" w:noVBand="1"/>
</w:tblPr>
<w:tblGrid>
<w:gridCol w:w="1984"/>
<w:gridCol w:w="2694"/>
<w:gridCol w:w="2885"/>
</w:tblGrid>
<w:tr w:rsidR="00D347DE" w:rsidRPr="00A709A0" w14:paraId="47BBA15B" w14:textId="77777777" w:rsidTr="00146A0B">
<w:tc>
<w:tcPr>
<w:tcW w:w="1984" w:type="dxa"/>
</w:tcPr>
<w:p>
<w:pPr>
<w:jc w:val="center"/>
</w:pPr>
<w:r>
<w:t>${表格匹配信息}</w:t>
</w:r>
</w:p>
</w:tc>
<w:tc>
<w:tcPr>
<w:tcW w:w="2694" w:type="dxa"/>
</w:tcPr>
<w:p>
<w:pPr>
<w:jc w:val="center"/>
</w:pPr>
<w:r>
<w:t xml:space="preserve"></w:t>
</w:r>
</w:p>
</w:tc>
<w:tc>
<w:tcPr>
<w:tcW w:w="2885" w:type="dxa"/>
</w:tcPr>
<w:p>
<w:pPr>
<w:jc w:val="center"/>
</w:pPr>
<w:r>
<w:t xml:space="preserve"></w:t>
</w:r>
</w:p>
</w:tc>
</w:tr>
</xml-fragment>
然后看一下我们自己生成的替换表格
<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">
<w:tblGrid>
<w:gridCol w:w="2500"/>
<w:gridCol w:w="3800"/>
<w:gridCol w:w="2500"/>
</w:tblGrid>
<w:tr>
<w:tc>
<w:p>
<w:r>
<w:t>姓名</w:t>
</w:r>
</w:p>
</w:tc>
<w:tc>
<w:p>
<w:r>
<w:t>身份证</w:t>
</w:r>
</w:p>
</w:tc>
<w:tc>
<w:p>
<w:r>
<w:t>金额</w:t>
</w:r>
</w:p>
</w:tc>
</w:tr>
<w:tr>
<w:tc>
<w:p>
<w:r>
<w:t>小七</w:t>
</w:r>
</w:p>
</w:tc>
<w:tc>
<w:p>
<w:r>
<w:t>12345</w:t>
</w:r>
</w:p>
</w:tc>
<w:tc>
<w:p>
<w:r>
<w:t>888888.00</w:t>
</w:r>
</w:p>
</w:tc>
</w:tr>
<w:tr>
<w:tc>
<w:p>
<w:r>
<w:t>合计笔数:1</w:t>
</w:r>
</w:p>
</w:tc>
<w:tc>
<w:p>
<w:r>
<w:t/>
</w:r>
</w:p>
</w:tc>
<w:tc>
<w:p>
<w:r>
<w:t>合计:888888.00</w:t>
</w:r>
</w:p>
</w:tc>
</w:tr>
</xml-fragment>
可以很明显的看出,我们自己生成的表格在属性和元素数量上都比正常表格少了很多。
三、解决方法
好在apache的代码设计结构清晰,十分优美,弥补了资料较少的不足。刚开始我是想参考正常表格手动补全缺少的内容,后来发现这样的工作量大不说,补出来的东西多多少少还是和正常结构有差,还是没法正常显示,后来发现了XMLObject这个类有一个set方法,可以通过这个方法直接复制正常表格的内容。
最终的代码就是这样
private void replaceTable(XWPFDocument xdoc, List<List<String>> lines, int pos, XWPFTable table) throws XmlException {
if (CollectionUtils.isEmpty(lines)) {
List<String> th = new ArrayList<String>();
th.add("姓名");
th.add("身份证");
th.add("金额");
if (lines == null) {
lines = new ArrayList<List<String>>();
}
lines.add(th);
}
XWPFTable replace = xdoc.createTable(lines.size(), lines.get(0).size());
CTTbl cttbl = replace.getCTTbl(); cttbl.getTblPr().set(table.getCTTbl().getTblPr()); CTTblGrid cg = cttbl.addNewTblGrid();
cg.addNewGridCol().setW(BigInteger.valueOf(2500));
cg.addNewGridCol().setW(BigInteger.valueOf(3800));
cg.addNewGridCol().setW(BigInteger.valueOf(2500)); CTRow originalRow = table.getCTTbl().getTrArray(0);
if (CollectionUtils.isNotEmpty(lines)) {
for (int i = 0; i < lines.size(); i++) {
List<String> line = lines.get(i);
CTRow ctRow = cttbl.getTrArray(i);
ctRow.set(originalRow);
for (int j = 0; j < line.size(); j++) {
CTTc ctTc = ctRow.getTcArray(j);
ctTc.removeP(0);
CTText text = ctTc.addNewP().addNewR().addNewT();
text.setStringValue(line.get(j)); }
}
}
xdoc.setTable(pos, replace);
xdoc.removeBodyElement(xdoc.getPosOfTable(replace));
}
解决 apache poi 转换 word(docx) 文件到 html 文件表格没边框的问题的更多相关文章
- POI读写Word docx文件
使用POI读写word docx文件 目录 1 读docx文件 1.1 通过XWPFWordExtractor读 1.2 通过XWPFDocument读 2 写docx ...
- Java利用poi生成word(包含插入图片,动态表格,行合并)
转(小改): Java利用poi生成word(包含插入图片,动态表格,行合并) 2018年12月20日 09:06:51 wjw_11093010 阅读数:70 Java利用poi生成word(包含插 ...
- 使用POI读写word docx文件
目录 1 读docx文件 1.1 通过XWPFWordExtractor读 1.2 通过XWPFDocument读 2 写docx文件 2.1 直接通过XWPF ...
- POI读word docx 07 文件的两种方法
POI在读写word docx文件时是通过xwpf模块来进行的,其核心是XWPFDocument.一个XWPFDocument代表一个docx文档,其可以用来读docx文档,也可以用来写docx文档. ...
- 使用java Apache poi 根据word模板生成word报表
项目开发过程中,客户提出一堆导出报表的需求,需要导出word格式,页眉还需要加上客户公司的logo,试了几种方案,最后选择了用 Apache poi 加上自定义标签的方式实现. 目前功能还比较简单,一 ...
- POI实现word文档转html文件
POI word文件转html package com.feiruo.officeConvert; import java.io.BufferedWriter; import java.io.File ...
- Apache Poi 操作word,替换字符保留样式问题,runs段落混乱问题。
关于这个问题也是刚好遇到,一通搜索也没有找到类似的或者是有效的方法.下面介绍一下. 首先apache poi的引入 <dependency> <groupId>org.apac ...
- 批量转换word文档到pdf文件
最近在整理每周的工作记录.因为每周的工作记录大都是单独的word文件,有时候忘记了也不容易找出来,一个个打开查找太费劲,因此想着把这些文件通过word2016的另存为功能转换为pdf,然后永Acrob ...
- 使用POI转换word doc文件
目录 1 转换为Html文件 2 转换为Xml文件 3 转换为Text文件 在POI中还存在有针对于word doc文件进行格式转换的功能.我们可以将word的内容 ...
随机推荐
- 使用CoApp创建NuGet C++静态库包
NuGet是微软开发平台下的包管理软件,使用它你可以非常方便的将一些第三方的库.框架整合进自己的项目中,省去了不少麻烦的配置过程.但是从官方文档上来看,貌似NuGet对C++的支持不是很好,并且在现阶 ...
- MySQL各模块工作配合
MySQL各模块工作配合 在了解了 MySQL 的各个模块之后,我们再看看 MySQL 各个模块间是如何相互协同工作的 .接下来,我们通过启动 MySQL,客户端连接,请求 query,得到返回结果, ...
- template might not exist or might not be accessible by any of the configured Template Resolvers
距离上一篇文章已经很长时间了,最近太忙碌了,今天发布spring boot遇到一个问题,找了好久才找到解决办法,今天贴出来和大家一起分享下,首先看错误信息 HTTP Status 500 - Requ ...
- 常见的JQuery应用举例
在学习JS之后,JQuery(以下简称JQ)为我们提供了一种更加便捷和简单的操作模式,利用它开发人员将更为高效的进行工作,下面将一些常见的问题进行举例. 1.点击某处弹出提醒,例如某些游戏在注册时会弹 ...
- 从ConcurrentHashMap的演进看Java多线程核心技术 Java进阶(六)
本文分析了HashMap的实现原理,以及resize可能引起死循环和Fast-fail等线程不安全行为.同时结合源码从数据结构,寻址方式,同步方式,计算size等角度分析了JDK 1.7和JDK 1. ...
- 霍尔开关MH253ESO在减压神器指尖手指陀螺中的作用
手指陀螺首先在欧美国家流行起来,现如今又在国外掀起一帆狂潮,它是一款排遣无聊的小玩具,又被称为减压神器. 其工作原理:是由一个双向的对称体作为主体,在主体中间嵌入一个轴承的设计组合,整体构成一个可平面 ...
- java IO之 字符流 (字符流 = 字节流 + 编码表) 装饰器模式
字符流 计算机并不区分二进制文件与文本文件.所有的文件都是以二进制形式来存储的,因此, 从本质上说,所有的文件都是二进制文件.所以字符流是建立在字节流之上的,它能够提供字符 层次的编码和解码.列如,在 ...
- javascript 实现 对XML文件 2级/3级联动操作
js代码 //实现对xml文档的读取:function loadXMLDoc(dname) { try // Internet Explorer { xmlDoc = new ActiveXObjec ...
- s2-048远程代码执行漏洞
在Struts 2.3.x 系列的 Showcase 应用中演示Struts2整合Struts 1 的插件中存在一处任意代码执行漏洞.当你的应用使用了Struts2 Struts1的插件时,可能导致不 ...
- git的一些基本命令
1.创建一个新的仓库:(选择一个合适的地方,创建一个空目录) $mkdir learngit //learngit是用git新建的一个目录 $cd learngit $pwd //pwd命令用于显示当 ...