javadocx4j动态⽣成表格,保存为word,并通过Libreoffice转PDF
缘起
最近客户要求把业务字段⽣成⼀个pdf,包含⼤量的表格,于是探究了两天版,终于出⼀个⽐较完美的解决⽅案。本次采⽤的是
docx4j,Libreoffice两个套件,docx4j本⾝有转PDF的功能,但是转换完成的PDF乱码,我没有到解决乱码的⽅法(⽐较菜,勿喷),然后选择了Libreoffice的⽅式,期间也是解决了很多bug,然后最终成功
安装 Libreoffice
之前在⽹上看到也有使⽤openoffice的,我之前也试过,转成pdf格式全变了,尤其是表格,后来发现的兼容性更好的Libreoffice,下⾯开始安装。
1. 官⽹地址:
2. 点击download,然后选择系统,我的是win10 64位的,所以选择Windows x86_64
3. 点下载后开始下载,如果感觉下载⽐较慢,在chrome(我使⽤的是⾕歌浏览器)的下载内容⾥⾯,复制下载链接,拷贝到迅雷⾥⾯,
我就是⽤的这种⽅法,下载速度还不错
4. 下载下来是msi⽂件,开始安装,我⾃定义了⾃⼰的路径:D:\libreOffice6\program\soffice -headless --
accept="socket,host=127.0.0.1,port=8100;urp;" -nologo -nofirststartwizard,host如果是127.0.0.1的话是只能本机访问,要是想让所有机器都能访问,就改为0.0.0.0,port是端⼝号。记住⼀定要加 -handless这个参数,不然在windows下调试⼀定会没法退出程序,这个参数的意思就是⽆界⾯运⾏。
coding
新建⼀个maven⼯程,l:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="/POM/4.0.0"xsi="/2001/XMLSchema-instance"
schemaLocation="/POM/4.0.0 /xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion>
<groupId>net.blf2</groupId>
<artifactId>test-docx4j</artifactId>
<version>0.1</version>getsavefilename
<name>Testdocx4j</name>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
&porting.outputEncoding>UTF-8</porting.outputEncoding>
<java.version>1.8</java.version>
<skipTests>true</skipTests>
</properties>
<dependencies>
<!-- mvnrepository/artifact/org.docx4j/docx4j -->
<dependency>
<groupId>org.docx4j</groupId>
<artifactId>docx4j</artifactId>
<version>3.3.7</version>
</dependency>
<!-- mvnrepository/artifact/org.docx4j/docx4j-export-fo -->
<dependency>
<groupId>org.docx4j</groupId>
<artifactId>docx4j-export-fo</artifactId>
<version>3.3.1</version>
</dependency>
<!-- mvnrepository/artifact/org.openoffice/bootstrap-connector -->
<dependency>
<groupId>org.openoffice</groupId>
<artifactId>bootstrap-connector</artifactId>
<version>0.1.1</version>
</dependency>
</dependencies>
</project>
代码:
package main.java.blf2;
import com.sun.star.beans.PropertyValue;
import com.sun.star.frame.XComponentLoader;
import com.sun.star.frame.XDesktop;
import com.sun.star.frame.XStorable;
import com.sun.star.lang.XComponent;
import com.sun.star.lang.XMultiComponentFactory;
import com.sun.star.uno.UnoRuntime;
import com.sun.star.uno.XComponentContext;
tor.BootstrapSocketConnector;
import org.docx4j.jaxb.Context;
import org.ptions.Docx4JException;
import org.ptions.InvalidFormatException;
import org.docx4j.openpackaging.packages.WordprocessingMLPackage;
import org.docx4j.openpackaging.parts.WordprocessingML.MainDocumentPart;
import org.docx4j.wml.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File;
import java.math.BigInteger;
import java.math.BigInteger;
public class Docx4jUtil {
private static final Logger logger = Logger(Docx4jUtil.class);
public static WordprocessingMLPackage wordPackage = null;
public static MainDocumentPart mainDocumentPart = null;
public static ObjectFactory objectFactory = null;
/**
* 创建word⽂档
*/
public static void createDocx(){
try{
wordPackage = atePackage();
mainDocumentPart = MainDocumentPart();
objectFactory = WmlObjectFactory();
}catch(InvalidFormatException e){
e.printStackTrace();
}catch(Exception e){
e.printStackTrace();
}
if(wordPackage == null || mainDocumentPart == null || objectFactory == null){
<("创建word⽂档失败");
wordPackage = null;
mainDocumentPart = null;
objectFactory = null;
}
}
/**
* 横向合并单元格
* @param mergeTable 需要合并的table
* @param beginColumn 开始列(从0开始算起)
* @param endColumn 结束列(从0开始算起)
* @param row 需要合并的⾏(从0开始算起)
* @param content 合并后内容
*/
public static void mergeTdCell(Tbl mergeTable,int beginColumn,int endColumn,int row, String content){        Tr tr =(Tr) Content().get(row);
Tc beginTd =(Tc) tr.getContent().get(beginColumn);
CTVerticalJc vjc =new CTVerticalJc();
vjc.setVal(STVerticalJc.CENTER);
TcPrInner.HMerge beginMerge =new TcPrInner.HMerge();
beginMerge.setVal("restart");
for(int i = beginColumn +1; i <= endColumn; i++){
Tc endTd =(Tc) tr.getContent().get(i);
TcPrInner.HMerge endMerge =new TcPrInner.HMerge();
endMerge.setVal("continue");
}
}
/**
* 纵向合并单元格
*
* @param mergeTable 需要合并的表格
* @param beginRow  开始⾏(从0开始算起)
* @param endRow    结束⾏(从0算起)
* @param column    列号(从0开始)
*/
public static void mergeMdCell(Tbl mergeTable,int beginRow,int endRow,int column, String content){        CTVerticalJc vjc =new CTVerticalJc();
vjc.setVal(STVerticalJc.CENTER);
Tc beginTd = null;
for(int i = beginRow;i <= endRow;i++){
Tr tr =(Tr) Content().get(i);
beginTd =(Tc) tr.getContent().get(column);
VMerge merge =new VMerge();
merge.setVal("restart");
}
}
/**
* 根据⼀个⼆维数据创建表格
* @param content ⼆维数组带内容
* @return
*/
public static Tbl createDataTable(String[][] content){
Tbl table = ateTbl();
PPr ppr =new PPr();
Jc jc =new Jc();
jc.setVal(JcEnumeration.CENTER);
ppr.setJc(jc);//单元格⽂本居中使⽤
for(int i =0; i < content.length; i++){
Tr dataTr = ateTr();
for(int j =0; j < content[i].length; j++){
Tc tc = ateTc();
tc.setTcPr(new TcPr());
}
}
setTcBorders(table);
return table;
}
/**
* 保存word⽂件
* @param outPathFileName 输出⽬录+⽂件名例如E:\\test\\test.docx
*/
public static void save(String outPathFileName){
try{
wordPackage.save(new File(outPathFileName));
}catch(Docx4JException e){
e.printStackTrace();
}
}
/**
* 把初始化的实例置为空
*/
public static void cleanResource(){
wordPackage.clone();
mainDocumentPart = null;
objectFactory = null;
logger.info("清理完成...");
}
/**
* 设置单元格边框
* @param table
*/
private static void setTcBorders(Tbl table){
table.setTblPr(new TblPr());// 必须设置⼀个TblPr,否则最后会报空指针异常        CTBorder border =new CTBorder();
border.setColor("auto");
border.setSz(new BigInteger("4"));
border.setSpace(new BigInteger("0"));
border.setVal(STBorder.SINGLE);
TblBorders borders =new TblBorders();
borders.setBottom(border);
borders.setLeft(border);
borders.setRight(border);
borders.setTop(border);
borders.setInsideH(border);
borders.setInsideV(border);
/
/ 获取其内部的TblPr属性设置属性
}
/**
* 把word转为pdf
* @param workingDir ⼯作⽬录就是word和pdf所在⽬录
* @param docxFileName word⽂件名
* @param pdfFileName pdf⽂件名
* @return
*/

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。