Note For Me
          the place I write down my taste of study
          posts - 3,  comments - 13,  trackbacks - 0

          在公司的項目中用JapserReport也做了不少報表了,現在也做個記錄吧,很多東西都從網上而來,總結一下而已。

          注意:本文由 bangke 所撰寫 版權歸屬于bangke  轉載請注明出處

          1.下載不說了,需要JapserReport和iReport,要pdf支持中文的話需要itextasian.jar(google!)
          2.資源:The JasperReports Ultimate Guide.pdf(google!)
           http://jasperreports.sourceforge.net/
           http://plateau.sicool.com (good!)
           源代碼包下面的examples

          3.先集中說一下中文支持問題:
             1)iReport中文顯示:去掉iReport lib目錄下的tinylaf.jar,會丑點兒:)
             2)要在pdf中顯示中文:如下圖設置字體或定義字體
                注意:在iReport中新建一個TextField會自動把pdf字體設為CP1252,需要修改,否則pdf輸出會報錯說找不到字體
          font.gif

          4.明確需求:
            JasperReport(0.5.2)目前支持Tabular形式的報表,分組,子報表
            不支持cross report(交叉表)和單元格合并。

          5.JasperReport簡述:
            JasperReport總的來說采用報表樣式和數據相分離的設計,在報表楊始中定義好和數據源的映射關系,然后在實際應用的時候再用數據源填充樣式得到最終的報表輸出。
            1)數據源:
            在JasperReport中可以定義多種數據源,都實現了dori.jasper.engine.JRDataSource接口。
            接口有兩個方法:
            public boolean next() throws JRException;
            public Object getFieldValue(JRField jrField) throws JRException;
            各個數據源簡介:
            dori.jasper.engine.JRResultSetDataSource封裝了一個java.sql.ResultSet
            dori.jasper.engine.JREmptyDataSource在沒有實際數據源的數據的時候可以使用它
            dori.jasper.engine.data.JRTableModelDataSource封裝了javax.swing.table.TableModel
            dori.jasper.engine.data.JRBeanArrayDataSource封裝了an array of JavaBeans and uses reflection to retrieve report field values.
            dori.jasper.engine.data.JRBeanCollectionDataSource封裝了java.util.Collection of JavaBeans,和上面的JRBeanArrayDataSource用法相像(強烈推薦,我一直都用它)
            簡而言之就是JRDataSource中封裝了一個循環的集合,在報表中一后會通過(屬性名)反射來取得每個數據項的內容
            為什么選擇JRBeanCollectionDataSource后面會解釋。

            構造數據源,采用數據工廠(針對JRBeanCollectionDataSource來說),工廠方法:
           

          public static JRDataSource getJRDataSource(String name,HttpServletRequest request) throws Exception{
              InterCustomerDS ds 
          = null;//InterCustomerDS是一個interface!
              try {
                ds 
          = (InterCustomerDS) Class.forName(name).
                    newInstance();
                ds.createDS(request);
          //這里需要request中的一些parameter來生成數據源
                return new JRBeanCollectionDataSource(ds.getBeanCollection());
              }

              
          catch (ClassNotFoundException ex) {
                
          throw new Exception(ex.getMessage());
              }

              
          catch (IllegalAccessException ex) {
                
          throw new Exception(ex.getMessage());
              }

              
          catch (InstantiationException ex) {
                
          throw new Exception(ex.getMessage());
              }


            }



            一個簡單的數據源需要兩個類,一個POJO,一個InterCustomerDS的實現

            POJO:

          public class TestVO {
            
          private String portfolio;
            
          private String year;
            
          private String period;

            
          public CCSPVO() {
            }

            
          public String getPeriod() {
              
          return period;
            }

            
          public String getPortfolio() {
              
          return portfolio;
            }

            
          public String getYear() {
              
          return year;
            }

            
          public void setPeriod(String period) {
              
          this.period = period;
            }

            
          public void setPortfolio(String portfolio) {
              
          this.portfolio = portfolio;
            }

            
          public void setYear(String year) {
              
          this.year = year;
            }

           }

           

           TestDateSource:

          public class TestDataSource implements InterCustomerDS {

            
          private Collection co;
            
          public CCSPDataSource() {
            }


            
          public void createDS(HttpServletRequest request) throws Exception{
              co
          =new ArrayList();
              
          /*
              這之中做數據庫查詢,然后使用查詢出來的結果生成TestVO,再把TestVO放入co中
              
          */

            }

            
            
          public Object[] getBeanArray() {
              
          return co.toArray();
            }


            
          public Collection getBeanCollection() {
              
          return co;
            }

          }


           

            2)報表樣式:
            JasperReport將一張報表分為了幾個Sections,又叫bands(按照一張報表的內容來劃分的):title, pageHeader, columnHeader, detail, columnFooter, pageFooter, summary, (如果有group的話,還有groupHeader和groupFooter)。用iReport畫報表的工作簡單得說就是把特定的內容放在特定的section中。
            title和summary在整個報表中只顯示一次(不過有個選項可以設置為每頁顯示一次)
            column和page是每頁顯示一次
            detail才是最關鍵的地方,循環顯示數據源的內容,直到全部顯示完為止。
            在樣式中的3個變量:fields,variables,parameters
            fields:從數據源傳入樣式的屬性名(日后通過反射取值使用,所以fields名一定要和數據源中的屬性名一樣!比如使用JRBeanCollectionDataSource的話,fields名就要和javabean中對應的屬性名一樣!)
            parameters:應用程序向報表傳入得非數據源形式的數據。
            variables:對fields,parameters,也包括所有java對象進行合法運算后得到的變量。(通常用做對數據源某個屬性的統計,比如求和什么等等)
           
            具體使用iReport設計報表樣式不說了,網上很多資料.
            需要注意的是
            在報表樣式中可以輸入表達式,也就是合法的java scriptlet
            在JasperReport中存在的都是java object所以某個textfield和對應數據的object類型一定要相同。
            parameters除了iReport默認的那些類型外其實可以使用任何java類型的。
            每個band在print when expression中輸入返回Boolean的表達式可以控制是否顯示
            可以使用group來添加bands,group其實并不需要和某個field對應,也就是說group沒有expression是可以的,只不過又expression的話會按照expression(通常的fields)來動態分組(這里又需要注意,效果上和sql的group by相當,但并不需要在查詢數據源的sql中寫group by, JasperReport回自己幫你做好的)
            在輸出數據的時候可以套用pattern,也就是正則表達式,比如輸出Double的時候使用 #,##0.00 表示金額:1,234.00, #0.00表示1234.00
           
            3)輸出報表
            采用一個Helper類,分別使用不同的方法得到填充了數據源的JasperPrint比如:
            

          public JasperPrint getPrinterbyBeanCollection(File reportFile,Map reportParameters,JRBeanCollectionDataSource bean) throws Exception{
             
          try {
               
          if(!reportFile.exists()){
                 
          throw new Exception("the jasper file is not exist");
               }

               JasperReport jasperReport 
          = (JasperReport) JRLoader.loadObject(reportFile.
                   getPath());
               JasperPrint jasperPrint 
          = JasperFillManager.fillReport(jasperReport,
                   reportParameters, bean);
               
          return jasperPrint;
             }

             
          catch (JRException ex) {
               logger.error(
          "report",ex);
               
          throw new Exception(ex.getMessage());
             }

           }

            
            然后使用JasperPrint得到報表輸出,比如html輸出:
            

          public void htmlExport(JasperPrint print,Map imagesMap,Object out) throws Exception{
              
          try{
                JRHtmlExporter exporter 
          = new JRHtmlExporter();
                exporter.setParameter(JRExporterParameter.JASPER_PRINT, print);
                exporter.setParameter(JRExporterParameter.OUTPUT_WRITER, 
          out);
                exporter.setParameter(JRHtmlExporterParameter.BETWEEN_PAGES_HTML, 
          "");
                exporter.setParameter(JRHtmlExporterParameter.IS_REMOVE_EMPTY_SPACE_BETWEEN_ROWS, Boolean.TRUE);
                exporter.setParameter(JRHtmlExporterParameter.IMAGES_MAP, imagesMap);
                exporter.setParameter(JRHtmlExporterParameter.IMAGES_URI, 
          "image?image=");
                exporter.exportReport();
              }
          catch(Exception ex){
                logger.error(
          "report",ex);
                
          throw new Exception(ex.getMessage());
              }

            }

              
            
           

          6.普通報表開發:
            開發3步驟
            1.定義POJO,寫DataSource查詢數據庫生成一個Collection of POJOs
            2.使用iReport設計報表,定義和POJO屬性一樣的fields等
            3.用戶輸入web頁面及輸出的Servlet開發

          7.SubReport
            其實和普通報表開發一樣,只不過多寫幾個報表樣式,POJO和DateSource。
            關鍵是在masterreport中對子報表的subreport選項卡中的Connection/DataSource Expression要選DataSource,然后填入你子報表的DataSource,當然先要把子報表的DataSource作為parameter傳入masterreport。(這里JasperReport的example全是Connection的example,害的我想了半天,呵呵,實際上在J2EE這個要求解藕程度很高的范圍內將sql寫在報表樣式中是不適合使用的)

          8.最后說說為什么使用JRBeanCollectionDataSource,原因上面其實很多地方都說明了
            1。使用POJO和Collection簡單,規范
            2。充分的解除報表樣式和數據庫之間的耦合,假如我要查詢的sql變了,我只需要修改sql和結果集存入POJO的對應處,報表樣式是不用修改的。

          9.喝咖啡,休息,(其實我更喜歡喝雪碧,呵呵)!                                                                        

                                                                                         本文由 bangke 所撰寫 版權歸屬于bangke  轉載請注明出處

          posted on 2005-04-01 17:14 蚌殼 閱讀(6832) 評論(11)  編輯  收藏 所屬分類: Java In Work

          FeedBack:
          # re: JasperReport Notes
          2005-06-09 17:27 | 有名氏
          總結得非常好!!!  回復  更多評論
            
          # re: JasperReport Notes
          2005-07-21 11:35 | 無名氏
          真TMD好!  回復  更多評論
            
          # re: JasperReport Notes
          2005-08-11 01:05 | 駱駝
          接口InterCustomerDS不存在?  回復  更多評論
            
          # re: JasperReport Notes
          2005-08-11 01:07 | 駱駝
          還有怎么向自定義數據源傳遞參數?謝謝  回復  更多評論
            
          # re: JasperReport Notes
          2005-09-14 09:27 | aron
          子報表用JRBeanCollectionDataSource能不能給個例子
          謝了
          <a href="http://www.8qu.net/register.asp?net=aronzhou">謝謝</a>  回復  更多評論
            
          # re: JasperReport Notes
          2005-11-23 10:58 | 皮皮
          怎么樣才能讓iReport中detail域中的內容不全顯示出來,而是顯示固定的頁數,多余的內容不顯示,少了的話不上空白該怎么實現呢?謝謝了:)

          qq:239566375
          郵箱:alice2331@163.com  回復  更多評論
            
          # re: JasperReport Notes
          2005-11-25 15:57 | shuli
          用JasperReport做交叉報表,
          縱向的值是可以變的
          橫向的值也是可以變的
          這個JasperReport 怎么實現
          高手指教,QQ:349283579 Email:to_liuchao@yahoo.com.cn  回復  更多評論
            
          # ireport問題
          2006-01-18 15:35 | 馬上
          急!!!怎么向自定義數據源傳遞參數?謝謝
            回復  更多評論
            
          # re: JasperReport Notes
          2006-03-09 13:52 | LIUXIAO
          請教各位啦,有交叉報表的例子嗎?我看了一些,可是不太明白,我是剛剛才開始研究Ireport+jasperreport,可以幫我一下嗎?  回復  更多評論
            
          # re: JasperReport Notes
          2006-04-04 16:49 | kelo
          是啊  回復  更多評論
            
          # re: JasperReport Notes
          2006-11-05 19:17 | tercel
          能不能給個具體的例子放在這邊下載,謝謝  回復  更多評論
            

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


          網站導航:
           

          <2006年3月>
          2627281234
          567891011
          12131415161718
          19202122232425
          2627282930311
          2345678

          常用鏈接

          留言簿(4)

          隨筆分類(3)

          隨筆檔案(3)

          搜索

          •  

          最新評論

          閱讀排行榜

          評論排行榜

          主站蜘蛛池模板: 安岳县| 上虞市| 汕头市| 岱山县| 阳谷县| 奎屯市| 夏邑县| 昌江| 普定县| 稻城县| 如皋市| 信阳市| 金乡县| 屏东市| 文水县| 霍州市| 化德县| 红桥区| 庆元县| 武鸣县| 赤峰市| 濉溪县| 铁岭县| 施甸县| 黑龙江省| 上高县| 乐至县| 星子县| 瓮安县| 大化| 游戏| 淳化县| 广昌县| 康定县| 兰西县| 兴宁市| 万荣县| 安化县| 景洪市| 祁连县| 错那县|