2009年9月29日

          前次,我曾經(jīng)介紹過可以通過使用JRBeanCollectionDataSource()返回一個JRDataSource,當時javabean 的數(shù)據(jù)類型都是原始類型,不曾碰到過使用集合類的復合javabean。這次考慮仍然使用javabean 來構(gòu)造數(shù)據(jù)源,由于對ireport的datasource的處理機制不是很熟悉,經(jīng)過很多次嘗試后才摸索出一個往子報表插入特定數(shù)據(jù)源的辦法(不是傳遞父報表的數(shù)據(jù)源,而是將父報表的一個變量當成數(shù)據(jù)源傳遞給子報表?。?/p>

          DEMO:

          準備工作:

          一、程序準備:

          1、 創(chuàng)建復合javabean :MainVO.java:(getter和setter方法自寫)

           

          package com.test;

          import java.util.List;

          public class MainVO {

              private String title;

              private String time;

              private List<SubVO> subList;

          }

           

          2、 創(chuàng)建子表javabean:SubVO.java(getter和setter方法自寫)

           

          package com.test;

          public class SubVO {

          private String name;

           

          3、 創(chuàng)建JRAbstractBeanDataSourceProvider:TestSubReport.java

           

          package com.test;

          public class TestSubReport extends JRAbstractBeanDataSourceProvider {

              public TestSubReport() {

                 super(MainVO.class);

              }

              public JRDataSource create(JasperReport arg0) throws JRException {

                 /**

                 *測試數(shù)據(jù),在使用中,不需要繼承JRAbstractBeanDataSourceProvider,

                 *只需要把集合類封裝到JRBeanCollectionDataSource中就可以了

                 **/

                 List<MainVO> mainList = new ArrayList<MainVO>();

                  List<SubVO> list = new ArrayList<SubVO>();

                 MainVO vo;

                  /**測試數(shù)據(jù)自寫*/

                  ……

                 return new JRBeanCollectionDataSource(mainList);

              }

           

          4、 創(chuàng)建外部測試類:TestMain.java:

           

          public static void main(String[] args) {

          String filename = "bin/SubReport.jasper";

          String outFileName = "bin/Out.html";

          /**測試數(shù)據(jù)mainList自寫*/

          try {

          JasperPrint print = JasperFillManager.fillReport(filename, new HashMap(),new JRBeanCollectionDataSource(mainList));

              JRExporter exporter = new JRHtmlExporter();

               exporter.setParameter(JRExporterParameter.OUTPUT_FILE_NAME,          outFileName);

              exporter.setParameter(JRExporterParameter.JASPER_PRINT, print);

              exporter.exportReport();

                 } catch (JRException e) {

                     e.printStackTrace();

                 }

              }

           

          5、 創(chuàng)建Scriptlet:reportScriptlet.java

          注意: 如果你從父報表傳給子報表的數(shù)據(jù)源是個集合類型,且不需要任何的數(shù)據(jù)處理,這步可以省略,但需要注意我在第二部分的第7步驟的提示。

          該類是用來進行類型轉(zhuǎn)換的,要想讓jasperreports識別數(shù)據(jù)源就必須把集合類封裝到JRDataSource中。由于父報表把數(shù)據(jù)源傳遞給子報表是在afterDetailEval()方法之后,因此只需要重寫該方法:

           

          package com.test;

          public class reportScriptlet extends JRAbstractScriptlet {

              /**其余方法省略*/

              @Override

              public void afterDetailEval() throws JRScriptletException {

                 System.out.println("afterDetailEval...");

                 List subList = (List)getFieldValue("subList");

                 JRDataSource jr = new JRBeanCollectionDataSource(subList);

                 /**

                 *該值是在父報表中定義的一個變量Variables,

                 *類型為net.sf.jasperreports.engine.JRDataSource

                   *(需要手動填寫Class Type)

                 **/

                   setVariableValue("other", jr);

              }

          }

           

               該Scriptlet供父報表使用

          二、報表準備

                 由于ireport的漢化很不完整,這里就使用英文的界面做demo(有興趣漢化的,可以編輯位于ireport.jar包的it.businesslogic.ireport.locale下的Ireport_zh_CN.properties)。

          1、 創(chuàng)建父報表:SubReport.jrxml,通過菜單欄:Data -->Connections /Datasources -->new選擇JRDataSourceProvider定義如圖:

          利用復合的javabean構(gòu)造基于jasperreports的子報表(轉(zhuǎn)) - 涸轍之魚 - 涸轍之魚

                                 Test 成功后(前提是先在ireport的classpath中設(shè)置工程編譯文件夾路徑)save。

          2、 設(shè)置另一個數(shù)據(jù)源(給子報表用)在這里我選擇了使用Custom JRDataSource

          利用復合的javabean構(gòu)造基于jasperreports的子報表(轉(zhuǎn)) - 涸轍之魚 - 涸轍之魚

                              使用Custom JRDataSource這里我必須在項目中編寫一個額外的類用于測試:

                   

           

          package com.test;

          public class CRDSFactory{

              public static JRDataSource createDatasource(){

              List<SubVO> list = new ArrayList<SubVO> ();

              /**測試數(shù)據(jù)自寫*/

                  ……

              return new JRBeanCollectionDataSource(list);

              }

          }

           

                               Test 成功后 save。

          3、 注冊字段Fileld

          利用菜單中的Data --> Report Query -->DataSource Provider 獲取字段,然后全選獲取到的字段點擊確認注冊。

          利用復合的javabean構(gòu)造基于jasperreports的子報表(轉(zhuǎn)) - 涸轍之魚 - 涸轍之魚

               

          4、 添加變量Variables

          該變量用途是作為父報表傳遞給子報表的數(shù)據(jù)源,所以類型為JRDataSource

                              如圖:

          利用復合的javabean構(gòu)造基于jasperreports的子報表(轉(zhuǎn)) - 涸轍之魚 - 涸轍之魚

          5、 創(chuàng)建子報表: SubReport_subreport0.jrxml,(名字由系統(tǒng)生成) 點擊工具欄中的”SubReport”圖標,并確定好子報表的位置,利用系統(tǒng)的wizard一步一步設(shè)置,注意在第2步設(shè)置”Connection/Datasource ”時最好選擇”no connection or datasource”,因為我們的datasource是父報表中的一個變量)

          6、 將ireport的Files視窗的其他報表文件關(guān)閉(大概需要這樣,前幾次因為沒關(guān)閉出了點問題,不清楚什么原因)如果看不到Files視窗,可以通過菜單的View --> Docking panes -->Files 回顯。單獨選擇剛才為該子報表而設(shè)置的數(shù)據(jù)源“custds”,通過剛才的Report Query -->JavaBean Data Source讀取子報表相關(guān)的javabean屬性。選擇后點ok將其注冊到Fields中。如圖:

          利用復合的javabean構(gòu)造基于jasperreports的子報表(轉(zhuǎn)) - 涸轍之魚 - 涸轍之魚

          7、 打開父報表,在設(shè)計窗口的子報表上右鍵,選擇Properties -->SubReport,設(shè)置由父報表傳遞給子報表的數(shù)據(jù)源:

                   

          利用復合的javabean構(gòu)造基于jasperreports的子報表(轉(zhuǎn)) - 涸轍之魚 - 涸轍之魚

                            提示:如果你略過了第一部分的第5步,這里的“ $V{other} ”要改成“ new  net.sf.jasperreports.engine.data.JRBeanCollectionDataSource($V{other})”

          8、 依次編譯(使用動態(tài)連接)子報表、父報表(注意數(shù)據(jù)源的對應關(guān)系),如果能通過父報表看到子報表的內(nèi)容被填充,則說明測試成功了!如果不成功,檢查剛才設(shè)置是否有遺漏的地方,最好重新創(chuàng)建子報表,有時并不是我們設(shè)置問題,ireport目前還不是很穩(wěn)定,在編譯和保存數(shù)據(jù)時很容易出錯,有時連子報表都不認-_-!!

          9、

                             效果圖:(沒有修飾,確實很難看…)

                    

          利用復合的javabean構(gòu)造基于jasperreports的子報表(轉(zhuǎn)) - 涸轍之魚 - 涸轍之魚

                           注意事項:

          ?        熟悉jaspereports的以手動編輯代碼為主, ireport為輔,使用ireport時有時也必須手動編輯jasperreport,特別是在編譯出錯的時候。

          ?       不能把父報表的一個變量同時傳遞給多個子報表,不然可能只能顯示一個或什么都不顯示,如果需要這么做,請定義多個變量。

          ?      子報表的添加不要用舊報表,即使你的舊報表是剛才使用的子報表。

          ?      如果子報表還要嵌套子報表的話,可以通過為子報表編寫一個Scriptlet實現(xiàn)。

                                              不過要清楚的是子報表有可能不執(zhí)行afterDetailEval()和beforeDetailEval()(比如使用jdbc連 接,這也許跟子報表的數(shù)據(jù)源選擇有關(guān)),最好先測試,具體原因希望達人告知!

          ?     在使用ireport進行開發(fā)時,當修改了某個類時,就需要重啟ireport才能看到修改的效果,即使是使用ireport的Scriptlet編輯器也一樣。

          ?     不是越高版本越好用,主要是缺少使用文檔,連javadoc

          posted @ 2009-09-29 09:01 caihaibo 閱讀(1434) | 評論 (0)編輯 收藏
          主站蜘蛛池模板: 安福县| 上犹县| 托里县| 河北区| 拉孜县| 遂川县| 清苑县| 延津县| 东安县| 上思县| 浦县| 天等县| 木里| 清原| 崇左市| 醴陵市| 武义县| 凌源市| 游戏| 龙里县| 湖南省| 抚远县| 玉龙| 驻马店市| 辽阳市| 镇安县| 桐乡市| 宣汉县| 广西| 泗洪县| 崇阳县| 抚宁县| 泗水县| 南雄市| 会泽县| 府谷县| 锦屏县| 台中县| 合水县| 云阳县| 白玉县|