前期准备
freemarker相关jar包
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
<version>2.3.23</version>
</dependency>
<dependency>
<groupId>org.xhtmlrenderer</groupId>
<artifactId>flying-saucer-pdf</artifactId>
<version>9.1.19</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.12.1</version>
</dependency>
docx4j相关jar包
<dependency>
<groupId>org.docx4j</groupId>
<artifactId>docx4j</artifactId>
<version>3.3.7</version>
</dependency>
<dependency>
<groupId>org.apache.xmlgraphics</groupId>
<artifactId>batik-util</artifactId>
<version>1.10</version>
</dependency>
<dependency>
<groupId>org.docx4j</groupId>
<artifactId>docx4j-export-fo</artifactId>
<version>3.3.6</version>
</dependency>
模板文件制作(后缀为.ftl)
1、在word文档中编写你想要的文档,并在相应位置设置变量
2、将word文档另存为xml格式
3、用编辑器检查XML中变量是否混乱(建议先格式化xml文件)
部分变量会被分割成字符串,例如:
这种情况直接删除变量中间的标签,修改后为:
将所有变量都检查完毕后,将xml文件直接重命名为后缀为 ftl 的文件
例:普通模板.xml ——>> 普通模板.ftl
将模板文件放置到resources包下
工具类
package zyxhj.utils;
import java.io.BufferedWriter;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStreamWriter;
import java.io.StringWriter;
import java.io.Writer;
import java.util.Map;
import org.docx4j.Docx4J;
import org.docx4j.convert.out.FOSettings;
import org.docx4j.fonts.IdentityPlusMapper;
import org.docx4j.fonts.Mapper;
import org.docx4j.fonts.PhysicalFonts;
import org.docx4j.openpackaging.packages.WordprocessingMLPackage;
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;
import freemarker.template.Version;
import sun.misc.BASE64Encoder;
/**
*
* @author JXians 模板导出word文档与PDF文档
*
*/
public class ExportOfficeUtils {
private static Configuration config = null;
static {
config = new Configuration(new Version("2.3.0"));
config.setClassForTemplateLoading(ExportOfficeUtils.class, "/template/");
config.setDefaultEncoding("UTF-8");
}
/**
* 获取配置对象
*
* @return
*/
public static Configuration getConfiguration() {
return config;
}
/**
* 合成数据与模板
*
* @param template 模板名称
* @param obj 模板需要填入的值
*/
public static String generate(String templateName, Object obj) throws IOException, TemplateException {
Configuration config = getConfiguration();
Template template = config.getTemplate(templateName, "utf-8");
StringWriter stringWriter = new StringWriter();
BufferedWriter writer = new BufferedWriter(stringWriter);
template.process(obj, writer);
String htmlStr = stringWriter.toString();
writer.flush();
writer.close();
return htmlStr;
}
/**
* 根据模板生成word文档
*
* @param templateName 模板名称
* @param dataMap 模板需求数据
* @param OutputFilePath 生成文件存放地址
*/
public static void generateWORD(String templateName, Map<String, Object> dataMap, String OutputFilePath) {
try {
// Configuration 用于读取ftl文件
Configuration configuration = getConfiguration();
// 输出文档路径及名称
File outFile = new File(OutputFilePath);
Template template = configuration.getTemplate(templateName, "utf-8");
Writer out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(outFile), "utf-8"), 10240);
template.process(dataMap, out);
out.close();
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 生成pdf文档
*
* @param templateName 模版文件
* @param obj 数据
* @param os 输出流
* @throws Exception
*/
public static void generatePDF(String templateName, Map<String, Object> dataMap, String PDFoutputFilePath)
throws Exception {
// 合并模板和数据模型 word doc os = ftl + obj
String generate = ExportOfficeUtils.generate(templateName, dataMap);
ByteArrayInputStream in = new ByteArrayInputStream(generate.getBytes());
// 文字处理对象
WordprocessingMLPackage wordMLPackage = WordprocessingMLPackage.load(in);
// wordMLPackage -> pdf os
FOSettings foSettings = Docx4J.createFOSettings();
Mapper fontMapper = new IdentityPlusMapper();
fontMapper.put("华文楷体", PhysicalFonts.get("STKaiti"));
fontMapper.put("隶书", PhysicalFonts.get("LiSu"));
fontMapper.put("宋体", PhysicalFonts.get("SimSun"));
fontMapper.put("微软雅黑", PhysicalFonts.get("Microsoft Yahei"));
fontMapper.put("黑体", PhysicalFonts.get("SimHei"));
fontMapper.put("楷体", PhysicalFonts.get("KaiTi"));
fontMapper.put("新宋体", PhysicalFonts.get("NSimSun"));
fontMapper.put("华文行楷", PhysicalFonts.get("STXingkai"));
fontMapper.put("华文仿宋", PhysicalFonts.get("STFangsong"));
fontMapper.put("仿宋", PhysicalFonts.get("FangSong"));
fontMapper.put("幼圆", PhysicalFonts.get("YouYuan"));
fontMapper.put("华文宋体", PhysicalFonts.get("STSong"));
fontMapper.put("华文中宋", PhysicalFonts.get("STZhongsong"));
fontMapper.put("等线", PhysicalFonts.get("SimSun"));
fontMapper.put("等线 Light", PhysicalFonts.get("SimSun"));
fontMapper.put("华文琥珀", PhysicalFonts.get("STHupo"));
fontMapper.put("华文隶书", PhysicalFonts.get("STLiti"));
fontMapper.put("华文新魏", PhysicalFonts.get("STXinwei"));
fontMapper.put("华文彩云", PhysicalFonts.get("STCaiyun"));
fontMapper.put("方正姚体", PhysicalFonts.get("FZYaoti"));
fontMapper.put("方正舒体", PhysicalFonts.get("FZShuTi"));
fontMapper.put("华文细黑", PhysicalFonts.get("STXihei"));
fontMapper.put("宋体扩展",PhysicalFonts.get("simsun-extB"));
fontMapper.put("仿宋_GB2312",PhysicalFonts.get("FangSong_GB2312"));
fontMapper.put("新細明體",PhysicalFonts.get("SimSun"));
//解决宋体(正文)和宋体(标题)的乱码问题
PhysicalFonts.put("PMingLiU", PhysicalFonts.get("SimSun"));
PhysicalFonts.put("新細明體", PhysicalFonts.get("SimSun"));
wordMLPackage.setFontMapper(fontMapper);
foSettings.setWmlPackage(wordMLPackage);
foSettings.setApacheFopMime("application/pdf");
Docx4J.toPDF(wordMLPackage, new FileOutputStream(PDFoutputFilePath));
}
/**
* 图片转码
*/
public static String getImageStr(String imgpath) {
InputStream in = null;
byte[] data = null;
try {
in = new FileInputStream(imgpath);
data = new byte[in.available()];
in.read(data);
in.close();
} catch (Exception e) {
e.printStackTrace();
}
BASE64Encoder encoder = new BASE64Encoder();
return encoder.encode(data);
}
}
主类
public static void main(String[] args) throws Exception {
Map<String, Object> map = new HashMap<String, Object>();
map.put("clientName", "JXians");
map.put("deputyApplicantName", "JXians_NAS");
map.put("address", "贵州遵义");
map.put("phone","18685644226");
map.put("Email", "zheng_xing_jiang@163.com");
map.put("onAddress", "贵州遵义");
map.put("onshore", " ");
map.put("offshore", "√");
map.put("intermediary", "中介代理人");
map.put("marn","NBS_0989");
map.put("visasType","移民签证");
map.put("contractMoney","1000.00");
map.put("advance", "500.00");
map.put("interEmail", "187263542@qq.com");
map.put("clientEmail", "27384922@qq.com");
map.put("interTime", new SimpleDateFormat("yyyy年MM月dd日").format(new Date()));
map.put("clientTime", new SimpleDateFormat("yyyy年MM月dd日").format(new Date()));
map.put("img", ExportOfficeUtils.getImageStr("C:/Users/Admin/Desktop/111.img"));
//模板文件名称
String templateName = "普通合同.ftl";
String PDFoutputFilePath = "C:/Users/Admin/Desktop/PDF_测试.pdf";
String WORDoutputFilePath = "C:/Users/Admin/Desktop/WORD_测试.doc";
ExportOfficeUtils.generatePDF(templateName, map, PDFoutputFilePath);
ExportOfficeUtils.generateWORD(templateName, map, WORDoutputFilePath);
}