Shao Fan

          關于JAVA與軟件工程
          posts - 31, comments - 71, trackbacks - 0, articles - 4
            BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理

          轉換HTML內容為PDF格式(2)

          Posted on 2006-06-01 07:56 shaofan 閱讀(3549) 評論(10)  編輯  收藏 所屬分類: Java

          Java 程序

          ?

          通過使用上述步驟中用過的三個工具的 DOM API ,我接下來會展示一個 JAVA 程序。它在運行時需要提供兩個命令行參數,會自動生成相應的 PDF 文檔,并且不會產生任何臨時文件。

          ?

          第一個程序新建一個 HTML 文件的 InputStream 對象,然后此對象被傳給 JTidy

          ?

          JTidy 有個方法叫 parseDOM() ,可以用來生成輸出的 XHTML 文檔的 Document 對象。

          ?

          ??? public static void main(String[] args) {

          ?

          ??? // 打開文件

          ??? if (args.length != 2) {

          ??????? System.out.println("Usage: Html2Pdf htmlFile styleSheet");

          ????? ??System.exit(1);

          ??? }

          ?

          ??? FileInputStream input = null;

          ??? String htmlFileName = args[0];

          ??? try {

          ??????? input = new FileInputStream(htmlFileName);

          ??? }

          ??? catch (java.io.FileNotFoundException e) {

          ??????? System.out.println("File not found: " + htmlFileName);

          ??? }

          ?

          ??????? Tidy tidy = new Tidy();

          ??? Document xmlDoc = tidy.parseDOM(input, null);

          ?

          JTidy DOM 實現并不支持 XML 命名空間。因此,我們必需修改 Antenna House 的樣式表,讓它使用默認的命名空間。比如,原來是:

          ?

          ??? <xsl:template match="html:h2">

          ????? <fo:block xsl:use-attribute-sets="h2">

          ? ?????? <xsl:call-template name="process-common-attributes-and-children"/>

          ????? </fo:block>

          ??? </xsl:template>

          ?

          被修改后是:

          ?

          ??? <xsl:template match="h2">

          ????? <fo:block xsl:use-attribute-sets="h2">

          ??????? <xsl:call-template name="process-common-attributes-and-children"/>

          ????? </fo:block>

          ??? </xsl:template>

          ?

          這個改動必需被應用到 xhtml2f0.xsl 中的所有模板,因為 JTidy 生成的 Document 對象以 <html> 標簽作為根,如:

          ?

          <html xmlns=quot;http://www.w3.org/1999/xhtml">

          ?

          修改后的 xhtml2fo.xsl 包含在這篇文章附帶的源代碼中。

          ?

          接著, xml2FO() 方法調用 Xalan ,使樣式表應用于 JTidy 生成的 DOM 對象:

          ?

          ??? Document foDoc = xml2FO(xmlDoc, args[1]);?

          ?

          方法 xml2FO() 首先調用 getTransformer() 來獲得一個指定的樣式表的 Transformer 對象。然后,代表著轉換結果的那個 Document 被返回:

          ?

          ??? private static Document xml2FO(Document xml, String styleSheet) {

          ?

          ??? DOMSource xmlDomSource = new DOMSource(xml);

          ????????? DOMResult domResult = new DOMResult();

          ?

          ??? Transformer transformer = getTransformer(styleSheet);

          ?

          ??? if (transformer == null) {

          ??????? System.out.println("Error creating transformer for " + styleSheet);

          ??????? System.exit(1);

          ??? }

          ??? try {

          ??????? transformer.transform(xmlDomSource, domResult);

          ??? }

          ??? catch (javax.xml.transform.TransformerException e) {

          ??????? return null;

          ??? }

          ??? return (Document) domResult.getNode();

          ?

          ??? }

          ?

          接著, main 方法用與 HTML 輸入文件相同的前綴來打開一個 FileOutputStream 。然后調用 fo2PDF() 方法所獲得的結果被寫入 OutputStream

          ?

          ??? String pdfFileName = htmlFileName.substring(0, htmlFileName.indexOf(".")) + ".pdf";

          ??? try {

          ??????? OutputStream pdf = new FileOutputStream(new File(pdfFileName));

          ??????? pdf.write(fo2PDF(foDoc));

          ??? }

          ??? catch (java.io.FileNotFoundException e) {

          ??????? System.out.println("Error creating PDF: " + pdfFileName);

          ??? }

          ??? catch (java.io.IOException e) {

          ??????? System.out.println("Error writing PDF: " + pdfFileName);

          ??? }

          ?

          方法 fo2PDF() 會使用在轉換中產生的 XSL-FO Document 和一個 ByteArrayOutputStream 來生成一個 FOP driver 對象。通過調用 Driver.run 可以生成 PDF 文件。結果被作為一個 byte array 返回:

          ?

          ??? private static byte[] fo2PDF(Document foDocument) {

          ?

          ??????? DocumentInputSource fopInputSource = new DocumentInputSource(

          ???????????????????????????????????????????????????????? foDocument);

          ?

          ??????? try {

          ?

          ??????????? ByteArrayOutputStream out = new ByteArrayOutputStream();

          ??????????? Logger log = new ConsoleLogger(ConsoleLogger.LEVEL_WARN);

          ?

          ??????????? Driver driver = new Driver(fopInputSource, out);

          ??????????? driver.setLogger(log);

          ???? ???????driver.setRenderer(Driver.RENDER_PDF);

          ??????????? driver.run();

          ?

          ??????????? return out.toByteArray();

          ?

          ??????? } catch (Exception ex) {

          ??????????? return null;

          ??????? }

          ??? }

          ?

          Html2Pdf.java 的源代碼可以在這篇文章的附帶代碼中找到。

          ?

          使用 DOM API 來完成這整個過程,速度要比使用命令行界面快得多,因為它不需要往磁盤中寫入任何中間文件。這種方法可以集成到服務器里,來處理并發的 HTML-PDF 轉換請求。

          ?

          以前我曾以這里展示的這個程序為基礎把生成 PDF 的功能集成到一個 WEB 應用。而生成 PDF 的過程是動態的,因此不需要考慮 WEB 頁面和相應 PDF 同步的問題,因為生成的 PDF 文件并不是存放在服務器上。

          ?

          結論

          ?

          綜述,在本文里我描述了怎樣利用開源組件來實現 HTML PDF 的轉換。雖然這種實現方法在價格和源碼方面很有吸引力,但同時也有一定的折衷。一些商業組件可以提供更完整的標準實現。

          ?

          比如說, FOP 目前的版本是 .91 ,不完全支持 XSL-FO 標準。盡管如此,相對其它的格式而言,對 PDF 提供了更多的支持。

          ?

          在開始一個文檔轉換的項目之前,你必需考慮對文檔格式的需求,并把它們與已有組件所實現的功能做個對比。這將有助于做出正確的決定。

          ?

          ?

          資源

          ?

          # 下載本文中的源碼 :

          http://www.javaworld.com/javaworld/jw-04-2006/html/jw-0410-html.zip

          # Adobe's Document Server 產品 :

          http://www.adobe.com/products/server/documentserver/main.html

          # Antenna House ( 出售商業的格式化程序 ):

          http://www.antennahouse.com

          # xhtml2fo.xsl XHTML 轉化為 XSL-FO 的樣式表 :

          http://www.antennahouse.com/XSLsample/XSLsample.htm

          # Apache FOP formatter XSL-FO 翻譯為 PDF:

          http://xmlgraphics.apache.org/fop

          # FOP XSL-FO 標準的兼容性 :

          http://xmlgraphics.apache.org/fop/compliance.html

          # JTidy ,把 HTML 轉化為 XHTML:

          http://sourceforge.net/projects/jtidy/

          # Xalan:

          http://xalan.apache.org/

          # XSL-FO, Dave Pawson (O'Reilly Media, 2002 8 ; ISBN: 0596003552):

          http://www.amazon.com/exec/obidos/ASIN/0596003552/javaworld

          # XSLT 2.0 Programmer's Reference, Michael Kay (Wrox, 2004 8 ; ISBN: 0764569090):

          http://www.amazon.com/exec/obidos/ASIN/0764569090/javaworld

          # 瀏覽 JavaWorld Development Tools 部分可以找到更多關于 Java 開發工具的文章 :

          http://www.javaworld.com/channel_content/jw-tools-index.shtml

          # JavaWorld Java XML 部分的文章索引 :

          http://www.javaworld.com/channel_content/jw-xml-index.shtml


          評論

          # re: 轉換HTML內容為PDF格式(2)  回復  更多評論   

          2006-06-02 11:28 by 六世軟件
          好耶,我試試

          # re: 轉換HTML內容為PDF格式(2)  回復  更多評論   

          2006-06-02 12:41 by 六世軟件
          不支持中文

          # re: 轉換HTML內容為PDF格式(2)  回復  更多評論   

          2006-06-02 17:47 by shaofan
          @六世軟件
          哦,中文我確實沒有試......是個問題啊

          # re: 轉換HTML內容為PDF格式(2)  回復  更多評論   

          2006-06-05 16:44 by 六世軟件
          如何解決中文問題?

          # re: 轉換HTML內容為PDF格式(2)  回復  更多評論   

          2006-06-08 06:10 by shaofan
          @六世軟件
          這個不太清楚哦~有空看看

          # re: 轉換HTML內容為PDF格式(2)  回復  更多評論   

          2007-04-02 09:09 by howesen
          中文問題我已經解覺了,就間重寫了itext包中的方法,現在已經在我的主頁中提供修改過的下載了,具體怎么個改法,請看我的主頁中的介紹。
          主頁:http://down.latea.cn

          # re: 轉換HTML內容為PDF格式(2)  回復  更多評論   

          2007-04-02 20:54 by shaofan2
          @howesen
          能否給個鏈接?

          # re: 轉換HTML內容為PDF格式(2)  回復  更多評論   

          2007-07-02 11:12 by
          @howesen
          你就發了一個網址,進去也找不到呀,拜托既然想幫大家,就別繞彎子好不

          # re: 轉換HTML內容為PDF格式(2)[未登錄]  回復  更多評論   

          2007-11-15 11:46 by Gary
          請問Document foDoc = xml2FO(xmlDoc, args[1])中,args[1]在文中的參數是什么?

          # re: 轉換HTML內容為PDF格式(2)  回復  更多評論   

          2008-07-22 03:30 by Hi
          how to keep the blank lines for html
          主站蜘蛛池模板: 舟山市| 汶上县| 周宁县| 井陉县| 布尔津县| 锡林浩特市| 温州市| 宣汉县| 垫江县| 江门市| 开封市| 方正县| 石楼县| 军事| 府谷县| 泗阳县| 台中县| 安龙县| 建昌县| 仙桃市| 宣威市| 中超| 克东县| 阜阳市| 霸州市| 乌兰浩特市| 兰考县| 永城市| 新丰县| 梧州市| 阳新县| 韶关市| 湖北省| 永顺县| 鹤壁市| 土默特左旗| 分宜县| 涞源县| 兴安县| 苏尼特右旗| 体育|