使用iText5来导出pdf,具体操作步骤如下:
1、首先创建一个doc格式的word文档,转换为html格式
word模板转html链接地址
2、替换要填充的内容,把html文件后缀改为ftl并放在resources/templates路径下,最后将字体(任何字体都可以)放在resources/font路径下
3、最后就是java代码
<!-- https://mvnrepository.com/artifact/com.itextpdf/itextpdf -->
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itextpdf</artifactId>
<version>5.5.10</version>
</dependency>
<dependency>
<groupId>com.itextpdf.tool</groupId>
<artifactId>xmlworker</artifactId>
<version>5.5.13</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.jsoup/jsoup -->
<dependency>
<groupId>org.jsoup</groupId>
<artifactId>jsoup</artifactId>
<version>1.14.3</version>
</dependency>
package com.catxcloud.purchase.util;
import com.catxcloud.core.exception.GenericException;
import com.itextpdf.text.*;
import com.itextpdf.text.pdf.BaseFont;
import com.itextpdf.text.pdf.PdfWriter;
import com.itextpdf.tool.xml.XMLWorkerFontProvider;
import com.itextpdf.tool.xml.XMLWorkerHelper;
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateExceptionHandler;
import freemarker.template.Version;
import org.apache.commons.lang3.StringUtils;
import org.jsoup.Jsoup;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer;
import sun.misc.BASE64Decoder;
import java.io.*;
import java.nio.charset.Charset;
import java.util.Iterator;
/**
* @packageName: com.emoon.utils
* @className: PdfTool
* @description: pdf工具类
* @version: 1.0.0
*/
public class PdfTool {
private static final Logger LOGGER = LoggerFactory.getLogger(PdfTool.class);
/**
* 默认的编码为utf-8
*/
private static final String DEFAULT_ENCODING = "utf-8";
/**
* 参数错误码
*/
private static final Integer PARAM_ERROR_CODE = 500001;
/**
* 参数错误描述
*/
private static final String PARAM_ERROR_DESC = "参数有误!";
/**
* 生成html错误码
*/
private static final Integer HTML_CREATE_ERROR_CODE = 500002;
/**
* html生成失败描述
*/
private static final String HTML_CREATE_ERROR_DESC = "html生成失败";
/**
* html转pdf失败错误码
*/
private static final Integer PARSE_HTML_TO_PDF_ERROR_CODE = 500003;
/**
* html转pdf失败描述
*/
private static final String PARSE_HTML_TO_PDF_ERROR_DESC = "html转pdf失败";
/**
* PDF生成失败错误码
*/
private static final Integer PDF_CREATE_ERROR_CODE = 500004;
/**
* PDF生成失败描述
*/
private static final String PDF_CREATE_ERROR_DESC = "PDF生成失败";
/**
* word转pdf失败错误码
*/
private static final Integer PARSE_WORD_TO_PDF_ERROR_CODE = 500005;
/**
* word转pdf失败描述
*/
private static final String PARSE_WORD_TO_PDF_ERROR_DESC = "word转pdf失败";
/**
* 获取pdf签章hash失败错误码
*/
private static final Integer GET_SIGN_HASH_ERROR_CODE = 500005;
/**
* 获取pdf签章hash失败的描述
*/
private static final String GET_SIGN_HASH_ERROR_DESC = "获取pdf签章hash失败";
/**
* description:创建Configuration配置的方法
* @param version 版本号
* @param encoding 编码
* @param ftlOrXmlParentPath ftl或者xml文件父路径地址
* @param pathIsAP ftl或者xml文件父路径地址是否是绝对路径,true-是,false-否
* @return freemarker.template.Configuration Configuration配置对象
*/
private static Configuration getConfiguration(Version version, String encoding,
String ftlOrXmlParentPath, boolean pathIsAP) throws IOException {
//Configuration 用于读取ftl文件
Configuration configuration = new Configuration(version);
configuration.setDefaultEncoding(encoding);
/**
* 两种指定ftl文件所在目录路径的方式,注意这两种方式都是
* 指定ftl文件所在目录的路径,而不是ftl文件的路径
*/
//指定路径的第一种方式(根据某个类的相对路径指定)
// configuration.setClassForTemplateLoading(this.getClass(), "");
//指定路径的第二种方式
// configuration.setDirectoryForTemplateLoading(new File(ftlOrXmlParentPath));
//如果是绝对路径
if (pathIsAP) {
configuration.setDirectoryForTemplateLoading(new File(ftlOrXmlParentPath));
} else {
FreeMarkerConfigurer freeMarkerConfigurer = SpringBootBeanUtil.getBean(FreeMarkerConfigurer.class);
configuration = freeMarkerConfigurer.getConfiguration();
if (StringUtils.isNotBlank(ftlOrXmlParentPath)) {
StringBuffer basePackagePath = new StringBuffer();
//加载指定的模版文件夹
if (ftlOrXmlParentPath.startsWith("/")) {
if (ftlOrXmlParentPath.endsWith("/")) {
basePackagePath.append(ftlOrXmlParentPath);
} else {
basePackagePath.append(ftlOrXmlParentPath);
basePackagePath.append("/");
}
} else {
basePackagePath.append("/");
if (ftlOrXmlParentPath.endsWith("/")) {
basePackagePath.append(ftlOrXmlParentPath);
} else {
basePackagePath.append(ftlOrXmlParentPath);
basePackagePath.append("/");
}
}
configuration.setClassForTemplateLoading(PdfTool.class, basePackagePath.toString());
}
}
return configuration;
}
/**
* description: 根据html修改的ftl模版填入数据生成html的方法(如果模版是word,转成html编辑成ftl模版即可)
* @param dataModel 数据模型
* @param ftlParentPath ftl文件的父路径,相对路径或者绝对路径,相对路径时指:相对classpath的路径,
* 可为空,当表示绝对父路径时必填,相对父路径时可不填,不填默认加载配置文件中的:
* spring.freemarker.template-loader-path=classpath:/templates/ 的配置
* @param ftlParentPathIsAP ftl文件的父路径是否是绝对路径,true--是,false-否
* @param ftlTemplateName ftl文件名称,需以.ftl结尾
* @param outputStream html文件输出流
* @param encoding 编码,可为空,默认为:utf-8
* @param versionCode 版本号,可为空,默认为:2.3.23
* @return boolean 生成html是否成功,true为是,false为否
*/
public static synchronized boolean createHtmlFileByFreemarker(Object dataModel, String ftlParentPath,
boolean ftlParentPathIsAP, String ftlTemplateName,
OutputStream outputStream, String encoding,
String versionCode) throws GenericException {
Version version = null;
if (StringUtils.isBlank(encoding)) {
encoding = DEFAULT_ENCODING;
}
if (StringUtils.isBlank(versionCode)) {
//默认为2.3.23
version = Configuration.VERSION_2_3_23;
} else {
version = new Version(versionCode);
}
if (dataModel == null) {
LOGGER.error("[根据ftl生成html]数据为空");
throw new GenericException(PARAM_ERROR_CODE, PARAM_ERROR_DESC);
}
if (StringUtils.isBlank(ftlTemplateName)) {
LOGGER.error("[根据ftl生成html]ftl模版的名字(ftlTemplateName)存在空的参数");
throw new GenericException(PARAM_ERROR_CODE, PARAM_ERROR_DESC);
}
//如果是绝对路径则ftl模版文件的父路径必填
if (ftlParentPathIsAP && StringUtils.isBlank(ftlParentPath)) {
LOGGER.error("[根据ftl生成html]ftl模版文件的父路径(ftlParentPath)不能为空");
throw new GenericException(PARAM_ERROR_CODE, PARAM_ERROR_DESC);
}
//如果ftl模版名字不是以.ftl结尾的
if (!ftlTemplateName.endsWith(".ftl")) {
LOGGER.error("[根据ftl生成html] ftl模版的名字(ftlTemplateName)名称有误,不是.ftl后缀");
throw new GenericException(PARAM_ERROR_CODE, PARAM_ERROR_DESC);
}
Writer out = null;
try {
Configuration configuration = getConfiguration(version, encoding, ftlParentPath, ftlParentPathIsAP);
//以指定编码读取ftl文件
Template template = configuration.getTemplate(ftlTemplateName, encoding);
out = new BufferedWriter(new OutputStreamWriter(outputStream, encoding), 10240);
template.process(dataModel, out);
//LOGGER.info("[根据ftl生成html]生成html成功");
return true;
} catch (Exception e) {
LOGGER.error("[根据ftl生成html]生成html出错", e);
throw new GenericException(HTML_CREATE_ERROR_CODE, HTML_CREATE_ERROR_DESC);
} finally {
try {
if (outputStream != null) {
outputStream.flush();
outputStream.close();
}
if (out != null) {
out.flush();
out.close();
}
} catch (Exception e) {
LOGGER.error("", e);
throw new GenericException(HTML_CREATE_ERROR_CODE, HTML_CREATE_ERROR_DESC);
}
}
}
/**
* description: 根据html修改的ftl模版填入数据生成html的方法(如果模版是word,转成html编辑成ftl模版即可)
* @param dataModel 数据模型
* @param ftlParentPath ftl文件的父路径,相对路径或者绝对路径,相对路径时指:相对classpath的路径,
* 可为空,当表示绝对父路径时必填,相对父路径时可不填,不填默认加载配置文件中的:
* spring.freemarker.template-loader-path=classpath:/templates/ 的配置
* @param ftlParentPathIsAP ftl文件的父路径是否是绝对路径,true--是,false-否
* @param ftlTemplateName ftl文件名称,需以.ftl结尾
* @param encoding 编码,可为空,默认为:utf-8
* @param versionCode 版本号,可为空,默认为:2.3.23
* @return java.lang.String 直接返回生成的html字符串
*/
public static synchronized String createHtmlFileByFreemarker(Object dataModel, String ftlParentPath,
boolean ftlParentPathIsAP, String ftlTemplateName,
String encoding, String versionCode) throws GenericException {
Version version = null;
if (StringUtils.isBlank(encoding)) {
encoding = DEFAULT_ENCODING;
}
if (StringUtils.isBlank(versionCode)) {
//默认为2.3.23
version = Configuration.VERSION_2_3_23;
} else {
version = new Version(versionCode);
}
if (dataModel == null) {
LOGGER.error("[根据ftl生成html]数据为空");
throw new GenericException(PARAM_ERROR_CODE, PARAM_ERROR_DESC);
}
if (StringUtils.isBlank(ftlTemplateName)) {
LOGGER.error("[根据ftl生成html]ftl模版的名字(ftlTemplateName)存在空的参数");
throw new GenericException(PARAM_ERROR_CODE, PARAM_ERROR_DESC);
}
//如果是绝对路径则ftl模版文件的父路径必填
if (ftlParentPathIsAP && StringUtils.isBlank(ftlParentPath)) {
LOGGER.error("[根据ftl生成html]ftl模版文件的父路径(ftlParentPath)不能为空");
throw new GenericException(PARAM_ERROR_CODE, PARAM_ERROR_DESC);
}
//如果ftl模版名字不是以.ftl结尾的
if (!ftlTemplateName.endsWith(".ftl")) {
LOGGER.error("[根据ftl生成html] ftl模版的名字(ftlTemplateName)名称有误,不是.ftl后缀");
throw new GenericException(PARAM_ERROR_CODE, PARAM_ERROR_DESC);
}
Writer out = null;
try {
Configuration configuration = getConfiguration(version, encoding, ftlParentPath, ftlParentPathIsAP);
configuration.setTemplateExceptionHandler(TemplateExceptionHandler.RETHROW_HANDLER);
configuration.setLogTemplateExceptions(false);
//以指定编码读取ftl文件
Template template = configuration.getTemplate(ftlTemplateName, encoding);
out = new StringWriter();
template.process(dataModel, out);
//LOGGER.info("[根据ftl生成html]生成html成功");
out.flush();
return out.toString();
} catch (Exception e) {
LOGGER.error("[根据ftl生成html]生成html出错", e);
throw new GenericException(HTML_CREATE_ERROR_CODE, HTML_CREATE_ERROR_DESC);
} finally {
try {
if (out != null) {
out.close();
}
} catch (Exception e) {
LOGGER.error("", e);
throw new GenericException(HTML_CREATE_ERROR_CODE, HTML_CREATE_ERROR_DESC);
}
}
}
/**
* description: html转化成pdf的方法
* @param pdfOutputStream pdf输出流
* @param htmlInputStream html输入流
* @param encoding 编码,可为空,默认为:UTF-8
* @return void 无
*/
public static synchronized void parseHtml2Pdf(OutputStream pdfOutputStream, InputStream htmlInputStream,
String encoding) throws GenericException {
if (StringUtils.isBlank(encoding)) {
encoding = DEFAULT_ENCODING;
}
//html的内容
StringBuffer htmlContent = new StringBuffer();
BufferedReader br = null;
PdfWriter writer = null;
try {
br = new BufferedReader(new InputStreamReader(htmlInputStream, encoding));
String line;
while ((line = br.readLine()) != null) {
htmlContent.append(line);
}
Document document = new Document();
writer = PdfWriter.getInstance(document, pdfOutputStream);
document.open();
if ("linux".equals(getCurrentOperatingSystem())) {
XMLWorkerHelper.getInstance().parseXHtml(writer, document,
new ByteArrayInputStream(htmlContent.toString().getBytes(encoding)), null,
Charset.forName(encoding), new ChinessFontProvider());
} else {
XMLWorkerHelper.getInstance().parseXHtml(writer, document,
new ByteArrayInputStream(htmlContent.toString().getBytes(encoding)),
Charset.forName(encoding));
}
document.close();
//LOGGER.info("[html转pdf]html转pdf成功");
} catch (Exception e) {
LOGGER.error("[html转pdf]html转pdf出错", e);
throw new GenericException(PARSE_HTML_TO_PDF_ERROR_CODE, PARSE_HTML_TO_PDF_ERROR_DESC);
} finally {
try {
if (br != null) {
br.close();
}
if (htmlInputStream != null) {
htmlInputStream.close();
}
if (pdfOutputStream != null) {
pdfOutputStream.flush();
pdfOutputStream.close();
}
if (writer != null) {
writer.flush();
writer.close();
}
} catch (Exception e) {
LOGGER.error("[html转pdf]html转pdf出错", e);
throw new GenericException(PARSE_HTML_TO_PDF_ERROR_CODE, PARSE_HTML_TO_PDF_ERROR_DESC);
}
}
}
/**
* description: html转化成pdf的方法
* @param pdfOutputStream pdf输出流
* @param htmlContent html的内容
* @param encoding 编码,可为空,默认为:UTF-8
* @return void 无
*/
public static synchronized void parseHtml2Pdf(OutputStream pdfOutputStream, String htmlContent,
String encoding) throws GenericException {
if (StringUtils.isBlank(encoding)) {
encoding = DEFAULT_ENCODING;
}
if (StringUtils.isBlank(htmlContent)) {
LOGGER.error("[html转pdf]html内容为空");
throw new GenericException(PARSE_HTML_TO_PDF_ERROR_CODE, PARSE_HTML_TO_PDF_ERROR_DESC);
}
// //LOGGER.info("[html转pdf]html内容为:" + htmlContent);
PdfWriter writer = null;
try {
Document document = new Document();
writer = PdfWriter.getInstance(document, pdfOutputStream);
document.open();
if ("linux".equals(getCurrentOperatingSystem())) {
XMLWorkerHelper.getInstance().parseXHtml(writer, document,
new ByteArrayInputStream(htmlContent.getBytes(encoding)), null,
Charset.forName(encoding), new ChinessFontProvider());
} else {
XMLWorkerHelper.getInstance().parseXHtml(writer, document,
new ByteArrayInputStream(htmlContent.getBytes(encoding)),
Charset.forName(encoding));
}
document.close();
//LOGGER.info("[html转pdf]html转pdf成功");
} catch (Exception e) {
LOGGER.error("[html转pdf]html转pdf出错", e);
throw new GenericException(PARSE_HTML_TO_PDF_ERROR_CODE, PARSE_HTML_TO_PDF_ERROR_DESC);
} finally {
try {
if (pdfOutputStream != null) {
pdfOutputStream.flush();
pdfOutputStream.close();
}
} catch (Exception e) {
LOGGER.error("[html转pdf]html转pdf出错", e);
throw new GenericException(PARSE_HTML_TO_PDF_ERROR_CODE, PARSE_HTML_TO_PDF_ERROR_DESC);
}
}
}
/**
* description: 获取当前的操作系统的方法
* @param
* @return java.lang.String 操作系统名称
*/
private static synchronized String getCurrentOperatingSystem() {
String os = System.getProperty("os.name").toLowerCase();
//LOGGER.info("---------当前操作系统是-----------" + os);
return os;
}
/**
* description: 使用Freemarker使用html的ftl模版生成pdf的方法,ftl模版由html改名而来
* 实现方式为通过freemaker根据ftl模版生成html文件,再将html转化为pdf,中间有临时文件html
* @param dataModel 装入ftl模版的数据
* @param htmlFtlParentPath html修改的ftl文件父路径,相对路径或者绝对路径,相对路径时指:相对classpath的路径
* 可为空,当表示绝对父路径时必填,相对父路径时可不填,不填默认加载配置文件中的:
* spring.freemarker.template-loader-path=classpath:/templates/ 的配置
* @param htmlFtlParentPathIsAP ftl文件的父路径是否是绝对路径,true--是,false-否
* @param htmlFtlTemplateName ftl文件名称,需以.ftl结尾
* @param htmlFileTempPath 临时html文件存放的位置,需绝对路径,且以.html结尾,可为空,为空时不经过html中间文件直接生成pdf
* @param pdfOutputStream 生成的pdf输出流
* @param encoding 编码,可为空,默认为:utf-8
* @param versionCode 版本号,可为空,默认为:2.3.23
* @date: 2020/11/15 21:39
*/
public static synchronized void createPdfByFreemarker(Object dataModel, String htmlFtlParentPath,
boolean htmlFtlParentPathIsAP, String htmlFtlTemplateName,
String htmlFileTempPath, OutputStream pdfOutputStream,
String encoding, String versionCode) throws GenericException {
//生成的临时html文件
File tempHtmlFile = null;
try {
//如果html临时文件的路径为空则直接生成pdf文件
if (StringUtils.isBlank(htmlFileTempPath)) {
//=============== 直接生成pdf,不生成中间html节省服务器空间=============
String htmlContent = PdfTool.createHtmlFileByFreemarker(dataModel, htmlFtlParentPath,
htmlFtlParentPathIsAP, htmlFtlTemplateName, encoding, versionCode);
PdfTool.parseHtml2Pdf(pdfOutputStream, htmlContent, encoding);
} else {
//处理临时文件路径
if (!htmlFileTempPath.toLowerCase().endsWith(".html")) {
LOGGER.error("[ftl生成pdf]html临时文件路径不是以.html结尾");
throw new GenericException(PARAM_ERROR_CODE, PARAM_ERROR_DESC);
}
//==============方便调试,生成html中间文件再生成pdf========================
//获取html临时文件的文件夹,如果不存在则创建
String htmlDirsPath = StringUtils.substringBeforeLast(htmlFileTempPath, "/");
File htmlDirs = new File(htmlDirsPath);
if (!htmlDirs.exists()) {
htmlDirs.mkdirs();
}
tempHtmlFile = new File(htmlFileTempPath);
FileOutputStream htmlFileOutputStream = new FileOutputStream(tempHtmlFile);
//先生成html临时文件
boolean createHtmlSuccess = PdfTool.createHtmlFileByFreemarker(dataModel, htmlFtlParentPath,
htmlFtlParentPathIsAP, htmlFtlTemplateName, htmlFileOutputStream, encoding, versionCode);
//如果html生成成功则读取html
if (createHtmlSuccess) {
FileInputStream htmlFileInputStream = new FileInputStream(tempHtmlFile);
//再将html文件转化为pdf
PdfTool.parseHtml2Pdf(pdfOutputStream, htmlFileInputStream, encoding);
//LOGGER.info("[ftl生成pdf]生成pdf成功");
} else {
LOGGER.error("[ftl生成pdf]生成pdf失败");
throw new GenericException(PDF_CREATE_ERROR_CODE, PDF_CREATE_ERROR_DESC);
}
}
} catch (GenericException e) {
throw e;
} catch (Exception e) {
LOGGER.error("[ftl生成pdf]生成pdf出错", e);
throw new GenericException(PDF_CREATE_ERROR_CODE, PDF_CREATE_ERROR_DESC);
} finally {
//删除临时文件
if (tempHtmlFile != null && tempHtmlFile.exists()) {
// tempHtmlFile.delete();
}
}
}
/**
* description: 将word转化为pdf的方法,支持.doc和.docx格式的word,实现方式为先将word转化为html,再将html转化为pdf
* @param wordInputStream word输入流
* @param pdfOutputStream pdf输出流
* @param docName word名称,需带后缀
* @param imageFolderPath word中如果有图片的话,图片所在的文件夹路径,绝对路径
* @param htmlFileTempPath html临时文件存储的路径,绝对路径,且以.html结尾
* @param encoding 编码,可为空,默认为:utf-8
* @return void 无
*/
public static synchronized void word2Pdf(InputStream wordInputStream, OutputStream pdfOutputStream,
String docName, String imageFolderPath, String htmlFileTempPath,
String encoding) throws GenericException {
if (StringUtils.isBlank(htmlFileTempPath)) {
LOGGER.error("[word转pdf]html临时文件路径为空");
throw new GenericException(PARAM_ERROR_CODE, PARAM_ERROR_DESC);
}
//处理临时文件路径
if (StringUtils.isNotBlank(htmlFileTempPath) && !htmlFileTempPath.toLowerCase().endsWith(".html")) {
LOGGER.error("[word转pdf]html临时文件路径不是以.html结尾");
throw new GenericException(PARAM_ERROR_CODE, PARAM_ERROR_DESC);
}
if (StringUtils.isBlank(encoding)) {
encoding = DEFAULT_ENCODING;
}
//生成的临时html文件
File tempHtmlFile = null;
FileOutputStream htmlOutputStream = null;
try {
//获取html临时文件的文件夹,如果不存在则创建
String htmlDirsPath = StringUtils.substringBeforeLast(htmlFileTempPath, "/");
File htmlDirs = new File(htmlDirsPath);
if (!htmlDirs.exists()) {
htmlDirs.mkdirs();
}
tempHtmlFile = new File(htmlFileTempPath);
htmlOutputStream = new FileOutputStream(tempHtmlFile);
//先将word转为html
boolean htmlSuccess = WordTool.word2Html(wordInputStream, htmlOutputStream, docName, imageFolderPath);
//如果生成html成功则读取html文件
if (htmlSuccess) {
//由于生成的html mate未闭合,手动对mate进行闭合做以下处理
org.jsoup.nodes.Document document = Jsoup.parse(tempHtmlFile, encoding);
//获取mate标签
org.jsoup.select.Elements elements = document.getElementsByTag("META");
if (elements != null) {
Iterator<org.jsoup.nodes.Element> it = elements.iterator();
while (it != null && it.hasNext()) {
//处理meta标签,进行闭合
it.next().appendText(" ");
}
}
//===============可以重新写入新的html,再读取,方便调试查看==========================
/* htmlOutputStream = new FileOutputStream(tempHtmlFile);
//重新写入html文件
htmlOutputStream.write(document.html().getBytes(encoding));
htmlOutputStream.flush();
htmlOutputStream.close();
htmlOutputStream = null;
//再读取新的html文件
FileInputStream htmlInputStream = new FileInputStream(tempHtmlFile);
//再将生成的html转化为pdf
PdfTool.parseHtml2Pdf(pdfOutputStream, htmlInputStream, encoding);*/
//====================也可以直接使用jsoup处理后的html生成pdf===================
//直接将html内容转化为pdf
PdfTool.parseHtml2Pdf(pdfOutputStream, document.html(), encoding);
//LOGGER.info("[word转pdf]word转pdf成功");
} else {
LOGGER.error("[word转pdf]word转pdf失败");
throw new GenericException(PARSE_WORD_TO_PDF_ERROR_CODE, PARSE_WORD_TO_PDF_ERROR_DESC);
}
} catch (GenericException e) {
throw e;
} catch (Exception e) {
LOGGER.error("[word转pdf]word转pdf出错", e);
throw new GenericException(PARSE_WORD_TO_PDF_ERROR_CODE, PARSE_WORD_TO_PDF_ERROR_DESC);
} finally {
try {
if (htmlOutputStream != null) {
htmlOutputStream.flush();
htmlOutputStream.close();
}
} catch (Exception e) {
}
//删除html临时文件
if (tempHtmlFile != null && tempHtmlFile.exists()) {
tempHtmlFile.delete();
}
}
}
/**
* @packageName: com.emoon.utils
* @className: ChinessFontProvider
* @description: itext加载中文的类
* @version: 1.0.0
*/
static class ChinessFontProvider extends XMLWorkerFontProvider {
private static final Logger LOGGER = LoggerFactory.getLogger(ChinessFontProvider.class);
//重写获取字体的方法
@Override
public Font getFont(String fontname, String encoding, boolean embedded, float size, int style,
BaseColor color) {
BaseFont bf = null;
try {
//加载resources文件夹下的font下的字体文件
bf = BaseFont.createFont("font/simsun.ttf", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
} catch (Exception e) {
LOGGER.error("[加载中文]加载中文出错", e);
}
Font font = new Font(bf, size, style, color);
font.setColor(color);
return font;
}
}
}
@Value("${template.ftlTemplateName}")
private String ftlTemplateName;
@SneakyThrows
@Override
public void download(String id, HttpServletRequest request, HttpServletResponse response) {
Map<String, Object> hyData = cgzbCghyMapper.getHyData(id);
if (hyData == null || hyData.size() == 0) {
throw new GenericException(purchaseCodeEnum.HY_IS_NULL.getCode(), purchaseCodeEnum.HY_IS_NULL.getMsg());
}
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm");
SimpleDateFormat timeFormat = new SimpleDateFormat("HH:mm");
String time = null;
try {
Date time1 = format.parse(hyData.get("time").toString());;
} catch (ParseException e) {
e.printStackTrace();
}
Map<String, Object> dataMap = new HashMap<>(16);
dataMap.put("qdsj", time);
dataMap.put("hydd", hyData.get("address"));
dataMap.put("hynr", hyData.get("content"));
dataMap.put("chry", hyData.get("chry"));
dataMap.put("zcbm", hyData.get("hyzcbm"));
String newPdfName = "会议签到单.pdf";
OutputStream outputStream = null;
//设置要下载的文件的名称
String s;
try {
s = fileService.encodeChineseDownloadFileName(request, newPdfName);
response.setHeader("Content-Disposition", "inline;fileName=" + s);
//设置MIME类型
response.setContentType("application/pdf;charset=UTF-8");
outputStream = response.getOutputStream();
} catch (Exception e) {
e.printStackTrace();
}
PdfTool.createPdfByFreemarker(dataMap, null, false,
this.ftlTemplateName, null, response.getOutputStream(), null,
null);
}
/**
* description:对文件流输出下载的中文文件名进行编码 屏蔽各种浏览器版本的差异性
* @param request http请求
* @param fileName 文件名称
* @return java.lang.String 新的zip名称
*/
public String encodeChineseDownloadFileName(HttpServletRequest request, String fileName) throws Exception {
String newFileName = null;
String agent = request.getHeader("USER-AGENT");
if (null != agent) {
if (-1 != agent.indexOf("Firefox")) {//Firefox
newFileName =
"=?UTF-8?B?" + (new String(org.apache.commons.codec.binary.Base64.encodeBase64(fileName.getBytes(
"UTF-8")))) + "?=";
} else if (-1 != agent.indexOf("Chrome")) {//Chrome
newFileName = new String(fileName.getBytes(), "ISO8859-1");
} else {//IE7+
newFileName = java.net.URLEncoder.encode(fileName, "UTF-8");
newFileName = newFileName.replace("+", "%20");
}
} else {
newFileName = fileName;
}
return newFileName;
}