Java HTML 生成 PDF

1、IText实现html2pdf,速度快,纠错能力差,支持中文(要求HTML使用unicode编码),但中支持一种中文字体,开源。

2、Flying Sauser实现html2pdf,纠错能力差,支持多种中文字体(部分样式不能识别),开源。

3、PD4ML实现html2pdf,速度快,纠错能力强,支持多种中文字体,商业。

 

(一)IText

官网:http://www.itextpdf.com/
测试案例:TestIText.java
依赖jar包:iText-2.0.8.jar、iTextAsian.jar(支持中文)
下面只是一个小的测试案例,如果项目中使用到了该组件可以参考API完成项目组中相应的功能!

         

import java.io.FileOutputStream;  
import java.io.FileReader;  
import java.util.ArrayList;  
import com.lowagie.text.Document;  
import com.lowagie.text.Element;  
import com.lowagie.text.Font;  
import com.lowagie.text.PageSize;  
import com.lowagie.text.Paragraph;  
import com.lowagie.text.html.simpleparser.HTMLWorker;  
import com.lowagie.text.html.simpleparser.StyleSheet;  
import com.lowagie.text.pdf.BaseFont;  
import com.lowagie.text.pdf.PdfWriter;  
public class TestIText{  
    public static void main(String[] args) {  
        TestIText ih = new TestIText();  
        ih.htmlCodeComeFromFile("D://Test//iText.html", "D://Test//iText_1.pdf");  
        ih.htmlCodeComeString("Hello中文", "D://Test//iText_2.pdf");  
    }  
      
    public void htmlCodeComeFromFile(String filePath, String pdfPath) {  
        Document document = new Document();  
        try {  
            StyleSheet st = new StyleSheet();  
            st.loadTagStyle("body", "leading", "16,0");  
            PdfWriter.getInstance(document, new FileOutputStream(pdfPath));  
            document.open();  
            ArrayList p = HTMLWorker.parseToList(new FileReader(filePath), st);  
            for(int k = 0; k < p.size(); ++k) {  
                document.add((Element)p.get(k));  
            }  
            document.close();  
            System.out.println("文档创建成功");  
        }catch(Exception e) {  
            e.printStackTrace();  
        }  
    }  
  
    public void htmlCodeComeString(String htmlCode, String pdfPath) {  
        Document doc = new Document(PageSize.A4);  
        try {  
            PdfWriter.getInstance(doc, new FileOutputStream(pdfPath));  
            doc.open();  
            // 解决中文问题  
            BaseFont bfChinese = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);  
            Font FontChinese = new Font(bfChinese, 12, Font.NORMAL);  
            Paragraph t = new Paragraph(htmlCode, FontChinese);  
            doc.add(t);  
            doc.close();  
            System.out.println("文档创建成功");  
        }catch(Exception e) {  
            e.printStackTrace();  
        }  
    }  
}  
 

 (二)Flying Sauser

项目主页:https://xhtmlrenderer.dev.java.net/

依赖jar包:iText-2.0.8.jar、iTextAsian.jar、core-renderer.jar

默认情况下,core-renderer.jar对中文是不能进行换行的,如果想解决换行问题可以去http://bettereveryday.javaeye.com/blog/611561下载一个jar包,该包对源代码做了稍加修改.

下面只是一个小的测试案例,如果项目中使用到了该组件可以参考API完成项目组中相应的功能!

        

import java.io.File;  
import java.io.FileOutputStream;  
import java.io.OutputStream;  
  
import org.xhtmlrenderer.pdf.ITextFontResolver;  
import org.xhtmlrenderer.pdf.ITextRenderer;  
  
import com.lowagie.text.pdf.BaseFont;  
  
public class TestFlyingSauser {  
    public static void main(String[] args) throws Exception {  
        demo_1();  
        demo_2();  
    }  
  
    // 不支持中文  
    public static void demo_1() throws Exception {  
        String inputFile = "D:/Test/flying.html";  
        String url = new File(inputFile).toURI().toURL().toString();  
        String outputFile = "D:/Test/flying.pdf";  
        OutputStream os = new FileOutputStream(outputFile);  
        ITextRenderer renderer = new ITextRenderer();  
        renderer.setDocument(url);  
        renderer.layout();  
        renderer.createPDF(os);  
        os.close();  
    }  
  
    // 支持中文  
    public static void demo_2() throws Exception {  
        String outputFile = "D:/Test/demo_3.pdf";  
        OutputStream os = new FileOutputStream(outputFile);  
        ITextRenderer renderer = new ITextRenderer();  
        ITextFontResolver fontResolver = renderer.getFontResolver();  
        fontResolver.addFont("C:/Windows/fonts/simsun.ttc", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);  
        StringBuffer html = new StringBuffer();  
        // DOCTYPE 必需写否则类似于 这样的字符解析会出现错误  
        html.append("<!DOCTYPE html PUBLIC /"-//W3C//DTD XHTML 1.0 Transitional//EN/" /"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd/">");  
        html.append("<html xmlns=/"http://www.w3.org/1999/xhtml/">").append("<head>")  
            .append("<meta http-equiv=/"Content-Type/" content=/"text/html; charset=UTF-8/" />")  
            .append("<mce:style type=/"text/css/"><!--  
body {font-family: SimSun;}  
--></mce:style><style type=/"text/css/" mce_bogus="1">body {font-family: SimSun;}</style>")  
            .append("</head>")  
            .append("<body>");  
        html.append("<div>支持中文!</div>");  
        html.append("</body></html>");  
        renderer.setDocumentFromString(html.toString());  
        // 解决图片的相对路径问题  
        // renderer.getSharedContext().setBaseURL("file:/F:/teste/html/");  
        renderer.layout();  
        renderer.createPDF(os);  
        os.close();  
    }  
}  
        


参考资料:
http://yongboy.javaeye.com/blog/510976
http://www.51itsns.com/sns/space.php?uid=4&do=blog&id=582

       

关于Flying Sauser的一篇非常不错的文章:http://today.java.net/pub/a/today/2007/06/26/generating-pdfs-with-flying-saucer-and-itext.html

 

(三)PD4ML
官网下载:http://pd4ml.com/downloads.htm
依赖jar包:pd4ml_demo.jar、pd4ml__css2.jar、fonts.jar
下面只是一个小的测试案例,如果项目中使用到了该组件可以参考API完成项目组中相应的功能!

      
[java] view plaincopy
import java.awt.Insets;  
import java.io.File;  
import java.io.FileOutputStream;  
import java.io.StringReader;  
  
import org.zefer.pd4ml.PD4Constants;  
import org.zefer.pd4ml.PD4ML;  
  
public class Converter {  
    public static void main(String[] args) throws Exception {  
        Converter converter = new Converter();  
        converter.generatePDF_2(new File("D:/Test/demo_ch_pd4ml_a.pdf"), "D:/Test/a.htm");  
        File pdfFile = new File("D:/Test/demo_ch_pd4ml.pdf");  
        StringBuffer html = new StringBuffer();  
        html.append("<html>")  
            .append("<head>")  
            .append("<meta http-equiv=/"Content-Type/" content=/"text/html; charset=UTF-8/" />")  
            .append("</head>")  
            .append("<body>")  
            .append("<font face=/"KaiTi_GB2312/">")  
            .append("<font color='red' size=22>显示中文</font>")  
            .append("</font>")  
            .append("</body></html>");  
        StringReader strReader = new StringReader(html.toString());  
        converter.generatePDF_1(pdfFile, strReader);  
    }  
    // 手动构造HTML代码  
    public void generatePDF_1(File outputPDFFile, StringReader strReader) throws Exception {  
        FileOutputStream fos = new FileOutputStream(outputPDFFile);  
        PD4ML pd4ml = new PD4ML();  
        pd4ml.setPageInsets(new Insets(20, 10, 10, 10));  
        pd4ml.setHtmlWidth(950);  
        pd4ml.setPageSize(pd4ml.changePageOrientation(PD4Constants.A4));  
        pd4ml.useTTF("java:fonts", true);  
        pd4ml.setDefaultTTFs("KaiTi_GB2312", "KaiTi_GB2312", "KaiTi_GB2312");  
        pd4ml.enableDebugInfo();  
        pd4ml.render(strReader, fos);  
    }  
  
    // HTML代码来自于HTML文件  
    public void generatePDF_2(File outputPDFFile, String inputHTMLFileName) throws Exception {  
        FileOutputStream fos = new FileOutputStream(outputPDFFile);  
        PD4ML pd4ml = new PD4ML();  
        pd4ml.setPageInsets(new Insets(20, 10, 10, 10));  
        pd4ml.setHtmlWidth(950);  
        pd4ml.setPageSize(pd4ml.changePageOrientation(PD4Constants.A4));  
        pd4ml.useTTF("java:fonts", true);  
        pd4ml.setDefaultTTFs("KaiTi_GB2312", "KaiTi_GB2312", "KaiTi_GB2312");  
        pd4ml.enableDebugInfo();  
        pd4ml.render("file:" + inputHTMLFileName, fos);  
    }  
}  
 

参考资料:

http://www.pd4ml.com/examples.htm
http://www.pd4ml.com/api/index.html
http://pd4ml.com/reference.htm#7.1
http://pd4ml.com/support/html-pdf-faq-f1/double-byte-support-t195.html
http://pd4ml.com/support/pd4ml-html-css-pdf-tips-tricks-f7/ttf-embedding-t42.html

 
生成PDF文档的方案大致就这些了,希望能够给大家带来帮助!如果上面的三种方案都还不能满足项目组的需求哪就只有去买商业软件了。

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。