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

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

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

    Shao Fan

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

    轉(zhuǎn)換HTML內(nèi)容為PDF格式(2)

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

    Java 程序

    ?

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

    ?

    第一個程序新建一個 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 實現(xiàn)并不支持 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>

    ?

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

    ?

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

    ?

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

    ?

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

    ?

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

    ?

    方法 xml2FO() 首先調(diào)用 getTransformer() 來獲得一個指定的樣式表的 Transformer 對象。然后,代表著轉(zhuǎn)換結(jié)果的那個 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 。然后調(diào)用 fo2PDF() 方法所獲得的結(jié)果被寫入 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() 會使用在轉(zhuǎn)換中產(chǎn)生的 XSL-FO Document 和一個 ByteArrayOutputStream 來生成一個 FOP driver 對象。通過調(diào)用 Driver.run 可以生成 PDF 文件。結(jié)果被作為一個 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 來完成這整個過程,速度要比使用命令行界面快得多,因為它不需要往磁盤中寫入任何中間文件。這種方法可以集成到服務(wù)器里,來處理并發(fā)的 HTML-PDF 轉(zhuǎn)換請求。

    ?

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

    ?

    結(jié)論

    ?

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

    ?

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

    ?

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

    ?

    ?

    資源

    ?

    # 下載本文中的源碼 :

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

    # Adobe's Document Server 產(chǎn)品 :

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

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

    http://www.antennahouse.com

    # xhtml2fo.xsl XHTML 轉(zhuǎn)化為 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 轉(zhuǎn)化為 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 部分可以找到更多關(guān)于 Java 開發(fā)工具的文章 :

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

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

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


    評論

    # re: 轉(zhuǎn)換HTML內(nèi)容為PDF格式(2)  回復(fù)  更多評論   

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

    # re: 轉(zhuǎn)換HTML內(nèi)容為PDF格式(2)  回復(fù)  更多評論   

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

    # re: 轉(zhuǎn)換HTML內(nèi)容為PDF格式(2)  回復(fù)  更多評論   

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

    # re: 轉(zhuǎn)換HTML內(nèi)容為PDF格式(2)  回復(fù)  更多評論   

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

    # re: 轉(zhuǎn)換HTML內(nèi)容為PDF格式(2)  回復(fù)  更多評論   

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

    # re: 轉(zhuǎn)換HTML內(nèi)容為PDF格式(2)  回復(fù)  更多評論   

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

    # re: 轉(zhuǎn)換HTML內(nèi)容為PDF格式(2)  回復(fù)  更多評論   

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

    # re: 轉(zhuǎn)換HTML內(nèi)容為PDF格式(2)  回復(fù)  更多評論   

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

    # re: 轉(zhuǎn)換HTML內(nèi)容為PDF格式(2)[未登錄]  回復(fù)  更多評論   

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

    # re: 轉(zhuǎn)換HTML內(nèi)容為PDF格式(2)  回復(fù)  更多評論   

    2008-07-22 03:30 by Hi
    how to keep the blank lines for html
    主站蜘蛛池模板: 国产高清免费观看| GOGOGO免费观看国语| 亚洲一区精彩视频| 亚洲不卡中文字幕| 学生妹亚洲一区二区| 亚洲国产成a人v在线观看| 亚洲乱码一二三四区乱码| 亚洲国产成a人v在线观看| 亚洲精品乱码久久久久久V| 亚洲国产AV一区二区三区四区| 亚洲精华液一二三产区| 无码天堂亚洲国产AV| 特级毛片aaaa免费观看| a级毛片免费观看在线| a级特黄毛片免费观看| 久久成人免费电影| 无码人妻精品中文字幕免费东京热| 无码乱肉视频免费大全合集| 成人免费看片又大又黄| 国产精品极品美女免费观看| 亚洲日韩在线观看| 久久久亚洲欧洲日产国码农村| 亚洲精品在线电影| 7777久久亚洲中文字幕| 久久久久亚洲精品无码网址色欲| 国产在亚洲线视频观看| 一级做α爱过程免费视频| 久艹视频在线免费观看| 久久国产免费福利永久| 日本一道综合久久aⅴ免费| 亚洲高清国产拍精品青青草原| 亚洲无码在线播放| 亚洲国产美女视频| 国产精品亚洲小说专区| 国产日韩AV免费无码一区二区 | 亚洲私人无码综合久久网| 国产亚洲精品91| 今天免费中文字幕视频| 成年免费大片黄在线观看岛国| 国产青草视频免费观看97| 亚洲国产无套无码av电影|