使用pd4ml 将html转换为pdf 遇到的几个问题,总结一下,与大家共享一下:
1 网上自带的fonts.jar不支持中文,加载进去中文乱码 , 需要修改fonts.jar,为此本人已修改好所需要的jar包(支持宋体中文simsun.ttc),链接在这。
2 pd4ml.jar,官方声明,只有pro版本支持中文,这个就比较坑了,并且带demo的在转换成PDF会有水印。
优缺点:
pd4ml相比itext,速度快,纠错能力强,支持多种中文字体,但是是商业。
IText实现html2pdf,速度快,纠错能力差(对Css,标签样式要求很高,标签不闭合都无转换),支持中文(要求HTML使用unicode编码),但中支持一种中文字体,开源。
上部分代码:
//发送业务数据;
request.setAttribute("techProtocolReview",techProtocolReview == null ?new TechProtocolReview() : techProtocolReview);//转发请求到jsp,返回解析之后的内容而不是输出到浏览器 String html = ServletUtils.forward(request,response,"/WEB-INF/views/modules/pads/machinedesign/techProtocolReviewTrsfPdfView.jsp");
//System.out.println(html); StringReader strReader = new StringReader(html); try { HtmlToPdf.byte2File(HtmlToPdf.generatePDF(strReader), "E:/", "test.pdf"); return new ReponseData.Builder(Constant.SUCCESS_CODE).message("页面转化PDF成功").build(); } catch (IOException e) { e.printStackTrace(); logger.error("页面转PDF失败:",e); return new ReponseData.Builder(Constant.SUCCESS_CODE).message("页面转化PDF失败!失败信息:"+e.getMessage()).build(); }
工具类:
附注:
WriteListener在javax.servlet 3.1.0版本中
import javax.servlet.ServletOutputStream; import javax.servlet.WriteListener; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponseWrapper; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.OutputStreamWriter; import java.io.PrintWriter;
public class ServletUtils { public static String forward(HttpServletRequest request, HttpServletResponse response, String src) { try{ //* ↓↓↓↓↓重新构造response,修改response中的输出流对象,使其输出到字节数组↓↓↓↓↓ *//* final ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); final ServletOutputStream servletOuputStream = new ServletOutputStream() { @Override public void write(int b) throws IOException { byteArrayOutputStream.write(b); } public boolean isReady() { return false; } public void setWriteListener(WriteListener writeListener) { } }; final PrintWriter printWriter = new PrintWriter(new OutputStreamWriter(byteArrayOutputStream, "UTF-8")); response = new HttpServletResponseWrapper(response) { public ServletOutputStream getOutputStream() { return servletOuputStream; } public PrintWriter getWriter() { return printWriter; } }; //* ↑↑↑↑↑↑重新构造response,修改response中的输出流对象,使其输出到字节数组↑↑↑↑↑↑ *//* //执行forward操作 request.getRequestDispatcher(src).forward(request,response); //把字节流中的内容太转为字符串 return new String(byteArrayOutputStream.toByteArray(),"utf-8"); } catch (Exception e){ throw new RuntimeException(e); } } }
import org.apache.log4j.Logger; import org.zefer.pd4ml.PD4Constants; import org.zefer.pd4ml.PD4ML; import java.awt.Insets; import java.io.*; public class HtmlToPdf { private static final Logger LOG = Logger.getLogger(HtmlToPdf.class); public static byte[] generatePDF( StringReader strReader) throws IOException { //FileOutputStream fos = new FileOutputStream(outputPDFFile); ByteArrayOutputStream os = new ByteArrayOutputStream(); PD4ML pd4ml = new PD4ML(); pd4ml.setPageInsets(new Insets(5, 5, 5, 5)); pd4ml.setHtmlWidth(900); pd4ml.setPageSize(PD4Constants.A4); // A4竖向显示 pd4ml.changePageOrientation(PD4Constants.A4)横向显示 //fonts.jar的配置文件中的值,用于中文乱码 pd4ml.useTTF("java:fonts", true); pd4ml.setDefaultTTFs("SimSun", "SimSun", "SimSun"); pd4ml.enableDebugInfo(); pd4ml.render(strReader, os); //如果用上面的fos,就是写出到指定的文件 return os.toByteArray(); } /** * 根据byte数组,生成文件 * @param bfile 文件数组 * @param filePath 文件存放路径 * @param fileName 文件名称 */ public static void byte2File(byte[] bfile,String filePath,String fileName) throws IOException { BufferedOutputStream bos=null; FileOutputStream fos=null; File file=null; File dir=new File(filePath); if(!dir.exists() && !dir.isDirectory()){//判断文件目录是否存在 dir.mkdirs(); } file=new File(filePath+fileName); fos=new FileOutputStream(file); bos=new BufferedOutputStream(fos); bos.write(bfile); //FileUtils.downFile(file, request, response); if(bos != null){ bos.close(); } if(fos != null){ fos.close(); } } }
相应的pom.xml:
<dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>3.1.0</version> <scope>provided</scope> </dependency>