Maven依賴
<dependency> <groupId>com.itextpdf</groupId> <artifactId>itextpdf</artifactId> <version>5.5.7</version> </dependency> <dependency> <groupId>com.itextpdf.tool</groupId> <artifactId>xmlworker</artifactId> <version>5.5.7</version> </dependency>
類圖及API
IHtml2PdfService
HTML轉PDF的服務接口
write (htmlContent: java.lang.String, os: java.io.OutputStream): void
將指定的html轉換成pdf內容后,寫到指定的輸出流。
Html2PdfServiceImpl
HTML轉PDF的服務實現類
write (htmlContent: java.lang.String, os: java.io.OutputStream): void
實現:將指定的html轉換成pdf內容后,寫到指定的輸出流。
getIntaceHtml (htmlContent: String): String私有方法,用於獲取完整的html文檔;如果傳入的只是html片斷,需要使用模板將其完整化。
doWrite (htmlContent: String, os: OutputStream): void
私有方法,將完整的html文檔轉換成pdf之后,寫到指定的輸出流。
代碼
IHtml2PdfService
package cn.ljl.javaweb.demo.ckeditor.service; public interface IHtml2PdfService { /** html完整內容的前綴標識 */ public static final String INTACT_FLAG = "<html>"; /** * html模板,當待轉換的html只是片斷時,需將其插入到模板的body內. */ public static final String TEMPLATE_HTML = "<html>" + " <head>" + " <style type='text/css'>body {font-family: SimSun;}</style>" + " </head>" + " <body>" + " ${content}" + " </body>" + "</html>"; /** 將指定的html內容轉化成pdf文檔之后,寫入到指定的輸出流. */ public void write(java.lang.String htmlContent, java.io.OutputStream os); }
Html2PdfServiceImpl
package cn.ljl.javaweb.demo.ckeditor.service; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.nio.charset.Charset; import com.itextpdf.text.DocumentException; public class Html2PdfServiceImpl implements IHtml2PdfService { @Override public void write(String htmlContent, OutputStream os) { if (htmlContent == null || htmlContent.length() == 0) return; if (os == null) return; htmlContent = getIntaceHtml(htmlContent); doWrite(htmlContent, os); } /** * 根據提供的html內容,獲取完整的html內容.<br> * @param htmlContent * @return */ private String getIntaceHtml(String htmlContent) { boolean intact = htmlContent.trim().toLowerCase() .startsWith(INTACT_FLAG); if (!intact) { htmlContent = TEMPLATE_HTML.replaceFirst("\\$\\{content\\}", htmlContent); } return htmlContent; } /** * 實施寫操作.<br> * @param htmlContent * @param os */ private void doWrite(String htmlContent, OutputStream os) { InputStream is = new ByteArrayInputStream(htmlContent.getBytes()); com.itextpdf.text.Document document = new com.itextpdf.text.Document(); com.itextpdf.text.pdf.PdfWriter writer = null; try { writer = com.itextpdf.text.pdf.PdfWriter .getInstance(document, os); document.open(); com.itextpdf.tool.xml.XMLWorkerHelper.getInstance().parseXHtml(writer, document, is, Charset.forName("gbk")); } catch (DocumentException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } writer.flush(); // SINOBEST HTML2PDF 如果我們調用writer.close(),可能無法正常的生成pdf,甚至會遇到 // Exception:The page 1 was requested but the document has only 0 pages. // writer.close(); document.close(); } }
可能遇到的問題
1. 中文字符顯示問題
如果是完整的html文檔,需要使用css為整個文檔設置一個默認的字體,如IHtml2PdfService的模板中的代碼片段:
<style type='text/css'>body {font-family: SimSun;}</style>
2. 部分內容空白
可能是html文檔使用了服務器中沒有的字體。比如html文檔的某個div,設置了仿宋字體,而機器上又沒有安裝,那么轉換成pdf的時候,對應的內容是空白。