解决 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的内容 ...
随机推荐
- [leetcode-575-Distribute Candies]
Given an integer array with even length, where different numbers in this array represent different k ...
- 数据结构之网络流入门(Network Flow)简单小节
网络流的相关定义: 源点:有n个点,有m条有向边,有一个点很特殊,只出不进,叫做源点. 汇点:另一个点也很特殊,只进不出,叫做汇点. 容量和流量:每条有向边上有两个量,容量和流量,从i到j的容量通常用 ...
- JVM总结之GC
哪些内存需要回收 在Java堆中存放着几乎所有的对象实例,垃圾收集器在对堆进行回收前,第一件事情就是要知道哪些对象还"存活着",哪些对象已经"死去". 引用计数 ...
- diy toy: image auto-handler
备忘之:) config.xml <?xml version="1.0" encoding="utf-8"?> <config> < ...
- sublime text 3 配置python IDE
Python越来越受“程序猿”们的青睐.快速的开发模式,简洁的代码格式,海量的扩展,这无疑都为python的火热奠定了基础. “磨刀不误砍柴工”,一款功能强劲的IDE能帮助开发者有效的管理.编辑,运行 ...
- English - Titanium Bike
The silver-gold triathlon bike was sitting in Kris's dining room next to the door. It had no kicksta ...
- Vue.js 基本功能了解
一.写在前面 隔了这么久才来出Vue的第二篇文章,真是堕落了,自己先惩罚下/(ㄒoㄒ)/~~ 回过头看自己第一篇相关文章<初试 Vue.js>(http://www.cnblogs.com ...
- java 数据库编程 学习笔记 不断更新
最近开始学习java,感觉java的数据库编程需要发个随笔记录一下,话不多说 切入正题. 一.数据库访问技术的简介 应用程序 → 执行SQL语句 →数据库 → 检索数据结果 → 应用程序 ( ...
- jsp注册页面验证,easyui的jsp+js表单验证
1.1下面的代码是写在Js里面的,就直接写进去不用什么其他东西,这样一个表单验证就好了(1.2图) $.extend($.fn.validatebox.defaults.rules, { phone: ...
- python基础(7):元祖类型(赋值补充)
前面学了列表和字典,今天我们看一个和列表相似的类型元祖. 预习: 简单购物车 实现打印商品详细信息,用户输入商品名和购买个数,则将商品名,价格,购买个数加入购物列表,如果输入为空或其他非法输入则要求用 ...