一、环境:
1、freemarker 2.3.21版本;
2、itext 2.1.7版本;
3、flying-saucer-core 11.0.7版本;
二、实现代码:
/**
* Copyright (c) 2006-2016 Hzins Ltd. All Rights Reserved.
*
* This code is the confidential and proprietary information of
* Hzins. You shall not disclose such Confidential Information
* and shall use it only in accordance with the terms of the agreements
* you entered into with Hzins,http://www.hzins.com.
*
*/
package com.hzins.utils.pdf;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.StringWriter;
import java.util.Map;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.w3c.dom.Document;
import org.xhtmlrenderer.pdf.ITextFontResolver;
import org.xhtmlrenderer.pdf.ITextRenderer;
import org.xml.sax.SAXException;
import com.lowagie.text.DocumentException;
import com.lowagie.text.pdf.BaseFont;
import freemarker.cache.StringTemplateLoader;
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;
/**
* <p>
*
*
*
* </p>
*
* @author hz15041240
* @date 2016-10-11 下午7:45:33
* @version
*/
public class PdfUtil {
/**
*
* <p>
*
* 根据Freemarker模板生成PDF文件并返回PDF字节数组
*
* </p>
*
* @param templeteBuffer freemarker模板文件字符串
* @param templateName 模板名称
* @param map 模板参数
* @param basePath 模板中图片相对基础路径
* @param fontFile 字体文件路径 (simsun.ttc 字体)
* @return
* @throws IOException
* @throws TemplateException
* @throws ParserConfigurationException
* @throws DocumentException
* @throws SAXException
*
* @author hz15041240
* @date 2016-10-11 下午8:11:29
* @version
*/
public byte[] generatePdf(String templeteBuffer, String templateName, Map<String, Object> map, String basePath, String fontFile) throws IOException, TemplateException, ParserConfigurationException, DocumentException, SAXException {
/** ----freemarker模板解析---- **/
Configuration configuration = new Configuration(Configuration.VERSION_2_3_21);
configuration.setDefaultEncoding("utf-8");
StringTemplateLoader stringLoader = new StringTemplateLoader();
stringLoader.putTemplate(templateName, templeteBuffer);
configuration.setTemplateLoader(stringLoader);
Template template = configuration.getTemplate(templateName);
StringWriter str = new StringWriter();
template.process(template, str);
/** -------生成PDF------- **/
DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
Document doc = builder.parse(new ByteArrayInputStream(str.toString().getBytes()));
ITextRenderer renderer = new ITextRenderer();
renderer.setDocument(doc, null);
// 解决中文支持问题
ITextFontResolver fontResolver = renderer.getFontResolver();
String simusun = fontFile;
if (simusun != null) {
fontResolver.addFont(simusun, BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
renderer.getSharedContext().setFontResolver(fontResolver);
}
// 解决图片的相对路径问题
renderer.getSharedContext().setBaseURL("file:" + basePath);
renderer.layout();
//返回PDF字节数组 一边上传文件服务器
ByteArrayOutputStream os = new ByteArrayOutputStream(1024000);
renderer.createPDF(os);
// 输出PDF文件
// OutputStream fileStream = new FileOutputStream("d:\\test.pdf");
// fileStream.write(os.toByteArray());
// fileStream.close();
return os.toByteArray();
}
}
三:pom.xml详细:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.xxxx.utils</groupId>
<artifactId>pdf-client-project</artifactId>
<version>1.0.0-SNAPSHOT</version>
<packaging>jar</packaging>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<slf4j-api.version>1.7.7</slf4j-api.version>
<logback.version>1.1.1</logback.version>
<commons-codec.version>1.9</commons-codec.version>
<commons-io.version>2.4</commons-io.version>
</properties>
<dependencies>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>${logback.version}</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
<version>${logback.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${slf4j-api.version}</version>
</dependency>
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
<version>2.3.21</version>
</dependency>
<dependency>
<groupId>org.xhtmlrenderer</groupId>
<artifactId>flying-saucer-pdf</artifactId>
<version>11.0.7</version>
</dependency>
<dependency>
<groupId>com.lowagie</groupId>
<artifactId>itext</artifactId>
<version>2.1.7</version>
</dependency>
<dependency>
<groupId>org.xhtmlrenderer</groupId>
<artifactId>flying-saucer-core</artifactId>
<version>11.0.7</version>
</dependency>
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>${commons-codec.version}</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>${commons-io.version}</version>
</dependency>
</dependencies>
</project>
示例:
freemarker test.ftl
<html lang="en">
<head>
<meta charset="utf-8" />
<title>Document</title>
<style type="text/css">
html, body { margin: 0; padding: 0; }
body { color: #000; font-family: SimSun; font-size: 20px; }
table { width: 100%; border-collapse: collapse; border-spacing: 0;padding: 0; margin: 0; }
td, th { padding: 0; margin: 0; font-size: 100%; }
@media print { @page { margin: 0; padding: 0; margin-bottom: 20px; } }
.no-bold {font-weight:normal;}
.breakline{word-wrap: break-word; word-break: normal; }
.footer { margin-top: 10px; }
@page {
margin: 20mm 5mm 40mm 5mm;
}
#header {position: running(header);}
#footer {position: running(footer);}
@page{
@top-center{
content : element(header);
}
@bottom-center{
content : element(footer)
}
}
#pages:before{
content : counter(page);
font-size : 10px;
}
#pages:after{
content : counter(pages);
font-size : 10px;
}
</style>
</head>
<body>
<div>
<div id="header" style="margin-top: 0px;">
<span>页眉页眉页眉页眉页眉页眉页眉页眉页眉页眉页眉页眉页眉页眉页眉页眉页眉页眉</span>
</div>
<div id="footer">
<div style="text-align: center;">第<span id="pages">页,共</span>页</div>
<span style="margin-top:5px;">页底页底页底页底页底页底页底页底页底页底页底页底页底页底页底页底页底页底</span>
</div>
<br/>
<div>
<table class="biaoge1">
<tr><td width="20%">编号1</td><td width="30%">名称</td><td width="20%">编号2</td><td width="30%" align="center">编号3</td></tr>
<#list insurantList as insurant>
<tr><td>${insurant.inssueNum}</td><td>${insurant.cname}</td><td>${insurant.cardNum}</td><td align="center">${insurant.brithday}</td></tr>
</#list>
</table>
</div>
</div>
</body>
</html>
生成的pdf效果:
图中有间隔是用两张图拼的,中间页就省略;
实现了页眉与页底+分页显示效果;