Flying-Saucer html 生成pdf 思路
1、编写ftl模板
2、使用freemarker生成html
3、根据生成的html在生成PD
项目依赖
<dependency>
<groupId>org.xhtmlrenderer</groupId>
<artifactId>flying-saucer-pdf-itext5</artifactId>
<version>9.1.6</version>
</dependency>
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
</dependency>
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itextpdf</artifactId>
<version>5.5.11</version>
</dependency>
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itext-asian</artifactId>
<version>5.2.0</version>
</dependency>
以下是实现类
PDF生成辅助类
import java.io.File;
import java.io.IOException;
import java.io.StringWriter;
import javax.servlet.http.HttpServletRequest;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.xhtmlrenderer.pdf.ITextRenderer;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.pdf.BaseFont;
import freemarker.core.ParseException;
import freemarker.template.Configuration;
import freemarker.template.MalformedTemplateNameException;
import freemarker.template.Template;
import freemarker.template.TemplateException;
import freemarker.template.TemplateNotFoundException;
/**
* PDF生成辅助类
*/
@SuppressWarnings("deprecation")
public class PdfHelper {
private static Configuration freemarkerCfg = null;
static{
try{
HttpServletRequest request = ((ServletRequestAttributes)RequestContextHolder.getRequestAttributes()).getRequest();
String path = request.getSession().getServletContext().getRealPath("").replaceAll("\\\\", "/") + "/flyingsauser/";
freemarkerCfg = new Configuration();
freemarkerCfg.setDirectoryForTemplateLoading(new File(path));
freemarkerCfg.setDefaultEncoding("UTF-8");
}catch (Exception e) {
e.printStackTrace();
}
};
public static ITextRenderer getRender(String ftlPath) throws DocumentException, IOException {
ITextRenderer render = new ITextRenderer();
//添加字体,以支持中文
render.getFontResolver().addFont(ftlPath + "/MSYH.TTC", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
//Microsoft YaHei,Open Sans,Gotham-Book,Lantinghei SC
return render;
}
//获取要写入PDF的内容
public static String getPdfContent(String ftlPath, String ftlName, Object o) throws TemplateNotFoundException, MalformedTemplateNameException, ParseException, IOException, TemplateException {
return useTemplate(ftlPath, ftlName, o);
}
//使用freemarker得到html内容
public static String useTemplate(String ftlPath, String ftlName, Object o) throws TemplateNotFoundException, MalformedTemplateNameException, ParseException, IOException, TemplateException {
StringWriter writer = new StringWriter();
String html = null;
try {
Template tpl = freemarkerCfg.getTemplate(ftlName);
tpl.setEncoding("UTF-8");
tpl.process(o, writer);
writer.flush();
html = writer.toString();
}catch (Exception e) {
e.printStackTrace();
} finally {
try {
writer.close();
} catch (IOException ex) {
ex.printStackTrace();
}
}
return html;
}
}
PDF生成工具类
import java.beans.PropertyDescriptor;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.text.SimpleDateFormat;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.beanutils.PropertyUtilsBean;
import org.slf4j.Logger;
import org.xhtmlrenderer.pdf.ITextRenderer;
import com.dji.hire.util.LogUtil;
import com.itextpdf.text.DocumentException;
import freemarker.core.ParseException;
import freemarker.template.MalformedTemplateNameException;
import freemarker.template.TemplateException;
import freemarker.template.TemplateNotFoundException;
/**
* PDF生成工具类
*
*/
public class PdfUtils {
// /**
// * 日志记录
// */
private static final Logger logger = LogUtil.get();
public static void main(String[] args) {
try {
Map<Object, Object> o=new HashMap<Object, Object>();
o.put("name", "http://www.xdemo.org/");
o.put("imagePath", "test.png");
String path = "E:/test/";
SimpleDateFormat sdf = new SimpleDateFormat("yyMMddHHmmss");
String warrantyCard = sdf.format(new java.util.Date());
String pdf = "D:\\"+warrantyCard+"xdemo.pdf";
// String path=PdfHelper.getPath();
generateToFile(path, "tpl.ftl",path, o, pdf);
// String f = readTxtFile("D:/newfile597f7ec6-99fe-4175-a2a8-c7f44db675de.html");
// System.out.println(f);
} catch (Exception e) {
e.printStackTrace();
}
}
public static Map<String, Object> beanToMap(Object obj) {
Map<String, Object> params = new HashMap<String, Object>(0);
try {
PropertyUtilsBean propertyUtilsBean = new PropertyUtilsBean();
PropertyDescriptor[] descriptors = propertyUtilsBean.getPropertyDescriptors(obj);
for (int i = 0; i < descriptors.length; i++) {
String name = descriptors[i].getName();
if (!"class".equals(name)) {
params.put(name, propertyUtilsBean.getNestedProperty(obj, name));
}
}
} catch (Exception e) {
e.printStackTrace();
}
return params;
}
/**
* 生成PDF到文件
* @param ftlPath 模板文件路径(不含文件名)
* @param ftlName 模板文件吗(不含路径)
* @param imageDiskPath 图片的磁盘路径
* @param data 数据
* @param outputFile 目标文件(全路径名称)
* @throws Exception
*/
public static void generateToFile(String ftlPath,String ftlName,String imageDiskPath,Object data,String outputFile) throws Exception {
String html=PdfHelper.getPdfContent(ftlPath, ftlName, data);
// logger.info(html);
try {
OutputStream out = null;
ITextRenderer render = null;
out = new FileOutputStream(outputFile);
render = PdfHelper.getRender(ftlPath);
render.setDocumentFromString(html);
if(imageDiskPath!=null&&!imageDiskPath.equals("")){
if(isLinux()){
//html中如果有图片,图片的路径则使用这里设置的路径的相对路径,这个是作为根路径
render.getSharedContext().setBaseURL("file:"+imageDiskPath);
}else{
//html中如果有图片,图片的路径则使用这里设置的路径的相对路径,这个是作为根路径
render.getSharedContext().setBaseURL("file:/"+imageDiskPath);
}
}
render.layout();
render.createPDF(out);
render.finishPDF();
render = null;
out.close();
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 判断当前环境是否为Linux
* @return
*/
public static boolean isLinux(){
String os = System.getProperty("os.name").toLowerCase();
if(os.indexOf("linux")>=0){
return true;
}else{
return false;
}
}
public static String readTxtFile(String filePath){
String texst = "";
try {
String encoding="UTF-8";
File file=new File(filePath);
if(file.isFile() && file.exists()){ //判断文件是否存在
InputStreamReader read = new InputStreamReader(
new FileInputStream(file),encoding);//考虑到编码格式
BufferedReader bufferedReader = new BufferedReader(read);
String lineTxt = "";
while((lineTxt = bufferedReader.readLine()) != null){
texst = texst + lineTxt;
}
read.close();
}else{
logger.info("找不到指定的文件");
}
} catch (Exception e) {
logger.error("读取文件内容出错");
e.printStackTrace();
}
return texst;
}
/**
* 生成PDF到输出流中(ServletOutputStream用于下载PDF)
* @param ftlPath ftl模板文件的路径(不含文件名)
* @param ftlName ftl模板文件的名称(不含路径)
* @param imageDiskPath 如果PDF中要求图片,那么需要传入图片所在位置的磁盘路径
* @param data 输入到FTL中的数据
* @param response HttpServletResponse
* @return
* @throws TemplateNotFoundException
* @throws MalformedTemplateNameException
* @throws ParseException
* @throws IOException
* @throws TemplateException
* @throws DocumentException
*/
public static OutputStream generateToServletOutputStream(String ftlPath,String ftlName,String imageDiskPath,Object data,HttpServletResponse response) throws TemplateNotFoundException, MalformedTemplateNameException, ParseException, IOException, TemplateException, DocumentException{
String html=PdfHelper.getPdfContent(ftlPath, ftlName, data);
OutputStream out = null;
ITextRenderer render = null;
out = response.getOutputStream();
render = PdfHelper.getRender(ftlPath);
render.setDocumentFromString(html);
if(imageDiskPath!=null&&!imageDiskPath.equals("")){
//html中如果有图片,图片的路径则使用这里设置的路径的相对路径,这个是作为根路径
render.getSharedContext().setBaseURL("file:/"+imageDiskPath);
}
render.layout();
render.createPDF(out);
render.finishPDF();
render = null;
return out;
}
}