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

          在公司的項目中用JapserReport也做了不少報表了,現(xiàn)在也做個記錄吧,很多東西都從網(wǎng)上而來,總結(jié)一下而已。

          注意:本文由 bangke 所撰寫 版權(quán)歸屬于bangke  轉(zhuǎn)載請注明出處

          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中顯示中文:如下圖設(shè)置字體或定義字體
                注意:在iReport中新建一個TextField會自動把pdf字體設(shè)為CP1252,需要修改,否則pdf輸出會報錯說找不到字體
          font.gif

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

          5.JasperReport簡述:
            JasperReport總的來說采用報表樣式和數(shù)據(jù)相分離的設(shè)計,在報表楊始中定義好和數(shù)據(jù)源的映射關(guān)系,然后在實際應(yīng)用的時候再用數(shù)據(jù)源填充樣式得到最終的報表輸出。
            1)數(shù)據(jù)源:
            在JasperReport中可以定義多種數(shù)據(jù)源,都實現(xiàn)了dori.jasper.engine.JRDataSource接口。
            接口有兩個方法:
            public boolean next() throws JRException;
            public Object getFieldValue(JRField jrField) throws JRException;
            各個數(shù)據(jù)源簡介:
            dori.jasper.engine.JRResultSetDataSource封裝了一個java.sql.ResultSet
            dori.jasper.engine.JREmptyDataSource在沒有實際數(shù)據(jù)源的數(shù)據(jù)的時候可以使用它
            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中封裝了一個循環(huán)的集合,在報表中一后會通過(屬性名)反射來取得每個數(shù)據(jù)項的內(nèi)容
            為什么選擇JRBeanCollectionDataSource后面會解釋。

            構(gòu)造數(shù)據(jù)源,采用數(shù)據(jù)工廠(針對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來生成數(shù)據(jù)源
                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());
              }


            }



            一個簡單的數(shù)據(jù)源需要兩個類,一個POJO,一個InterCustomerDS的實現(xiàn)

            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();
              
          /*
              這之中做數(shù)據(jù)庫查詢,然后使用查詢出來的結(jié)果生成TestVO,再把TestVO放入co中
              
          */

            }

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


            
          public Collection getBeanCollection() {
              
          return co;
            }

          }


           

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

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

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

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

                                                                                         本文由 bangke 所撰寫 版權(quán)歸屬于bangke  轉(zhuǎn)載請注明出處

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

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

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

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


          網(wǎng)站導(dǎo)航:
           

          <2005年4月>
          272829303112
          3456789
          10111213141516
          17181920212223
          24252627282930
          1234567

          常用鏈接

          留言簿(4)

          隨筆分類(3)

          隨筆檔案(3)

          搜索

          •  

          最新評論

          閱讀排行榜

          評論排行榜

          主站蜘蛛池模板: 山东省| 读书| 平塘县| 昌乐县| 安阳市| 小金县| 鄂伦春自治旗| 遵义市| 清苑县| 无为县| 南乐县| 万荣县| 德化县| 垦利县| 禹州市| 桐乡市| 乡宁县| 怀柔区| 格尔木市| 阿图什市| 永昌县| 拉萨市| 青川县| 获嘉县| 邮箱| 赤水市| 逊克县| 富民县| 南昌市| 乌鲁木齐县| 信宜市| 北票市| 田阳县| 台南县| 松原市| 湛江市| 镇巴县| 渭南市| 同仁县| 昔阳县| 富阳市|