如题

解决方案 »

  1.   

    import java.io.ByteArrayInputStream;
    import java.io.ByteArrayOutputStream;
    import java.io.FileNotFoundException;
    import java.io.FileOutputStream;
    import java.io.InputStream;
    import java.io.OutputStream;import javax.xml.parsers.DocumentBuilder;
    import javax.xml.parsers.DocumentBuilderFactory;
    import javax.xml.transform.Transformer;
    import javax.xml.transform.TransformerFactory;
    import javax.xml.transform.dom.DOMSource;
    import javax.xml.transform.stream.StreamResult;import org.w3c.dom.Document;
    import org.xhtmlrenderer.pdf.ITextFontResolver;
    import org.xhtmlrenderer.pdf.ITextRenderer;import com.lowagie.text.pdf.BaseFont;public class HTML2PDF { /**
     * 调用方式 htmlToPDF(response.getOutputStream(), htmlstr,
     * "C:/WINDOWS/Fonts/simfang.ttf", "FangSong_GB2312", "GB2312",
     * "http://xxxx/dtd/xhtml1-transitional.dtd");
     * 
     * 相关图片必须使用绝对路径才能显示 如果要下载生成的文件,在此方法上方加上:
     * response.setHeader("Content-disposition",
     * "attachment;filename=英文文件名.pdf");
     * 
     * @param 参数
     * @param OutputStream
     *            out 输出流
     * @param String
     *            htmlcode html代码。
     * 
     * @param String
     *            fontName 字体名称 如:FangSong_GB2312
     * @param String
     *            fontpath windows 字体路径 如:C:/WINDOWS/FONTS/SIMFANG.TTF
     * @param String
     *            encoding 编码 如:GB2312。
     * @param String
     *            htmlDTDURL 如:http://xxxx/xhtml1-transitional.dtd version
     *            2009.03.05
     */
    public void htmlToPDF(OutputStream out, String htmlcode, String fontpath,
    String fontName, String encoding, String htmlDTDURL)
    throws Exception {

    DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
    ByteArrayOutputStream bos = new ByteArrayOutputStream();
    Transformer transformer = TransformerFactory.newInstance().newTransformer();
    ITextRenderer renderer = new ITextRenderer();
    ITextFontResolver resolver = renderer.getFontResolver();
    InputStream intream = null;
    Document doc = null;
    Document doc2 = null;
    try {
    htmlcode = this.filterHeader(htmlcode, encoding, fontName, htmlDTDURL);
    intream = new ByteArrayInputStream(htmlcode.getBytes(encoding));
    doc = (Document) builder.parse(intream);
    transformer.setOutputProperty("encoding", encoding);
    transformer.transform(new DOMSource(doc), new StreamResult(bos));
    intream = new ByteArrayInputStream(bos.toString().getBytes());
    doc2 = (Document) builder.parse(intream); resolver.addFont(fontpath, BaseFont.IDENTITY_H,
    BaseFont.NOT_EMBEDDED); renderer.setDocument(doc2, null);
    // renderer.getSharedContext().setBaseURL("file:/c:/");
    renderer.layout(); renderer.createPDF(out, true); out.flush();
    out.close();
    } catch (Exception ex) { throw new Exception(ex.getMessage());
    }
    } /**
     * 文件头
     */
    private String filterHeader(String htmlcode, String encoding,
    String fontName, String htmlDTDURL) {
    htmlcode = "<table style=\"font-family:FangSong_GB2312\" width=\"100%\" height=\"100%\" border=\"0\"><tr><td>"
    + htmlcode + "</td></tr></table>";
    htmlcode = "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\"  \""
    + htmlDTDURL + "\" >\n" + htmlcode;
    htmlcode = "<?xml version=\"1.0\" encoding=\"" + encoding + "\" ?>\n"
    + htmlcode;
    return htmlcode;
    }

    public static void main(String[] args){
    HTML2PDF html2pdf = new HTML2PDF();
    String htmlcode = "<table><tr><td style=\"color:red;\">中国</td></tr><tr><td>中国</td></tr><tr><td>中国</td></tr><tr><td>中国</td></tr><tr><td><img src=\"c:/1.jpg\"/></td></tr></table>";
    String fontpath = "C:/WINDOWS/FONTS/SIMFANG.TTF";
    String fontName = "";
    String encoding = "UTF-8";
    String htmlDTDURL = "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd";
    try {
    html2pdf.htmlToPDF(new FileOutputStream("c:/dd.pdf"), htmlcode, fontpath, fontName, encoding, htmlDTDURL);
    } catch (FileNotFoundException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    } catch (Exception e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }
    }


    }
    我用的就是这代码,太慢了。
      

  2.   

    速度慢是因为访问w3c的网站吧
    下面的代码还是比较快的
    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 = "G:/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("<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();  
        }}
      

  3.   

    转图片的就复杂一些了,我之前倒是做过
    用htmlparser解析html,把里面的图片相对地址改成文件绝对地址,然后把所有的数据添加到pdf中就行了
      

  4.   

    图片的问题我也解决了,方法是:
    renderer.getSharedContext().setBaseURL("file:/C:/"); 
    用这句设置一下路径,然后,HTML中的图片的地址写相对于这个路径的路径:
    如:
    图片:c:/test/1.jpg
    写成
    <img src=\"test/1.jpg\"/>
    这样就可以了.
      

  5.   

    把代码帖出来,如下:
     public static void demo_2() throws Exception {  
            String outputFile = "c:/demo_3.pdf";  
            OutputStream os = new FileOutputStream(outputFile);  
            ITextRenderer renderer = new ITextRenderer();  
            ITextFontResolver fontResolver = renderer.getFontResolver();  
    //        renderer.getSharedContext().setBaseURL("file:/C:/"); 
            
            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\">");
            html.append("<head>");
            html.append("<style type=\"text/css\" mce_bogus=\"1\">body {font-family: SimSun;}</style>");
            html.append(" <meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\"/>");
            html.append("<title>test</title>");
            html.append("</head>");
            html.append("<body>");
            html.append("<h1>");
            html.append("名字");
            html.append("</h1>");
            html.append("<h3>");
            html.append("名字");
            html.append("</h3>");
            html.append("<div>");
            html.append("<ul>");
            html.append("<li><a href=\"http://service.qq.com/special/aq/info/45293.html\">我的密保手机不用了,怎么找回密码?</a></li>");
            html.append("<li><a href=\"http://service.qq.com/special/aq/info/45273.html\" >申诉回执编号在哪里查询?</a></li>");
            html.append("<li><a href=\"http://service.qq.com/special/aq/info/13895.html\">申诉处理时间是多久?</a></li>");
            html.append("<li><a href=\"http://service.qq.com/special/aq/info/13953.html\" >如何避免qq帐号被盗?</a></li>");
            html.append("</ul>");
            html.append("</div>");
            html.append("</body>");
            html.append("</html>");
            
    //        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("<style type=\"text/css\" mce_bogus=\"1\">body {font-family: SimSun;}</style>") 
    //            .append("</head>")  
    //            .append("<body>");  
    //        html.append("<table id=\"asdf\">");
    //        html.append("<tr><td>中国</td></tr>");
    //        html.append("<tr><td>中国</td></tr>");
    //        html.append("<tr><td>中国</td></tr>");
    //        html.append("</table>");
    //        html.append("<div>支持中文!</div>");  
    //        html.append("<div><img src=\"1.jpg\" /></div>");
    //        html.append("</body></html>");          
            
            
            
    //        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\">");
    //        html.append("<HEAD>");
    //        html.append("<TITLE>腾讯客服中心官方网站-QQ安全中心客服专区</TITLE>");
    //        html.append("<META content=\"text/html; charset=utf-8\" http-equiv=\"Content-Type\"/>");
    //        html.append("<LINK rel=\"stylesheet\" type=\"text/css\" href=\"3_files/global2.css\"/>");
    //        html.append("<LINK rel=\"stylesheet\" type=\"text/css\" href=\"3_files/alone2_css.css\"/>");
    //        html.append("<META name=\"GENERATOR\" content=\"MSHTML 8.00.6001.19019\"/>");
    //        html.append("</HEAD>");
    //        html.append("<BODY>");
    //        html.append("<DIV class=\"header_simple_bg\">");
    //        html.append("<DIV id=\"header_simple\" class=\"clearfix\">");
    //        html.append("<DIV class=\"logo\">");
    //        html.append("<DIV class=\"left kf_logo\">");
    //        html.append("<A href=\"http://service.qq.com/\" target=\"_blank\"><IMG src=\"3_files/logo.png\"/></A>");
    //        html.append("</DIV>");
    //        html.append("<DIV class=\"left\">");
    //        html.append("<A href=\"http://service.qq.com/special/aq.html\"><IMG src=\"3_files/logo_aq.png\"/></A>");
    //        html.append("</DIV>");
    //        html.append("</DIV>");
    //        html.append("</DIV>");
    //        html.append("</DIV>");
    //        html.append("<H2>");
    //        html.append("热点问题");
    //        html.append("<SPAN class=\"more\"><A href=\"http://service.qq.com/special/aq/category/aq.html\">更多&gt;&gt;</A></SPAN>");
    //        html.append("</H2>");
    //        html.append("<DIV class=\"li_faq_2 aq_list\">");
    //        html.append("<UL>");
    //        html.append("<LI><A href=\"http://service.qq.com/special/aq/info/45293.html\" target=\"_blank\">我的密保手机不用了,怎么找回密码?</A></LI>");
    //        html.append("<LI><A href=\"http://service.qq.com/special/aq/info/45273.html\" target=\"_blank\">申诉回执编号在哪里查询?</A></LI>");
    //        html.append("<LI><A href=\"http://service.qq.com/special/aq/info/13895.html\" target=\"_blank\">申诉处理时间是多久?</A></LI>");
    //        html.append("<LI><A href=\"http://service.qq.com/special/aq/info/13953.html\" target=\"_blank\">如何避免QQ帐号被盗?</A></LI>");
    //        html.append("</UL>");
    //        html.append("</DIV>");
    //        html.append("</BODY></HTML>");
            
            renderer.setDocumentFromString(html.toString());  
            // 解决图片的相对路径问题  
            renderer.getSharedContext().setBaseURL("file:/c:/test/");
            renderer.layout();  
            renderer.createPDF(os);  
            os.close();  
        }
    大家要把注掉的部分删了就行了,
    可注意的问题有:
    1.html所有的标签都得是小写的,大写不识别。
    2.所有的标签要成对出现:如:<div></div>
    3.图片要先用renderer指定一个路径,代码中引用图片是要写与指定路径对应的相对路径
    4.上面的html.append("<style type=\"text/css\" mce_bogus=\"1\">body {font-family: SimSun;}</style>");
    一行不能去掉,否则就不能执行成功了,不知道为什么。
    目前我就总结了这么多,还不全,请大家一起努力,谢谢。
      

  6.   

    在这里我在感谢 youthon ,因为他给我分享了他的代码,确实很快!
      

  7.   

    我只想说,对于没有规则的html,想转化为pdf,基本没戏。
    不要死缠了。
    对于有规则的html,使用模板技术freeet。
      

  8.   

    freeet没整过,我知道一个freeer好像有这功能
      

  9.   

    大家有没有人知道在html转pdf的时候,文字换行是怎么设置的?