<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    Shao Fan

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

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

    Posted on 2006-06-01 07:56 shaofan 閱讀(3544) 評論(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
    主站蜘蛛池模板: 日韩精品视频免费网址| 成人免费午夜视频| 亚洲午夜无码AV毛片久久| 国产精品久久久久久亚洲小说| 最近最好的中文字幕2019免费| 亚洲乱码在线视频| 成人免费视频77777| 国产成人精品日本亚洲18图| 亚洲欧洲免费无码| 亚洲国产成人精品无码区花野真一 | 亚洲AⅤ无码一区二区三区在线 | 亚洲中文无码永久免| 永久免费av无码网站韩国毛片| 亚洲人成免费网站| 扒开双腿猛进入爽爽免费视频| 亚洲高清毛片一区二区| 国产精品免费综合一区视频| 国产精品久久久久久亚洲小说| 国产亚洲av人片在线观看| 三级黄色免费观看| 亚洲久本草在线中文字幕| 0588影视手机免费看片| 精品亚洲成a人在线观看| 无码专区一va亚洲v专区在线 | 久久久久无码精品亚洲日韩| 99在线免费观看视频| 亚洲日韩一区二区一无码| 亚洲国产婷婷香蕉久久久久久| 两个人看的www免费视频| 亚洲伦理一二三四| 国产a不卡片精品免费观看| 特级做A爰片毛片免费看无码| 久久精品亚洲一区二区三区浴池| 成全高清视频免费观看| 免费国产在线精品一区| 日韩精品一区二区亚洲AV观看| 在线观看免费污视频| 久久精品成人免费观看97| 亚洲女人初试黑人巨高清| 全亚洲最新黄色特级网站 | 亚洲福利秒拍一区二区|