亚洲免费在线-亚洲免费在线播放-亚洲免费在线观看-亚洲免费在线观看视频-亚洲免费在线看-亚洲免费在线视频

使用jasperReport實現(xiàn)動態(tài)表頭

系統(tǒng) 1811 0

最近在我公司drp(運營分銷系統(tǒng))開發(fā)中,需要大量報表,由于本人有過jasperReport的開發(fā)經(jīng)驗,所以選用了它,jr確實不錯,開源,可擴展性很好,缺點就是免費的文檔很少,更可氣的是,代碼中的doc少的可憐,基本上沒有參考價值.

?????? 由于我們的產(chǎn)品是用于服裝行業(yè)的,在服裝行業(yè)有一個尺碼組,非常的麻煩,在制作含有尺碼組的報表時,表頭的各種尺碼不能寫死,要從數(shù)據(jù)庫查詢出來.但是,一般的報表工具都是不支持表頭動態(tài)化的(我理解,報表嘛,是呈現(xiàn)給特定人物如老板看的特定內(nèi)容,表頭應(yīng)該是設(shè)計好的,不會經(jīng)常性的更改),jasperReport也是一樣,并不直接支持,細究它的實現(xiàn)過程,我們還是可以擴展從而解決這個問題的.

????? 先看jasperReport的流程圖.

?? ????????從上圖可看到,jrxml文件要通過JRXmlLoader解析為一個JasperDesign的對象,從源碼中可以看出,此對象用java類去描述了報表的整個設(shè)計,比如,columnHeader,detail,columnFooter等等.然后由JasperCompileManager編譯為一個JasperReport對象,其實,如果你用ireport(jasperReport報表的可視化設(shè)計器)制作報表,你完全可以不必理會怎樣生成jaserReport對象.ireport對此有很好的支持.

???????了解了以上過程,我們可以看出,如果要動態(tài)的加入設(shè)計元素,只能在JasperDesign對象中下手.加入需要的動態(tài)元素,我的需求是在columnHeader中加入一個尺碼組的表頭,代碼實現(xiàn)如下.

java 代碼
  1. package ?com.webstone.drp.report.common.dynamicHeader; ??
  2. ??
  3. import ?java.io.File; ??
  4. import ?java.lang.reflect.InvocationTargetException; ??
  5. import ?java.util.Iterator; ??
  6. import ?org.apache.commons.beanutils.BeanUtils; ??
  7. import ?net.sf.jasperreports.engine.JRException; ??
  8. import ?net.sf.jasperreports.engine.JasperCompileManager; ??
  9. import ?net.sf.jasperreports.engine.JasperReport; ??
  10. import ?net.sf.jasperreports.engine.design.JRDesignBand; ??
  11. import ?net.sf.jasperreports.engine.design.JRDesignStaticText; ??
  12. import ?net.sf.jasperreports.engine.design.JasperDesign; ??
  13. import ?net.sf.jasperreports.engine.xml.JRXmlLoader; ??
  14. ??
  15. /** ?
  16. ?*?@author?yaer ?
  17. ?*/ ??
  18. @SuppressWarnings ( "unchecked" ) ??
  19. public ? class ?ReportDesignProcess?{ ??
  20. ???? private ? static ? final ?String?flagTextKey?=? "customFlagText" ; ??
  21. ??
  22. ???? public ? static ?JasperReport?getJasperReport(String?xmlFilePath, ??
  23. ????????????String[][]?sizeGroup)? throws ?JRException?{ ??
  24. ????????JasperDesign?design?=?getJasperDesign(xmlFilePath); ??
  25. ????????JRDesignBand?columnHeader?=?(JRDesignBand)?design.getColumnHeader(); ??
  26. ??
  27. ????????reSetColumnHeaderHeight(columnHeader,?sizeGroup); ??
  28. ????????reSetshapeAndPosition(columnHeader,?sizeGroup); ??
  29. ????????addElementToColumnHeader(columnHeader,?sizeGroup); ??
  30. ???????? return ?JasperCompileManager.compileReport(design); ??
  31. ????} ??
  32. ???? private ? static ?JasperDesign?getJasperDesign(String?filePath) ??
  33. ???????????? throws ?JRException?{ ??
  34. ???????? return ?JRXmlLoader.load( new ?File(filePath)); ??
  35. ????} ??
  36. ???? private ? static ? void ?reSetColumnHeaderHeight(JRDesignBand?columnHeader, ??
  37. ????????????String[][]?sizeGroup)?{ ??
  38. ????????columnHeader.setHeight(columnHeader.getHeight()?*?sizeGroup.length); ??
  39. ????} ??
  40. ???? private ? static ?JRDesignStaticText?getFlagTextInDesign( ??
  41. ????????????JRDesignBand?columnHeader)?{ ??
  42. ???????? return ?(JRDesignStaticText)?columnHeader.getElementByKey(flagTextKey); ??
  43. ????} ??
  44. ???? private ? static ? void ?reSetshapeAndPosition(JRDesignBand?columnHeader, ??
  45. ????????????String[][]?sizeGroup)?{ ??
  46. ????????JRDesignStaticText?flagText?=?getFlagTextInDesign(columnHeader); ??
  47. ????????Iterator<jrdesignstatictext></jrdesignstatictext>?children?=?columnHeader.getChildren() ??
  48. ????????????????.iterator(); ??
  49. ????????JRDesignStaticText?element; ??
  50. ???????? while ?(children.hasNext())?{ ??
  51. ????????????element?=?children.next(); ??
  52. ???????????? if ?(element.getX()?>?flagText.getX())?{ ??
  53. ????????????????element.setX(flagText.getX()?+?flagText.getWidth() ??
  54. ????????????????????????*?sizeGroup[ 0 ].length); ??
  55. ????????????} ??
  56. ???????????? if ?(!flagTextKey.equals(element.getKey()))?{ ??
  57. ????????????????element.setHeight(element.getHeight()?*?sizeGroup.length); ??
  58. ????????????} ??
  59. ????????} ??
  60. ????} ??
  61. ???? private ? static ? void ?addElementToColumnHeader(JRDesignBand?columnHeader, ??
  62. ????????????String[][]?sizeGroup)?{ ??
  63. ????????JRDesignStaticText?flagText?=?getFlagTextInDesign(columnHeader); ??
  64. ????????columnHeader.removeElement(flagText); ??
  65. ???????? for ?( int ?i?=? 0 ;?i?<?sizeGroup.length;?i++)?{ ??
  66. ???????????? for ?( int ?j?=? 0 ;?j?<?sizeGroup[i].length;?j++)?{ ??
  67. ???????????????? try ?{ ??
  68. ????????????????????JRDesignStaticText?newElement?=?(JRDesignStaticText)?BeanUtils ??
  69. ????????????????????????????.cloneBean(flagText); ??
  70. ????????????????????newElement.setText(sizeGroup[i][j]); ??
  71. ????????????????????newElement.setX(flagText.getX()?+?flagText.getWidth()?*?j); ??
  72. ????????????????????newElement.setY(flagText.getY()?+?flagText.getHeight()?*?i); ??
  73. ????????????????????columnHeader.addElement(newElement); ??
  74. ????????????????}? catch ?(IllegalAccessException?e)?{ ??
  75. ????????????????????e.printStackTrace(); ??
  76. ????????????????}? catch ?(InstantiationException?e)?{ ??
  77. ????????????????????e.printStackTrace(); ??
  78. ????????????????}? catch ?(InvocationTargetException?e)?{ ??
  79. ????????????????????e.printStackTrace(); ??
  80. ????????????????}? catch ?(NoSuchMethodException?e)?{ ??
  81. ????????????????????e.printStackTrace(); ??
  82. ????????????????} ??
  83. ????????????} ??
  84. ????????} ??
  85. ????} ??
  86. }??

????? 很遺憾,沒有寫注解,原因是我看了一本書叫<<測試驅(qū)動開發(fā)>>,里面有一句話"意圖導(dǎo)向編程",意思是說,用手段比如容易理解,貼切的類名,方法名,屬性達到讓讀者輕易理解代碼.從而少寫注解,讓代碼更簡捷.如果大家不大明白以上代碼的意思,那就是我寫的不夠好,還要繼續(xù)努力.

  此類只有一個方法,根據(jù)傳來的報表文件路徑和一個二維數(shù)組式的尺碼組生成一個jaserReport的對象.有三個關(guān)鍵方法.重新設(shè)置columnHeader的height;重新設(shè)置靜態(tài)內(nèi)容的形狀和大小,添加新的元素到columnHeader中,其實,這兒有一個不太容易理的東西:類中有一個flagTextKey的屬性,它是標識報表設(shè)計中動態(tài)內(nèi)容的一個樣板元素,為什么要這個樣板元素了,因為用它承載動態(tài)內(nèi)容的樣式,要比在用代碼實現(xiàn)方便的多.請看BeanUtils.coloneBean()方法,實際上是克隆樣板元素對象.

??????? 這個類設(shè)計的太具體于應(yīng)用,應(yīng)該寫成一個抽象方法,讓子類來具體實現(xiàn)加入動態(tài)元素的過程,我相信大家的需求和我不太一樣.由于時間關(guān)系,我沒有仔細考究.畢竟這只是一個參考實現(xiàn).

  最后,在用于ireport畫報表時就要注意了,一呈不變的元素該怎么畫就怎么畫,但樣板元素的位置一定要放好.動態(tài)內(nèi)容起始的位置和樣式就靠它來定義,大多數(shù)時候,它是一個標簽.只不過它的"key"屬性和上面類的"flagTextKey"要保持一致.

  這個話題就到這兒了,我這兒還有一個我包裝的工具類,我們公司的同事都認為對開發(fā)報表有幫助.

java 代碼
  1. package ?com.webstone.drp.report.common; ??
  2. ??
  3. import ?java.util.ArrayList; ??
  4. import ?java.util.Collection; ??
  5. import ?java.util.HashMap; ??
  6. import ?java.util.Map; ??
  7. import ?javax.servlet.http.HttpServletRequest; ??
  8. import ?javax.servlet.http.HttpSession; ??
  9. import ?javax.faces.context.FacesContext; ??
  10. import ?org.apache.commons.lang.ArrayUtils; ??
  11. import ?com.webstone.drp.report.common.dataSource.JRArrayCollectionDataSource; ??
  12. import ?com.webstone.drp.report.common.dynamicHeader.ReportDesignProcess; ??
  13. import ?net.sf.jasperreports.engine.JRException; ??
  14. import ?net.sf.jasperreports.engine.JasperFillManager; ??
  15. import ?net.sf.jasperreports.engine.JasperPrint; ??
  16. import ?net.sf.jasperreports.engine.JasperReport; ??
  17. import ?net.sf.jasperreports.engine.data.JRBeanCollectionDataSource; ??
  18. import ?net.sf.jasperreports.engine.JRDataSource; ??
  19. import ?net.sf.jasperreports.engine.util.JRLoader; ??
  20. ??
  21. /** ?
  22. ?*?使用jasperReport做報表時的工具支持類.有兩個用途,生成jasperPrint對象,和設(shè)置導(dǎo)出時的session ?
  23. ?*? ?
  24. ?*?@author?yaer ?
  25. ?*?@date?2006-8-26? ?
  26. ?*?@modify?date?2006-12-8 ?
  27. ?*/ ??
  28. public ? class ?ReportUtils?{ ??
  29. ???? public ? static ? final ?String?XLS?=? "xls" ; //?導(dǎo)出為xls文件; ??
  30. ???? public ? static ? final ?String?PDF?=? "pdf" ; //?導(dǎo)出為pdf文件; ??
  31. ???? private ? static ? final ?String?JASPER?=? "jasper" ; //?編譯過后的報表文件; ??
  32. ???? private ? static ? final ?String?JRXML?=? "jrxml" ; //?原始的報表文件(xml格式); ??
  33. ???? private ?HttpServletRequest?request; ??
  34. ???? private ?HttpSession?session; ??
  35. ???? private ?String?rootPath; //?報表文件路徑 ??
  36. ??
  37. ???? /** ?
  38. ?????*?在jsf環(huán)境下時構(gòu)造些工具類對象 ?
  39. ?????*? ?
  40. ?????*?@param?context ?
  41. ?????*????????????jsf的上下文對象 ?
  42. ?????*/ ??
  43. ??
  44. ???? public ?ReportUtils(FacesContext?context)?{ ??
  45. ????????request?=?(HttpServletRequest)?context.getExternalContext() ??
  46. ????????????????.getRequest(); ??
  47. ????????session?=?(HttpSession)?context.getExternalContext().getSession( true ); ??
  48. ???????? this .createRootPath(request); //?生成報表文件的絕對路徑 ??
  49. ????} ??
  50. ???? /** ?
  51. ?????*?在其它web環(huán)境下構(gòu)造此工具類對象 ?
  52. ?????*? ?
  53. ?????*?@param?req ?
  54. ?????*????????????request請求對象 ?
  55. ?????*/ ??
  56. ???? public ?ReportUtils(HttpServletRequest?req)?{ ??
  57. ???????? this .request?=?req; ??
  58. ???????? this .session?=?req.getSession(); ??
  59. ???????? this .createRootPath(request); //?生成報表文件的絕對路徑 ??
  60. ????} ??
  61. ???? /** ?
  62. ?????*?獲得報表文件的絕對路徑 ?
  63. ?????*? ?
  64. ?????*?@return?rootPath ?
  65. ?????*/ ??
  66. ???? public ?String?getRootPath()?{ ??
  67. ???????? return ?rootPath; ??
  68. ????} ??
  69. ???? /** ?
  70. ?????*?獲得JasperPrint對象;?jasperPrint對象在jasperReport中是填充了報表數(shù)據(jù)后的一個實體,打印,導(dǎo)出,顯示都要使用它. ?
  71. ?????*?此方法含有java5.0支持的'可變參數(shù)'特性.params其實質(zhì)是一個對象數(shù)組.在調(diào)用些方法時要注意它可能的參數(shù)順序. ?
  72. ?????*?此方法參數(shù)描述: ?
  73. ?????*?1、最多只有四個參數(shù)。 ?
  74. ?????*?2、固定參數(shù)filePath表示報表文件的路徑,為了支持drp系統(tǒng)中動態(tài)尺碼組做表頭的特性,?filePath包括兩類: ?
  75. ?????*????編譯過后的文件擴展名為'.jasper'和未編譯的原始xml文件'.jrxml'; ?
  76. ?????*????若報表中有動態(tài)尺碼組作表頭,則filePath為擴展名是'.jrxml'的文件。 ?
  77. ?????*????若報表中不涉及動態(tài)尺碼組,則filePath為擴展名是'.jasper'的文件。 ?
  78. ?????*?3、可變參數(shù)params的完整列表是(注意順序):Object?obj/Collection?dataSource,String?seprator,String[][]?sizeGroup. ?
  79. ?????*????這三個參數(shù)中,有一個例外,Object?obj/Collection?dataSource必須有一個,此參數(shù)表示填充報表的數(shù)據(jù),可以是一個Collection式的集合, ?
  80. ?????*????也可以是一個model對象(有且只有一個Collection的屬性); ?
  81. ?????*????String?seprator表示分隔符,如果數(shù)據(jù)源是一個Array的集合,則需此參數(shù)。String[][]sizeGroup表款尺碼組的二維數(shù)組。 ?
  82. ?????*? ?
  83. ?????*?@param?filePath ?
  84. ?????*?@param?params ?
  85. ?????*?@return?jasperPrint ?
  86. ?????*/ ??
  87. ???? public ?JasperPrint?getJasperPrint(String?filePath,?Object...?params)?{ ??
  88. ????????JasperReport?jasperReport?=? null ; ??
  89. ???????? try ?{ ??
  90. ???????????? if ?(JASPER.equals(filePath.substring(filePath.indexOf( "." )?+? 1 , ??
  91. ????????????????????filePath.length())))?{ //?jasper式文件的處理 ??
  92. ????????????????jasperReport?=?getReportTemplate(filePath); ??
  93. ????????????} ??
  94. ???????????? if ?(JRXML.equals(filePath.substring(filePath.indexOf( "." )?+? 1 , ??
  95. ????????????????????filePath.length())))?{ //?jrxml式文件的處理 ??
  96. ????????????????jasperReport?=?ReportDesignProcess.getJasperReport(filePath, ??
  97. ????????????????????????(String[][])?params[params.length?-? 1 ]); //?重新設(shè)置表頭,編譯 ??
  98. ????????????????params?=?ArrayUtils.remove(params,?params.length?-? 1 ); //?刪除參數(shù)中的sizeGroup ??
  99. ????????????} ??
  100. ???????????? return ?fillReport(jasperReport,?params); ??
  101. ????????}? catch ?(JRException?e)?{ ??
  102. ????????????e.printStackTrace(); ??
  103. ????????} ??
  104. ???????? return ? null ; ??
  105. ????} ??
  106. ???? /** ?
  107. ?????*?獲得JasperPrint對象;自定義填充報表時的parameter和dataSource.?參數(shù)說明和動態(tài)表頭的用法參考上一方法 ?
  108. ?????*?@param?filePath ?
  109. ?????*?@param?parameter ?
  110. ?????*?@param?dataSource ?
  111. ?????*?@param?sizeGroup ?
  112. ?????*?@return ?
  113. ?????*/ ??
  114. ???? public ?JasperPrint?getJasperPrint(String?filePath,?Map?parameter, ??
  115. ????????????JRDataSource?dataSource,?Object...?sizeGroup)?{ ??
  116. ????????JasperReport?jasperReport?=? null ; ??
  117. ???????? try ?{ ??
  118. ???????????? if ?(sizeGroup.length?==? 0 )?{ ??
  119. ????????????????jasperReport?=?getReportTemplate(filePath); ??
  120. ????????????} ??
  121. ???????????? if ?(sizeGroup.length?==? 1 )?{ ??
  122. ????????????????jasperReport?=?ReportDesignProcess.getJasperReport(filePath, ??
  123. ????????????????????????(String[][])?sizeGroup[sizeGroup.length?-? 1 ]); //?重新設(shè)置表頭,編譯 ??
  124. ????????????} ??
  125. ???????????? return ?JasperFillManager.fillReport(jasperReport,?parameter, ??
  126. ????????????????????dataSource); ??
  127. ????????}? catch ?(JRException?e)?{ ??
  128. ????????????e.printStackTrace(); ??
  129. ????????} ??
  130. ???????? return ? null ; ??
  131. ????} ??
  132. ???? public ? void ?setAttrToPage(JasperPrint?jasperPrint,?String?report_fileName, ??
  133. ????????????String?report_type)?{ ??
  134. ????????session.setAttribute( "REPORT_JASPERPRINT" ,?jasperPrint); ??
  135. ????????session.setAttribute( "REPORT_FILENAME" ,?report_fileName); ??
  136. ????????session.setAttribute( "REPORT_TYPE" ,?report_type); ??
  137. ????} ??
  138. ???? private ?JasperPrint?fillReport(JasperReport?jasperReport,?Object[]?params) ??
  139. ???????????? throws ?JRException?{ ??
  140. ????????Map?parameters?=? null ; ??
  141. ????????JRDataSource?ds?=? null ; ??
  142. ???????? if ?(params.length?==? 0 )?{ ??
  143. ???????????? return ? null ; ??
  144. ????????} ??
  145. ???????? if ?(params.length?==? 1 ?&&?params[ 0 ].getClass()?==?ArrayList. class )?{ //其實質(zhì)是要判斷是否是集合 ??
  146. ????????????ds?=? new ?JRBeanCollectionDataSource((Collection)?params[ 0 ]); ??
  147. ????????} ??
  148. ???????? if ?(params.length?==? 1 ?&&?params[ 0 ].getClass()?!=?ArrayList. class )?{ ??
  149. ????????????ClassAnalysis?ca?=? new ?ClassAnalysis(params[ 0 ]); ??
  150. ????????????parameters?=?ca.getFields(); ??
  151. ????????????ds?=? new ?JRBeanCollectionDataSource(ca.getSet()); ??
  152. ????????} ??
  153. ???????? if ?(params.length?==? 2 ?&&?params[ 0 ].getClass()?==?ArrayList. class )?{ ??
  154. ????????????ds?=? new ?JRArrayCollectionDataSource((Collection)?params[ 0 ], ??
  155. ????????????????????params[ 1 ].toString()); ??
  156. ????????} ??
  157. ???????? if ?(params.length?==? 2 ?&&?params[ 0 ].getClass()?!=?ArrayList. class )?{ ??
  158. ????????????ClassAnalysis?ca?=? new ?ClassAnalysis(params[ 0 ]); ??
  159. ????????????parameters?=?ca.getFields(); ??
  160. ????????????ds?=? new ?JRArrayCollectionDataSource(ca.getSet(),?params[ 1 ] ??
  161. ????????????????????.toString()); ??
  162. ????????} ??
  163. ???????? return ?JasperFillManager.fillReport(jasperReport, ??
  164. ????????????????parameters?==? null ??? new ?HashMap()?:?parameters,?ds); ??
  165. ????} ??
  166. ???? private ? void ?createRootPath(HttpServletRequest?request)?{ ??
  167. ????????rootPath?=?request.getSession().getServletContext().getRealPath( "/" ) ??
  168. ????????????????+? "WEB-INF\\classes\\com\\webstone\\drp\\report\\jaser\\" ; ??
  169. ????} ??
  170. ???? private ?JasperReport?getReportTemplate(String?jasperPath) ??
  171. ???????????? throws ?JRException?{ ??
  172. ???????? return ?(JasperReport)?JRLoader.loadObject(rootPath?+?jasperPath); ??
  173. ????} ??
  174. } ??
   此類用于生成填充后報表對象jasperPrint.

使用jasperReport實現(xiàn)動態(tài)表頭


更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯(lián)系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發(fā)表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 久久精品国产免费中文 | 精品国产一区二区三区2021 | 欧美一级成人 | 一区二区在线 | 日韩一区国产二区欧美三区 | 884hutv四虎永久黄网 | 欧美成人免费观看国产 | 国产一区二区三区在线观看免费 | aaa一级黑人毛片 | www.黄网站| 久久亚洲精品中文字幕二区 | 婷婷在线观看网站 | 2021最新国产成人精品免费 | 中文字幕不卡在线播放 | 亚洲伦理一二三四 | 国产精品中文字幕在线观看 | 国产大毛片 | 国内精品久久久久久中文字幕 | 伊人黄网 | 中文字幕在线观看不卡视频 | 国产免费不卡v片在线观看 国产免费不卡视频 | 天天狠狠色综合图片区 | 松永纱奈在线观看 | 免费一级黄色片 | 日日干夜夜艹 | 日本不卡在线视频高清免费 | 高清视频 一区二区三区四区 | 欧美一级毛片免费高清aa | 久久精品国产一区二区三区肥胖 | 波多野结衣精品中文字幕 | 国产伦精品一区三区视频 | 欧美 激情 在线 | 曰本女人色黄网站 | 日韩免费大片 | 性做爰片视频毛片 | 色爱区综合 | 中文字幕免费视频 | 欧美成人精品高清在线观看 | 免费看一级欧美毛片 | 欧美一级毛片免费高清的 | 日韩一区二区久久久久久 |