解决 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的内容 ...
随机推荐
- Mac QQ 怎么清除聊天记录
在 Mac 电脑上登录 QQ 以后,点击顶部菜单中“应用”下的“消息管理器”选项,如图所示
- 【Android Developers Training】 78. 序言:执行网络操作
注:本文翻译自Google官方的Android Developers Training文档,译者技术一般,由于喜爱安卓而产生了翻译的念头,纯属个人兴趣爱好. 原文链接:http://developer ...
- 7.如何发布vue项目到服务器
1.确保程序是可运行的,即npm run dev可以运行 2.把index.js修改 3.运行npm命令npm run build 4.生成的dist文件为 直接点击index.html就能运行,部署 ...
- php如何上传txt文件,并且读取txt文件
1.创建目录如下
- vmware虚拟机的克隆
开发中需要用到多个虚拟机进行实验.重新安装过程又太繁琐,通过vmware虚拟机自带软件能够很好的快速克隆出完全相同的系统.下面会为大家讲解关于vmware虚拟机怎么克隆,我所用的VMware版本是11 ...
- 关闭chrome浏览器的developer tools
背景 Chrome使用过程中,很容易启动Chrome developer tools,一些误触如按到F12.CTRL+Shift+C等都会启动developer tools.对于不开发Web的人来说, ...
- Android开发随手记
本文是作者在Android开发实践中的随手速记,记录一些小问题的解决方案和注意事项,持续更新. 以下是速记内容,若有不严谨的地方,望小伙伴们指出. 1.Module 不生成R文件,可尝试取消对该Mod ...
- MyBatis-sql映射文件
Sql映射文件 MyBatis真正的力量是在映射语句中.这里是奇迹发生的地方.对于所有的力量,SQL映射的XML文件是相当的简单.当然如果你将它们和对等功能的JDBC代码来比较,你会发现映射文件节省了 ...
- HTML基本结构与标签总结整理篇
HTML基本结构与标签总结整理篇 前言:这是笔者的学习总结与整理,如果有错误或疑问的地方,欢迎指正与讨论!另:此文会不定时更新~ 1.了解HTML 学习前端技术,必然涉及三个方面:html(结构).c ...
- C#调用TSC条码打印机打印二维码
#region 调用TSC打印机打印 /// <summary> /// 调用TSC打印机打印 /// </summary> /// <param name=" ...