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

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

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

    The Spark of Thinking

    Focus on Eclipse Tools.

      BlogJava :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理 ::
      3 隨筆 :: 27 文章 :: 4 評論 :: 0 Trackbacks
    如何在程序中嵌入FOP????

    FOP 簡介
    馬 路 (stevema@263.net)
    2001 年 11 月

    如何在程序中嵌入FOP?FOP是由James Tauber發(fā)起的一個開源項目,最初的目的是利用xsl-fo將xml文件轉(zhuǎn)換成pdf文件。目前最新的版本是2001年9月29日發(fā)布的0.20.2,它可以將xml文件轉(zhuǎn)換成pdf,mif,pcl,txt等多種格式以及直接輸出到打印機(jī),并且支持使用SVG描述圖形。XML顯然是最好的內(nèi)容存儲格式,而PDF是目前最流行的內(nèi)容載體格式,F(xiàn)OP顯然希望借助這種必然的XML to PDF需求,來推動xsl-fo規(guī)范的發(fā)展。雖然xsl-fo規(guī)范停滯不前,但利用FOP能使自己的程序具有將XML內(nèi)容輸出成PDF等流行格式的功能無疑是令人興奮的。
    FOP使用方式
    FOP有3種使用方式,分別為命令行,程序嵌入,XT 嵌入,這里將主要介紹如何在程序中嵌入FOP功能。將XML文件轉(zhuǎn)換為PDF實際上分為2步,第1步是利用XSLT將XML轉(zhuǎn)換為XSL-FO,第2步是將XSL-FO轉(zhuǎn)換為PDF。這里不想講述XSLT和XSL-FO有關(guān)的知識(這方面的文檔相當(dāng)多),而只將講述如何進(jìn)行第2步的轉(zhuǎn)換編程。

    在程序中嵌入FOP
    1. 范例simple.fo文件
    <?xml version="1.0" encoding="utf-8"?>
    <fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">

    ? <fo:layout-master-set>
    ??? <fo:simple-page-master master-name="simple"
    ????????????????? page-height="29.7cm"
    ????????????????? page-width="21cm"
    ????????????????? margin-top="1cm"
    ????????????????? margin-bottom="2cm"
    ????????????????? margin-left="2.5cm"
    ????????????????? margin-right="2.5cm">
    ????? <fo:region-body margin-top="3cm"/>
    ????? <fo:region-before extent="3cm"/>
    ????? <fo:region-after extent="1.5cm"/>
    ??? </fo:simple-page-master>
    ? </fo:layout-master-set>

    ? <fo:page-sequence master-name="simple">
    ??? <fo:flow flow-name="xsl-region-body">
    ?????? <!-- Title -->
    ????? <fo:block font-size="18pt"
    ??????????? font-family="sans-serif"
    ??????????? line-height="24pt"
    ??????????? space-after.optimum="15pt"
    ??????????? background-color="blue"
    ??????????? color="white"
    ??????????? text-align="center"
    ??????????? padding-top="3pt">
    ??????????? FOP 0.20.2
    ????? </fo:block>
    ????? <!-- Normal Text -->
    ????? <fo:block font-size="12pt"
    ??????????????? font-family="sans-serif"
    ??????????????? line-height="15pt"
    ??????????????? space-after.optimum="3pt"
    ??????????????? text-align="justify">
    FOP is the world's first print formatter driven by XSL formatting objects.
    It is a Java application that reads a formatting object tree and then turns it into a PDF document.
    ????? </fo:block>
    ??? </fo:flow>
    ? </fo:page-sequence>
    </fo:root>



    上述是一個很簡單的fo文件,將顯示兩塊文字,具體的fo語法請讀者自己查看相應(yīng)資料。

    2. 簡單調(diào)用FOP
    FOP提供的所有對外調(diào)用接口都在org.apache.fop.apps下,其下的AWTStarter.class是一個用AWT寫的轉(zhuǎn)換結(jié)果預(yù)覽程序,CommandLineStarter.class提供命令行使用方式,PrintStarter.class提供打印接口,XTDriver.class提供XT嵌入方式接口,Driver.class則是我們要在這里討論的程序接口。下面這個程序foptest.java演示了FOP的最簡單也是最常用的使用方式。


    import java.io.*;
    import org.xml.sax.InputSource;
    import org.xml.sax.XMLReader;
    import org.apache.fop.apps.*;

    public class foptest {
    public static void main(String[] args) {
    try {
    Driver driver = new Driver();
    //設(shè)置要轉(zhuǎn)換的fo文件名
    driver.setInputSource(new InputSource (args[0]));
    //設(shè)置輸出文件名
    driver.setOutputStream(new FileOutputStream(args[1]));
    //設(shè)置轉(zhuǎn)換類型
    //還可以為RENDER_PCL,RENDER_PS,RENDER_TXT,RENDER_MIF
    driver.setRenderer(Driver.RENDER_PDF);
    //開始轉(zhuǎn)換
    driver.run();
    }
    catch( Exception e ){
    e.printStackTrace();
    }
    }
    }



    上述程序?qū)⒔邮軆蓚€命令行參數(shù),第一個參數(shù)是需要轉(zhuǎn)換的fo文件名,第二個參數(shù)是輸出文件名。在CLASSPATH中添加下述jar文件:
    {FOP安裝目錄}\build\fop.jar
    {FOP安裝目錄}\lib\batik.jar
    {FOP安裝目錄}\lib\xalan-2.0.0.jar
    {FOP安裝目錄}\lib\xerces-1.2.3.jar
    {FOP安裝目錄}\lib\avalon-framework-4.0.jar
    {FOP安裝目錄}\lib\logkit-1.0b4.jar
    {FOP安裝目錄}\lib\jimi-1.0.jar
    然后執(zhí)行java foptest simple.fo simple.pdf

    執(zhí)行后產(chǎn)生的simple.pdf文件效果如下



    3. 顯示中文
    上面的演示程序段可以應(yīng)付絕大部分轉(zhuǎn)換編程的需要,不過對于國內(nèi)用戶來說,不可避免的需要產(chǎn)生中文PDF文件,讓我們把上述simple.fo的標(biāo)題從"FOP 0.20.2"改成"支持中文的FOP 0.20.2",不改動程序的情況下執(zhí)行結(jié)果顯示如下



    可以看到由于沒有加入相應(yīng)的字體支持,漢字被顯示成了#。

    東方字符的顯示在FOP的早期版本中并不被支持,最早嘗試對FOP打補(bǔ)丁以解決顯示東方字符的是日本人。從FOP 0.16版本開始,他們在sourceforge上建立了一個jpfop項目來解決日文字符的顯示問題,使用相同的方法也可以被用來顯示中文字符。幸運的是,當(dāng)前的FOP版本已經(jīng)能很好的解決中文顯示的問題,不再需要我們打補(bǔ)丁,下面是在FOP中使用中文的步驟:

    第一步,建立font metrics文件對于后綴為ttf的TrueType字體文件,我們可以執(zhí)行以下命令來產(chǎn)生font metrics文件
    java org.apache.fop.fonts.apps.TTFReader C:\WINNT\Fonts\simkai.ttf simkai.xml
    這里simkai.xml就是我們?yōu)榭w產(chǎn)生的font metrics文件。
    對于Windows下的宋體來說,存在的是后綴為ttc的TrueType Collection文件,即包含多個TrueType的文件,這時首先要做的是得到這個Collection中所有TrueType的名字,執(zhí)行以下命令(這個命令其實有錯誤):
    java org.apache.fop.fonts.apps.TTFReader C:\WINNT\Fonts\simsun.ttc simsun.xml

    產(chǎn)生輸出如下:
    This is a TrueType collection file with2 fonts
    Containing the following fonts:
    SimSun
    NSimSun
    java.io.IOException: Failed to read font
    ??????? at org.apache.fop.fonts.TTFFile.readFont(TTFFile.java:388)
    ??????? at org.apache.fop.fonts.apps.TTFReader.loadTTF(TTFReader.java:181)
    ??????? at org.apache.fop.fonts.apps.TTFReader.main(TTFReader.java:143)




    后面的異常是由于我們給的參數(shù)不對(因為ttc不是ttf字體文件)造成的,F(xiàn)OP開發(fā)小組知道這個問題,但是可能覺得無關(guān)痛癢而沒去修正它。無論怎樣,我們得到了我們要得到的結(jié)果,里面含的字體名為SimSun和NSimSun,通過以下命令為其中的SimSun字體產(chǎn)生font metrics文件:
    java org.apache.fop.fonts.apps.TTFReader -ttcname "SimSun" C:\WINNT\Fonts\simsun.ttc simsun.xml
    -ttcname后面指定需要從ttc文件中提取的字體名稱

    第二步,登記上述字體
    在FOP主目錄下的conf子目錄下有一個userconfig.xml文件,為了方便,我們將它和上一步產(chǎn)生的simsun.xml,simkai.xml都拷貝到與我們的演示程序同一目錄下。在userconfig.xml的最后幾行有一個<fonts></fonts>標(biāo)記區(qū),我們在其中加入以下項:
    <font metrics-file="simsun.xml" kerning="yes" embed-file="c:\WINNT\fonts\simsun.ttc">
    ??? <font-triplet name="mysimsun" style="normal" weight="normal"/>
    </font>
    <font metrics-file="simkai.xml" kerning="yes" embed-file="c:\WINNT\fonts\simkai.ttf">
    ??? <font-triplet name="mysimkai" style="normal" weight="normal"/>
    </font>




    其中metrics-file里可以設(shè)相對路徑或絕對路徑(因為我們這里在同一目錄下,所以只需寫文件名即可),font-triplet里的name可以自己自由設(shè)定,并不要求與字體名一樣。設(shè)定這個名字后,在fo里就只能通過這個名字引用這個字體。

    為了演示中文顯示,范例simplecn.fo文件為
    <?xml version="1.0" encoding="gb2312"?>
    <fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">

    ? <fo:layout-master-set>
    ??? <fo:simple-page-master master-name="simple"
    ????????????????? page-height="29.7cm"
    ????????????????? page-width="21cm"
    ????????????????? margin-top="1cm"
    ????????????????? margin-bottom="2cm"
    ????????????????? margin-left="2.5cm"
    ????????????????? margin-right="2.5cm">
    ????? <fo:region-body margin-top="3cm"/>
    ????? <fo:region-before extent="3cm"/>
    ????? <fo:region-after extent="1.5cm"/>
    ??? </fo:simple-page-master>
    ? </fo:layout-master-set>

    ? <fo:page-sequence master-name="simple">
    ??? <fo:flow flow-name="xsl-region-body">
    ????? <fo:block font-size="18pt"
    ??????????? font-family="mysimsun"
    ??????????? line-height="24pt"
    ??????????? text-align="center"
    ??????????? padding-top="3pt">
    ??????????? 這是宋體
    ????? </fo:block>
    ????? <fo:block font-size="18pt"
    ??????????? font-family="mysimkai"
    ??????????? line-height="24pt"
    ??????????? text-align="center"
    ??????????? padding-top="3pt">
    ??????????? 這是楷體
    ????? </fo:block>
    ??? </fo:flow>
    ? </fo:page-sequence>
    </fo:root>


    上述fo文件使用兩種字體分別顯示一行文字,注意在<fo:block>的屬性中的font-family被我們設(shè)成userconfig.xml中相應(yīng)的名字。

    由于需要讀入userconfig.xml來得到字體信息,程序主體修改如下:
    Driver driver = new Driver();
    driver.setInputSource(new InputSource (args[0]));
    driver.setOutputStream(new FileOutputStream(args[1]));
    driver.setRenderer(Driver.RENDER_PDF);
    //讀入配置(在Options的構(gòu)造函數(shù)中完成)
    Options options = new Options(new File("userconfig.xml"));
    driver.run();



    這里在run之前一行讀入配置(產(chǎn)生的Options的實例在以后沒有用處),執(zhí)行結(jié)果為:



    總結(jié)
    FOP從技術(shù)上說無疑是一個非常優(yōu)秀的產(chǎn)品,但是目前它對用戶的開發(fā)支持顯然很欠缺。FOP的開發(fā)小組也意識到了這個問題,他們允諾在將來會建立一個專門的Web站點以及豐富它的文檔。如果現(xiàn)在就想使用更方便的產(chǎn)品的話,你也可以考慮一些商用產(chǎn)品,如RenderX和X2P。

    另外需要注意的是,今年8月推出的FOP 0.20.1版本非常的不好,不但一些范例無法運行,而且附帶的源代碼有若干錯誤,而這個9月29日推出的0.20.2RC版本有極大的改進(jìn),建議大家盡快升級到這個版本。

    參考資料

    FOP主站點 http://xml.apache.org/fop
    FO規(guī)范 http://www.w3.org/TR/xsl/

    關(guān)于作者:
    馬路,2000級清華大學(xué)計算機(jī)系研究生,目前在清華大學(xué)Java應(yīng)用技術(shù)實驗室學(xué)習(xí)。E-mail:stevema@263.net
    posted on 2006-07-24 09:51 The Spark of Thinking 閱讀(677) 評論(1)  編輯  收藏

    評論

    # re: 如何在程序中嵌入FOP (轉(zhuǎn)載) 2006-07-24 09:54 The Spark of Thinking
    xml 與 FOP
    PDF目前最流行的內(nèi)容載體格式,不少公司都將其作為首選的REPORT PRINTING 格式。要將待處理的數(shù)據(jù)轉(zhuǎn)換成PDF文件,如果你不想使用PDF編輯器象寫文章一樣寫出來的話,有幾種方法可以幫助你靈活地根據(jù)數(shù)據(jù)的不同自動生成PDF文件,APACHE 開源項目下的FOP就是其中一個。
    雖然FOP已經(jīng)并不是什么新鮮東西,也不是什么主流技術(shù),其xsl-fo表示語言只是XSLT的輸出格式的一種,不過它可以提取XML中的數(shù)據(jù),按照用戶的需求生成相應(yīng)的PDF文檔,這種應(yīng)用模式使 XSL-FO非常流行。
    FOP應(yīng)用本身并不難,只要按照它的語言規(guī)范去編排格式就是了,不過對于XSLT和XSL-FO不是很熟的朋友來說,一開始如果想要弄個復(fù)雜的PDF樣式可能會痛苦點,特別是目前其中文資料偏少,不少人無從了解其格式使用。本人曾經(jīng)為朋友的系統(tǒng)應(yīng)用過該技術(shù),覺得其功能還是較強(qiáng)的,特別是處理樣式比較復(fù)雜的PDF,當(dāng)然,前提是你有一定的XSLT和XSL-FO應(yīng)用基礎(chǔ)。
    XML顯然是最好的內(nèi)容存儲格式,使用XSL-FO可以輕易的將XML的數(shù)據(jù)按照規(guī)定的格式轉(zhuǎn)換成pdf,mif,pcl,txt等多種格式以及直接輸出到打印機(jī),并且支持使用SVG描述圖形。
    集成后的FOP將是一種強(qiáng)有力的文件生成工具,例如配合原生型XML數(shù)據(jù)庫(Native XML DB)的應(yīng)用,F(xiàn)OP可以直接使用COLLECTION 中的XML文件,生成指定格式的PDF,省時,省力,省錢。

    對FOP有興趣朋友可以參考以下內(nèi)容或跟我討論:
    http://xml.apache.org/fop/embedding.html
      回復(fù)  更多評論
      


    只有注冊用戶登錄后才能發(fā)表評論。


    網(wǎng)站導(dǎo)航:
    博客園   IT新聞   Chat2DB   C++博客   博問  
     
    主站蜘蛛池模板: 偷自拍亚洲视频在线观看99| 在线观看亚洲AV日韩A∨| 亚洲成在人线aⅴ免费毛片| 免费看国产精品3a黄的视频| 亚洲综合丁香婷婷六月香| 9久9久女女免费精品视频在线观看| 久久久久久亚洲AV无码专区| 日本免费在线观看| 性感美女视频在线观看免费精品| 三上悠亚亚洲一区高清| 中文字幕亚洲综合久久| 无码毛片一区二区三区视频免费播放| 国产成人青青热久免费精品| 免费看又黄又爽又猛的视频软件| 无码不卡亚洲成?人片| eeuss影院www天堂免费| 亚洲亚洲人成综合网络| 亚欧免费一级毛片| 伊在人亚洲香蕉精品区麻豆| 免费国产va在线观看| 亚洲乳大丰满中文字幕| 37pao成人国产永久免费视频| 国产啪亚洲国产精品无码| APP在线免费观看视频| 日本久久久久亚洲中字幕| 在线观看av永久免费| 国产成人亚洲精品91专区高清| 亚洲精品高清在线| 日本免费一区二区三区| 亚洲综合精品成人| 亚洲精品无码av天堂| 99在线观看精品免费99| 亚洲人成自拍网站在线观看| 国产精品V亚洲精品V日韩精品| 久久免费动漫品精老司机| 亚洲 日韩 色 图网站| 亚洲精品尤物yw在线影院| 最近免费中文字幕高清大全 | 国产亚洲精品一品区99热| 欧美亚洲精品一区二区| 亚洲人成网亚洲欧洲无码久久|