赞
踩
适用范围:
1.已有word模板,word中的一些数据需要动态生成。
2.word转为pdf
本文章讲解的内容是一个完整的适用流程。就是首先是一个word模板,然后动态填充数据生成了一个新的word,填充数据之后最后转换成了pdf。
如果你只需要动态填充数据,得到一个新的word的话,适当修改下代码就可以了。说白了就是删代码,因为本身就用到了此功能。
如果你需要word转为pdf,适当修改下代码也是可以的。说白了还是删代码,因为本身也用到此功能。
发挥您的想象空间,此插件甚是强大。有问题联系我哦。代码注释里说了怎么找我…
Constants.java
package org.example.util;
/**
* @author lucas
* @program wtp-site
* @description
* @createDate 2020-03-04 23:05:31
* 关注微信公众号"程序员无名",600GJava架构师网盘资料等你下载
* 这套代码我已经亲测可用了。若有特殊问题,请于公众号里随时与我联系。
**/
public class Constants {
/**
* aspose需要的签名文件名称
*/
public static String licensePath = "license.xml";
/**
* 模板,签名文件存放的路径(绝对路径哈,我这里是mac的绝对路径。)
*/
public static String docXmlTemplatePath = "/Users/lisw/work/work-project/workTppdf/";
}
DocToPdf.java
package org.example.util;
import com.aspose.words.Document;
import com.aspose.words.FontSettings;
import com.aspose.words.License;
import com.aspose.words.SaveFormat;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.util.Map;
import java.util.UUID;
/**
* @author lucas
* @program wtp-site
* @description word转pdf核心代码
* @createDate 2020-03-04 23:05:31
* 关注微信公众号"程序员无名",600GJava架构师网盘资料等你下载
* 这套代码我已经亲测可用了。若有特殊问题,请于公众号里随时与我联系。
**/
public class DocToPdf {
static String docTemplatePath = Constants.docXmlTemplatePath;
public static boolean getLicense() {
boolean result = false;
try {
InputStream is = new FileInputStream(docTemplatePath+Constants.licensePath);
License aposeLic = new License();
aposeLic.setLicense(is);
result = true;
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
public static String DocToPdf(Map<String,Object> params,String documentXmlName,String documentDocName) throws Exception {
try{
if (!getLicense()) { // 验证License 若不验证则转化出的pdf文档会有水印产生
return null;
}
String templateUUId = UUID.randomUUID().toString();
String baseUrl=System.getProperty("java.io.tmpdir")+"/";
String xml = baseUrl+templateUUId+".xml";
XmlToDocx.toDocx(documentXmlName,docTemplatePath+documentDocName,xml,baseUrl+templateUUId+".docx",params);
String docx = baseUrl+templateUUId+".docx";
String pdf = baseUrl+templateUUId+".pdf";
File file = new File(pdf); // 新建一个空白pdf文档
FileOutputStream os = new FileOutputStream(file);
Document doc = new Document(docx); // Address是将要被转化的word文档
String osName = isWindows();
String fonts [] = null;
/**
* 适配字体文件
*/
if(osName.equals("linux")){
fonts = new String[]{"/usr/share/fonts/chinese/","/usr/share/fonts/simsun/","/usr/share/fonts/black/","/usr/share/fonts/wingdings/"};
}else if(osName.equals("mac")){
fonts = new String[]{"/Users/fonts/chinese/","/Users/fonts/simsun/","/Users/fonts/black/","/Users/fonts/wingdings/"};
}
FontSettings.setFontsFolders(fonts, true);
doc.save(os, SaveFormat.PDF);// 全面支持DOC, DOCX, OOXML, RTF HTML, OpenDocument, PDF,
if(os!=null){
os.close();
}
delete(xml,docx);//删除文件
return pdf;
}catch (Exception e){
e.printStackTrace();
return null;
}
}
private static String isWindows() {
String osName = System.getProperties().getProperty("os.name").toUpperCase();
if(osName.indexOf("WINDOWS")!=-1){
return "windows";
}else if(osName.indexOf("MAC")!=-1){
return "mac";
}else{
return "linux";
}
}
public static void delete(String xmlPath,String wordPath){
File file = new File(xmlPath);
if(file.exists()){
file.delete();
}
File wordFile = new File(wordPath);
if(wordFile.exists()){
wordFile.delete();
}
}
}
XmlToDocx.java
package org.example.util;
import freemarker.template.TemplateException;
import java.io.*;
import java.util.Enumeration;
import java.util.Map;
import java.util.zip.ZipEntry;
import java.util.zip.ZipException;
import java.util.zip.ZipFile;
import java.util.zip.ZipOutputStream;
/**
* @author lucas
* @program wtp-site
* @description word动态填充数据核心类
* @createDate 2020-03-04 23:05:31
* 关注微信公众号"程序员无名",600GJava架构师网盘资料等你下载
* 这套代码我已经亲测可用了。若有特殊问题,请于公众号里随时与我联系。
**/
public class XmlToDocx {
/**
* @param xmlTemplate xml的文件名
* @param docxTemplate docx的路径和文件名
* @param xmlTemp 填充完数据的临时xml
* @param toFilePath 目标文件名
* @param map 需要动态传入的数据
* @throws IOException
*/
public static void toDocx(String xmlTemplate, String docxTemplate, String xmlTemp, String toFilePath, Map map) {
try {
// 1.map是动态传入的数据
// 这个地方不能使用FileWriter因为需要指定编码类型否则生成的Word文档会因为有无法识别的编码而无法打开
Writer w1 = new OutputStreamWriter(new FileOutputStream(xmlTemp), "utf-8");
// 2.把map中的数据动态由freemarker传给xml
XmlTplUtil.process(xmlTemplate, map, w1);
// 3.把填充完成的xml写入到docx中
XmlToDocx xtd = new XmlToDocx();
xtd.outDocx(new File(xmlTemp), docxTemplate, toFilePath);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* @param documentFile 动态生成数据的docunment.xml文件
* @param docxTemplate docx的模板
* @param toFilePath 需要导出的文件路径
* @throws ZipException
* @throws IOException
*/
public void outDocx(File documentFile, String docxTemplate, String toFilePath) throws ZipException, IOException {
try {
File docxFile = new File(docxTemplate);
ZipFile zipFile = new ZipFile(docxFile);
Enumeration<? extends ZipEntry> zipEntrys = zipFile.entries();
ZipOutputStream zipout = new ZipOutputStream(new FileOutputStream(toFilePath));
int len = -1;
byte[] buffer = new byte[1024];
while (zipEntrys.hasMoreElements()) {
ZipEntry next = zipEntrys.nextElement();
InputStream is = zipFile.getInputStream(next);
// 把输入流的文件传到输出流中 如果是word/document.xml由我们输入
zipout.putNextEntry(new ZipEntry(next.toString()));
if ("word/document.xml".equals(next.toString())) {
InputStream in = new FileInputStream(documentFile);
while ((len = in.read(buffer)) != -1) {
zipout.write(buffer, 0, len);
}
in.close();
} else {
while ((len = is.read(buffer)) != -1) {
zipout.write(buffer, 0, len);
}
is.close();
}
}
zipout.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
XmlTplUtil.java
package org.example.util;
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;
import java.io.File;
import java.io.IOException;
import java.io.Writer;
import java.util.Map;
/**
* @author lucas
* @program wtp-site
* @description word动态填充工具类
* @createDate 2020-03-04 23:05:31
* 关注微信公众号"程序员无名",600GJava架构师网盘资料等你下载
* 这套代码我已经亲测可用了。若有特殊问题,请于公众号里随时与我联系。
**/
public class XmlTplUtil {
private static XmlTplUtil tplm = null;
private Configuration cfg = null;
private XmlTplUtil() {
cfg = new Configuration();
try {
cfg.setDirectoryForTemplateLoading(new File(Constants.docXmlTemplatePath));
} catch (Exception e) {
e.printStackTrace();
}
}
private static Template getTemplate(String name) throws IOException {
if (tplm == null) {
tplm = new XmlTplUtil();
}
Template template = tplm.cfg.getTemplate(name,"utf-8");
return template;
}
/**
* @param templatefile 模板文件
* @param param 需要填充的内容
* @param out 填充完成输出的文件
* @throws IOException
* @throws TemplateException
*/
public static void process(String templatefile, Map param, Writer out) throws IOException, TemplateException {
// 获取模板
Template template = XmlTplUtil.getTemplate(templatefile);
template.setOutputEncoding("utf-8");
// 合并数据
template.process(param, out);
if (out != null) {
out.close();
}
}
}
App.java Main方法主类执行入口
package org.example;
import org.example.util.DocToPdf;
import java.util.HashMap;
import java.util.Map;
/**
* @author lucas
* @program wtp-site
* @description
* @createDate 2020-03-04 23:05:31
* 关注微信公众号"程序员无名",600GJava架构师网盘资料等你下载
* 这套代码我已经亲测可用了。若有特殊问题,请于公众号里随时与我联系。
**/
public class App
{
/**
* 注意事项
* 1:如果转换之后有乱码现象,极大的概率是你的word当中用了系统不支持的字体。
* 比如微软雅黑,你在本地windows上可能可以用,一旦你放到了服务器上面,Linux没有这个字体就会乱码。需要安装字体。
* @param args
* @throws Exception
*/
public static void main( String[] args ) throws Exception {
Map<String,Object> params = new HashMap<String,Object>();
params.put("name","Lucas");
String pdfPath = DocToPdf.DocToPdf(params, "document.xml", "template.docx");
//pdfPath便是最后在系统磁盘里生成的绝对路径地址了,后续业务如果需要,可以读取这个路径进行把文件上传到云空间里或者其他地方。
//如果上传到云空间了,记得把这个文件在系统磁盘删掉,避免占用系统磁盘。
//有问题,公众号找我。我等你
System.out.println("pdf已生成,路径是:"+pdfPath);
}
}
截止到此,代码已经贴完了。不想看,就下附件,小意思…
注意事项:
1:使用前需要准备三个文件,第一个word模板文件(word格式,代码中文件名叫做template.docx),第二个签名文件(xml格式。我会给你,直接用就行了,代码中叫做license.xml),第三个word模板的源代码文件(xml格式,代码中文件名叫做document.xml)
2:word模版文件:找到你需要生成的word源文件,名字改为template.docx(不改文件名,你就改代码,改成你的文件名字)
3:word源代码文件:这个就需要点东西才能生成了,首先把你的word源文件复制一份哈,毕竟代码还是要用到的。然后将复制后的文件,后缀名改为zip,然后解压zip,找到word文件夹里面的document.xml,这个就是word的源代码文件啦。
4:Constants.java里面需要配置一下,你这些源文件所在的文件夹路径(切记切记切记)。
我的template.docx是这样的
我的document.xml是这样的
生成生后的pdf是这样的
动态数据填充完成,并且成功转换成了pdf。结束了。有问题代码中找我哦…
以下是项目工程哈,有一个aspose的jar包在maven里面是没有的,我也附带给你们了哈。
完整实例代码请关注微信公众号:程序员无名。回复“word”就可以领取了哦。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。