iText + freemarker转成pdf字节流打印 无需生成本地pdf文件
- 本项目为springboot项目 引入依赖
<!-- 模板引擎 代码生成 -->
<dependency>
<groupId>org.apache.velocity</groupId>
<artifactId>velocity-engine-core</artifactId>
<version>${velocity-engine.version}</version>
</dependency>
<!-- freemarker 模板引擎 -->
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
<version>${freemarker.version}</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.itextpdf/itextpdf 对itext的支持-->
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itextpdf</artifactId>
<version>5.5.11</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.itextpdf.tool/xmlworker -->
<dependency>
<groupId>com.itextpdf.tool</groupId>
<artifactId>xmlworker</artifactId>
<version>5.5.11</version>
</dependency>
2.操作工具类
private static final String FONT = "font/simhei.ttf";
/**
* pdf 字节流响应
*
* @param response
* @param result pdf字节输出流 字符串
* @throws IOException
*/
public static void pdfResponse(HttpServletResponse response, String result) throws IOException {
//如果跨域需设置解码
result = URLDecoder.decode(result, "ISO-8859-1");
ByteArrayInputStream inStream = new ByteArrayInputStream(result.getBytes("ISO-8859-1"));
// 循环取出流中的数据
byte[] b = new byte[2048];
int len;
try {
while ((len = inStream.read(b)) > 0) {
response.getOutputStream().write(b, 0, len);
}
inStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 生成pdf
*
* @param content freemarker 渲染后输出的文本
* @return
* @throws IOException
* @throws DocumentException
*/
public static String createPdf(String content) throws IOException, DocumentException {
Rectangle rectPageSize = new Rectangle(PageSize.A4);
// step 1
Document document = new Document(rectPageSize);
// step 2
//构建字节输出流
ByteArrayOutputStream baos = new ByteArrayOutputStream();
PdfWriter writer = PdfWriter.getInstance(document, baos);
// step 3
document.open();
// step 4
XMLWorkerFontProvider fontImp = new XMLWorkerFontProvider(XMLWorkerFontProvider.DONTLOOKFORFONTS);
fontImp.register(FONT);
XMLWorkerHelper.getInstance().parseXHtml(writer, document, new ByteArrayInputStream(content.getBytes()), null, Charset.forName("UTF-8"), fontImp);
// step 5
document.close();
baos.close();
//转字符串设置编码
String result = new String(baos.toByteArray(), "ISO-8859-1");
return URLEncoder.encode(result, "ISO-8859-1");//如果跨域需设置编码
}
/**
* 生成pdf
* @param content freemarker 渲染后输出的文本
* @param dest 生成pdf所在文件位置
* @throws IOException
* @throws DocumentException
*/
public void createPdf(String content, String dest) throws IOException, DocumentException {
Rectangle rectPageSize = new Rectangle(PageSize.A4);
Document document = new Document(rectPageSize);
PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(dest));
document.open();
XMLWorkerFontProvider fontImp = new XMLWorkerFontProvider(XMLWorkerFontProvider.DONTLOOKFORFONTS);
fontImp.register(FONT);
XMLWorkerHelper.getInstance().parseXHtml(writer, document, new ByteArrayInputStream(content.getBytes()), null, Charset.forName("UTF-8"), fontImp);
document.close();
}
/**
* freemarker 渲染 html
*
* @param data 数据 Map<String,Object>
* @param htmlTmp 模板名称
* @return
*/
public static String freeMarkerRender(Map<String, Object> data, String htmlTmp) {
Configuration freemarkerCfg = new Configuration();
//freemarker的模板目录 "/freemakertemplate/"
try {
freemarkerCfg.setDirectoryForTemplateLoading(new File(FileUtil.class.getResource("/").getPath() + "/freemakertemplate"));
} catch (IOException e) {
e.printStackTrace();
}
Writer out = new StringWriter();
try {
// 获取模板,并设置编码方式
Template template = freemarkerCfg.getTemplate(htmlTmp);
template.setEncoding("UTF-8");
// 合并数据模型与模板
//将合并后的数据和模板写入到流中,这里使用的字符流
template.process(data, out);
out.flush();
return out.toString();
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
out.close();
} catch (IOException ex) {
ex.printStackTrace();
}
}
return null;
}
/**
* pdf 打印
* @param data
* @param freemarkertemplate
* @param response
*/
public static void printPdf(Map<String, Object> data, String freemarkertemplate, HttpServletResponse response) {
//freemarker 模板渲染
String content = freeMarkerRender(data,freemarkertemplate);
try {
String result = createPdf(content);
pdfResponse(response,result);
} catch (IOException e) {
e.printStackTrace();
} catch (DocumentException e) {
e.printStackTrace();
}
}
3.controller层调用 构造data
4.模板 以及字体目录结构