<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 程序

    ?

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

    ?

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

    ?

    JTidy 有個(gè)方法叫 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 實(shí)現(xiàn)并不支持 XML 命名空間。因此,我們必需修改 Antenna House 的樣式表,讓它使用默認(rèn)的命名空間。比如,原來是:

    ?

    ??? <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>

    ?

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

    ?

    <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() 來獲得一個(gè)指定的樣式表的 Transformer 對象。然后,代表著轉(zhuǎn)換結(jié)果的那個(gè) 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 輸入文件相同的前綴來打開一個(gè) 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 和一個(gè) ByteArrayOutputStream 來生成一個(gè) FOP driver 對象。通過調(diào)用 Driver.run 可以生成 PDF 文件。結(jié)果被作為一個(gè) 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 來完成這整個(gè)過程,速度要比使用命令行界面快得多,因?yàn)樗恍枰疟P中寫入任何中間文件。這種方法可以集成到服務(wù)器里,來處理并發(fā)的 HTML-PDF 轉(zhuǎn)換請求。

    ?

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

    ?

    結(jié)論

    ?

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

    ?

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

    ?

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

    ?

    ?

    資源

    ?

    # 下載本文中的源碼 :

    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 標(biāo)準(zhǔn)的兼容性 :

    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
    @六世軟件
    哦,中文我確實(shí)沒有試......是個(gè)問題啊

    # 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
    @六世軟件
    這個(gè)不太清楚哦~有空看看

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

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

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

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

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

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

    # 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
    主站蜘蛛池模板: 亚洲制服在线观看| 免费国产va视频永久在线观看| 无码少妇一区二区浪潮免费| 亚洲精品乱码久久久久久蜜桃图片| 亚洲国产成人精品无码久久久久久综合| 中国在线观看免费的www| 亚洲一区二区三区四区视频| 亚洲av麻豆aⅴ无码电影| 亚洲三级在线免费观看| 免费精品国产自产拍在线观看| 亚洲色图在线播放| 亚洲AⅤ优女AV综合久久久| 在免费jizzjizz在线播| 一级特黄色毛片免费看| 亚洲小视频在线播放| 亚洲综合国产精品第一页| 久久精品a一国产成人免费网站 | 亚洲区小说区激情区图片区| 无码精品A∨在线观看免费| 99久久99这里只有免费的精品| 亚洲中文精品久久久久久不卡| 亚洲国产另类久久久精品小说| 在线A级毛片无码免费真人 | 久久久久久亚洲精品不卡| 麻豆一区二区免费播放网站 | 亚洲国产精品第一区二区三区| 国产成人精品免费视| 大地影院MV在线观看视频免费| 四虎一区二区成人免费影院网址| 亚洲成人午夜电影| 亚洲妇熟XXXX妇色黄| 国产午夜亚洲不卡| 四虎永久免费地址在线观看| 日韩av无码成人无码免费| 2019中文字幕在线电影免费| 91精品成人免费国产| 久久精品无码专区免费| 五级黄18以上免费看| 一级毛片免费在线| 污网站免费在线观看| 亚洲Av无码国产一区二区|