import com.itextpdf.text.Document;
import com.itextpdf.text.PageSize;
import com.itextpdf.text.pdf.PdfWriter;
import com.itextpdf.tool.xml.XMLWorkerHelper;
import freemarker.template.Configuration;
import freemarker.template.Template;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.Map;
/**
* @author X-MD
* @version 1.0.0
* @Description 根据HTML魔板导出PDF
* @createTime 2022年01月17日 16:47:00
*/
public class PdfHtmlUtil {
private static Configuration freemarkerCfg;
static {
//freemarker的模板目录
try {
freemarkerCfg = new Configuration(Configuration.VERSION_2_3_28);
String templatePath = PdfHtmlUtil.class.getResource("/").getPath() + "/templates";
freemarkerCfg.setDirectoryForTemplateLoading(new File(templatePath));
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 预览PDF
*
* @param response
* @param data 数据
* @param template templates文件下的HTML文件名称(test.html)
*/
public static void createHtmlPdfPreview(HttpServletResponse response, String filename, Map<String, Object> data, String template) {
try (
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
) {
createHtmlPdf(outputStream, data, template);
// inline(默认)当前页面打开;attachment 下载到本地=
response.setContentType("application/pdf");
response.addHeader("Content-Disposition", "inline;filename=" + URLEncoder.encode(filename, "UTF-8") + ".pdf");
OutputStream stream = response.getOutputStream();
outputStream.writeTo(stream);
outputStream.flush();
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 下载PDF
*
* @param response
* @param data 数据
* @param template templates文件下的HTML文件名称(test.html)
*/
public static void createHtmlPdfDownload(HttpServletResponse response, String filename, Map<String, Object> data, String template) {
try (
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
) {
createHtmlPdf(outputStream, data, template);
response.setContentType("application/x-download");
response.addHeader("Content-Disposition", "inline;filename=" + URLEncoder.encode(filename, "UTF-8") + ".pdf");
OutputStream stream = response.getOutputStream();
outputStream.writeTo(stream);
outputStream.flush();
} catch (Exception e) {
e.printStackTrace();
}
}
private static void createHtmlPdf(ByteArrayOutputStream outputStream, Map<String, Object> data, String template) {
String content = freeMarkerRender(data, template);
Document document = new Document(PageSize.A4);
try (
ByteArrayInputStream stream = new ByteArrayInputStream(content.getBytes(StandardCharsets.UTF_8))
) {
PdfWriter pdfWriter = PdfWriter.getInstance(document, outputStream);
document.open();
XMLWorkerHelper xmlWorkerHelper = XMLWorkerHelper.getInstance();
xmlWorkerHelper.parseXHtml(pdfWriter, document, stream, StandardCharsets.UTF_8, new AsianFontProvider());
} catch (Exception e) {
e.printStackTrace();
} finally {
document.close();
}
}
/**
* freemarker渲染html
*/
private static <T> String freeMarkerRender(T data, String htmlTmp) {
try (
Writer out = new StringWriter()
) {
// 获取模板,并设置编码方式
Template template = freemarkerCfg.getTemplate(htmlTmp);
// 合并数据模型与模板,将合并后的数据和模板写入到流中,这里使用的字符流
template.process(data, out);
out.flush();
return out.toString();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}