亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 開發 > Java > 正文

java學習之JasperReport踩坑

2024-07-13 10:17:01
字體:
來源:轉載
供稿:網友

下面進入正題,來介紹下今天的豬腳JasperReport或者叫它ireport亦或jasperstudio,當然后面兩個是它的可視化工具。

JasperReport是個什么東西?

這貨其實在國內用戶也不少,是個國外的產品,而且可以說在JAVA報表領域應用是相當的廣泛。

我當初剛剛接觸這個報表的時候還是相當的喜歡的,最主要的是它的可視化工具,真的是讓我欲罷不能,竟然可以通過簡單畫圖的方式來設計JAVA報表。說起畫圖就是可以通過可視化的工具,讓我們可視化的設計報表模板,并且它支持輸出的文件格式很廣泛,包括EXCEL、WORD、PDF、HTML、XML、CSV等等。

看起來是不是很強大,一次設計,多次復用。當然強大得的東西,往往都有兩面性,這不就被我遇到了,折磨了我相當長的時間,后文會詳細描述的。

JasperReport的大胸弟

前面我說,JasperReport或者叫它ireport或jasperstudio,其實這是不準確的。二弟ireport、三弟jasperstudio其實是jasper的輔助視覺設計工具,你不用它也能設計jasper報表,多寫點XML白。5.5之前這個工具叫ireport,5.5之后隨著三弟jasperstudio的出生,ireport就被完全替代了,其實這兩個工具基本上是一樣的,一奶同胞。

具體的工作流程:

①首先Jasper會獲取需要輸出的格式信息的xml文件,然后從xml文件中編譯出.jasper類型的文件,然后這個jasper文件可以在我們的應用程序中被加載生成最終的報表。有沒有很熟悉的感覺,是的,這一點和java很像,都需要編譯一下。

下圖,就是ireport的操作界面,jasperstudio類似,就不貼了,大家可以自行百度下。

java,JasperReport

上圖每種類型的band簡單介紹一下。

(1)Title band:title段只在整個報表的第一頁的最上面部分顯示,除了第一頁以外,不管報表中共有多少個頁面也不會再出現Title band中的內容。

(2)pageHeader Band:顧名思義,pageHeader 段中的內容將會在整個報表中的每一個頁面中都會出現,顯示在位置在頁面的上部,如果是報表的第一頁,pageHeader 中的內容將顯示在Title Band下面,除了第一頁以外的其他所有頁面中pageHeader中的內容將在顯示在頁面的最上端。

(3)pageFooter Band:顯示在所在頁面的最下端。

(4)lastPageFooter Band:顯示在最后一頁的最下端。

(5)Detail Band:報表內容段,在這個Band 中設計報表中需要重復出現的內容,Detail 段中的內容每頁都會出現。

(6)columnHeader Band:針對Detail Band的表頭段,一般情況下在這個段中畫報表的表頭。

(7)columnFooter Band:針對Detail Band的表尾段。

(8)Summary Band:表格的合計段,出現在整個報表的最后一頁中的Detail band 的后面,一般用來統計報表中某一個或某幾個字段的合計值。

上面就是可視化的工具的全部,其實怎么用很簡單,上手摸索下就會了,既然是踩坑實錄,這個自然不是重點,不說了。

代碼中的應用

這是我總結的步驟,可能描述的不是很準確,大家湊合下

①設計模板,生成JRXML文件,↑↑上面的可視化工具設計你所需要的模板樣式

②編譯模板,JRXML編譯成Jasper文件,就像java中的.java和.class文件一樣,程序中運行的需要是*.jasper的二進制文件。

其實這一步可以直接用ireport編譯生成.jasper,當然也可以在運行時通過jasper程序編譯。但是建議如果在程序中編譯的話,jasper版本最好和ireport或者jasperstudio的版本一致。

③執行報表(數據填充到報表)

1、 加載模板生成Jasperreport對象

2、利用JasperFillManager,生成JasperPrint對象

④最后利用JRXlsxExporter導出類,將報表導出或者展示

加載模板

既然我們已經利用可視化工具生成了.jasper或者.jrxml文件了,自然是需要讓程序加載它。

加載的代碼,返回jasperport對象

    if (urlPath.endsWith(".jrxml")) {      //compile jrxml to jasper      try {        InputStream is = url.openStream();        jasperReport = JasperCompileManager.compileReport(is);      } catch (IOException e) {        throw new BaseException("Load jasper error", e);      } catch (JRException e) {        throw new BaseException("The jrxml template transform to jasper file error", e);      } catch (Throwable e) {        log.error(e);        throw new BaseException(e.getMessage());      }    } else if (urlPath.endsWith(".jasper")) {      try {        InputStream is = url.openStream();        jasperReport = (JasperReport) JRLoader.loadObject(is);      } catch (IOException e) {        throw new BaseException("Load jasper error", e);      } catch (JRException e) {        throw new BaseException("The jrxml template file error", e);      } catch (Throwable e) {        log.error(e);        throw new BaseException(e.getMessage());      }    } else {      throw new BaseException("Invalid file!");    }

獲取報表中的數據源

這里我采用javabean的方式獲取

      JRDataSource dataSource = null;      if (fieldValues != null && fieldValues.size() > 0) {        dataSource = new JRBeanCollectionDataSource(fieldValues);      } else {        dataSource = new JREmptyDataSource();      }

fieldValues 為數據庫中獲取的pojo集合。

執行報表填充

得到jasperprint對象

Map<String, Object> parameterValue = new HashMap<String, Object>();jasperPrint = JasperFillManager.fillReport(jasperReport, parameterValue, dataSource);

最后我們利用JRXlsxExporter導出報表

這個也是需要配置參數最多的一個地方

baos = new ByteArrayOutputStream();exporter = new JRXlsxExporter();exporter.setParameter(JRExporterParameter.JASPER_PRINT, jasperPrint);exporter.setParameter(JRExporterParameter.OUTPUT_STREAM, baos);exporter.exportReport();

完成,數據已經寫入輸出流中了,怎么輸出自己決定,是不是比其他方式代碼簡介很多。

確實在代碼書寫中JasperReport有著無法比擬的優勢,各種api已經封裝好。但是可能是恰恰做的太多,問題也不少。

JasperReport的問題

1、兩行前的空白

如果你使用上面的代碼導出EXCEL的話,你會發現Excel的背景是白色,沒了Excel一個個的小格子,這是因為jasper默認背景為白色,這樣在導出其他格式時也好做到兼容,當然當我們導出EXCEL并不需要。只需要加上下面兩行就可以解決。

      //去除兩行之前的空白       exporter.setParameter(JRXlsExporterParameter.IS_REMOVE_EMPTY_SPACE_BETWEEN_ROWS,Boolean.TRUE);       exporter.setParameter(JRXlsExporterParameter.IS_REMOVE_EMPTY_SPACE_BETWEEN_COLUMNS,Boolean.TRUE);       //設置Excel表格的背景顏色為默認的白色       exporter.setParameter(JRXlsExporterParameter.IS_WHITE_PAGE_BACKGROUND,Boolean.FALSE);

2、數據量很大,title多次寫入

如果你一個Sheet數據很多,可能會遇到表頭多次打印的情況,這種情況下,你需要加上高度設置。

Field pageHeight = JRBaseReport.class.getDeclaredField(          "pageHeight");      pageHeight.setAccessible(true);      pageHeight.setInt(jasperReport, Integer.MAX_VALUE);

3、Cell的類型的問題

有時候我們導出的Excel報表,需要使用Excel的函數計算,如果全都是文本格式,自然計算不了,這種情況下,我們需要使用

 //自動選擇格式 exporter.setParameter(JRXlsExporterParameter.IS_DETECT_CELL_TYPE, Boolean.TRUE);

切記,在報表設計時,Field字段選擇正確的類型。

4、多Sheet的問題

我上面那個簡單的例子,只是一個文件中包含一個Sheet頁,假如我們的需求是一個文件導出多個Sheet怎么辦,別急,這個Japser早已為我們想到了。

只需要將上文中導出步驟換成下面這個樣子

baos = new ByteArrayOutputStream();exporter = new JRXlsxExporter();exporter.setParameter(JRExporterParameter.JASPER_PRINT_LIST, listJasperPrint);exporter.setParameter(JRExporterParameter.OUTPUT_STREAM, baos);//設置為true,即可在一個excel中,每個單獨的jasper對象放入到一個sheet頁中exporter.setParameter(JRXlsExporterParameter.IS_ONE_PAGE_PER_SHEET,Boolean.TRUE);

JRExporterParameter.JASPER_PRINT_LIST,傳入一個listJasperPrint的集合,每個JasperPrint即一個Sheet頁。

5、Linux下啟動不報錯,但是無法導出報表

其實這個問題也困擾了我很久,后來在大佬的幫助下才想起來問題所在,因為它拋出的根本不是個Exception,而是Error。我看到網上也有同學問這個問題,所以貼出來。

可以用throwable捕獲,就可以得到錯誤信息,報錯:java.lang.InternalError: Can't connect to X11 window server using ':0.0' as

解決方法:修改tomcat/bin/catalina.sh 加JAVA_OPTS="$JAVA_OPTS  -Djava.awt.headless=true"

6、大數據內存溢出和內存泄露問題!!

這里需要說一下,EXCEL 03和07版的區別,03版我記得好像是只支持65532行吧,而07版之后就大的多了,具體數字我忘了,反正不是一個數量級的。

JRXlsxExporter支持導出xlsx文件,

JRXlsExporter則是xls的文件,很好辨認,導出的工具和excel的格式一樣。

然后是內存溢出和內存泄露問題,這個我相信玩JAVA的朋友基本上都遇到過。

關于內存溢出最通常的解決辦法便是增大容器的內存,增加tomcat的內存大小,方法大家可以百度,有很多,不重復造輪子了。

這里提醒下,如果你使用的是tomcat的話,windows安裝版,解壓縮版和Linux版的配置方式都是不同的,需要注意下。

這里我需要介紹的是JasperReport的方式,其實JasperReport是對大數據有解決方案的,在很早期的版本便推出了,JRFileVirtualizer的仿真器。

這個東西是做啥用的呢,其實它會根據你設置的參數,將數據寫到硬盤的臨時文件上,這樣解決了填充報表時內存占用過大溢出的問題。

目前JasperReport有3個仿真器,都是用來解決這個問題的。

分別是:

①JRFileVirtualizer

②JRSwapFileVirtualizer

③JRGzipVirtualizer

這三個仿真器又有什么區別呢?

首先是推出最早的JRFileVirtualizer,我在測試時,當導出30W左右的數據,就會報內存溢出,后來加上這個后就可以正常導出了。這個仿真器會把每一個對象生成一個臨時文件存放在硬盤上解決內存占用的問題,但是因為產生的臨時文件較多,無形中增加了文件創建和刪除的內存消耗,所以并不是很推薦。

//寫多個文件 JRFileVirtualizer virtualizer = new JRFileVirtualizer(2, catchPath); Map<String, Object> parameterValue = new HashMap<String, Object>(); parameterValue.put(JRParameter.REPORT_VIRTUALIZER, virtualizer);virtualizer.setReadOnly(true);

catchPath為文件緩存路徑,必須真實存在,否則會報錯。

然后是JRSwapFileVirtualizer,這個是為了解決JRFileVirtualizer的問題而推出的。這個仿真器,只會創建一個臨時文件,每個對象會占這個文件的一部分,所以就減少的文件創建和刪除的內存消耗,其實這個也不是特別推薦。

//寫單個文件RSwapFile arquivoSwap = new JRSwapFile(catchPath, 4096, 25);JRAbstractLRUVirtualizer virtualizer = new JRSwapFileVirtualizer(2, arquivoSwap, true);    Map<String, Object> parameterValue = new HashMap<String, Object>();parameterValue.put(JRParameter.REPORT_VIRTUALIZER, virtualizer);virtualizer.setReadOnly(true);

最后是JRGzipVirtualizer這個,看到Gzip,不知道你是否有聯系到壓縮這個詞匯。沒錯,這個仿真器就是使用一種特殊的壓縮算法,可以將內存占用壓縮到二十分之一還是十分之一來著,總之很神奇。

JRAbstractLRUVirtualizer virtualizer = new JRGzipVirtualizer(2);Map<String, Object> parameterValue = new HashMap<String, Object>();parameterValue.put(JRParameter.REPORT_VIRTUALIZER, virtualizer);jasperPrint = JasperFillManager.fillReport(jasperReport, parameterValue, dataSource);

說了這么多,總之就是三種仿真器解決內存溢出問題,我也看了很多博客里面寫利用JRFileVirtualizer,解決內存大數據問題。然后我在這里想說,我最最最不推薦使用JRFileVirtualizer仿真器,因為它不僅創建文件消耗大,還有個很嚴重的BUG,內存泄露!??!還有JRSwapFileVirtualizer也有這個問題。

另外,需要說明的是不使用仿真器,也會有內存泄露的問題,當你導出報表后,dump出堆棧信息,會發現net.sf.jasperreports.engine.fill.JRTemplatePrintText類的實例特別多,無法回收,無法回收!?。〔⑶易钚掳娴膉apserreport 6.x依舊存在這個問題,在jasper的社區和Stack Overflow存在很多這樣的問題,而沒有解決方案。

這里推薦JRGzipVirtualizer仿真器,雖然依舊存在泄露問題,但是因為獨特的壓縮算法,已經將內存泄露問題控制在很小的范圍里了,算是一種緩解的方案吧,大概泄露的內存占用緩解了九成以上。

總的來說,我現在已經放棄這種方案了,寫出來也是為了后來的兄弟少走彎路。擼了一個POI的工具類,接下來準備把所有的報表改成POI導出的方式,話說POI的大數據方案還是挺不錯的。


注:相關教程知識閱讀請移步到JAVA教程頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
日韩国产中文字幕| 国产91精品久| 91免费精品国偷自产在线| 麻豆国产精品va在线观看不卡| 在线亚洲欧美视频| 不卡av在线播放| 日韩天堂在线视频| 亚洲欧美国产精品| 欧美成人剧情片在线观看| 亚洲黄页视频免费观看| 国产精品日日摸夜夜添夜夜av| 欧美成人久久久| 日本一欧美一欧美一亚洲视频| 国产精品久久色| 一区三区二区视频| 欧美最猛性xxxx| 午夜精品美女自拍福到在线| 亚洲人在线观看| 久久久久久久久久久免费精品| 国产精品xxxxx| 亚洲最大av在线| 亚洲美女av在线播放| 欧美老妇交乱视频| 按摩亚洲人久久| 国产成人a亚洲精品| 91精品国产91久久久久久不卡| 日韩欧美在线看| 国产免费成人av| 成人自拍性视频| 国产精品大陆在线观看| 久热精品视频在线免费观看| 亚洲人成绝费网站色www| 欧美激情极品视频| 欧美日韩亚洲国产一区| 欧亚精品中文字幕| 久久久久日韩精品久久久男男| 亚洲视屏在线播放| 日韩国产在线看| 亚洲男人天堂2019| wwwwwwww亚洲| 欧美成人精品在线观看| 日韩一区二区av| 亚洲色图欧美制服丝袜另类第一页| 欧美性少妇18aaaa视频| 日日摸夜夜添一区| 国产精品情侣自拍| 美日韩丰满少妇在线观看| 日韩欧美国产中文字幕| 亚洲成**性毛茸茸| 欧美怡春院一区二区三区| 日韩欧美中文字幕在线观看| 欧美激情亚洲一区| 欲色天天网综合久久| 欧美性猛交xxxx乱大交极品| 欧美电影免费观看高清完整| 国产日韩在线观看av| 亚洲国产精品久久久久秋霞不卡| 久久99视频精品| 91精品在线一区| 亚洲精品91美女久久久久久久| 国产精品手机播放| 日韩在线不卡视频| 国产亚洲精品一区二555| 久久综合免费视频影院| 97香蕉久久夜色精品国产| 日韩激情在线视频| 少妇高潮久久久久久潘金莲| 欧美激情xxxx| 亚洲专区国产精品| 欧美性猛交丰臀xxxxx网站| 97在线观看免费高清| 日韩成人xxxx| 亚洲人成伊人成综合网久久久| 国产91九色视频| 亚洲精品日韩丝袜精品| 日韩av网址在线观看| 国产精品羞羞答答| 国产精品极品在线| 91成人性视频| 亚洲成人黄色网址| 亚洲xxx大片| 欧美与欧洲交xxxx免费观看| 中文字幕日韩在线视频| 九九精品视频在线| 亚洲欧洲午夜一线一品| 久久综合伊人77777尤物| 一区二区成人av| 性欧美xxxx| 国产精品成人久久久久| 91精品视频专区| 欧美成人一区在线| 精品五月天久久| 日韩精品在线免费观看| 中文字幕久久久| 日韩电影免费在线观看| 欧美精品www在线观看| 日韩免费在线视频| 国产视频在线观看一区二区| 国产精品久久久久一区二区| 96sao精品视频在线观看| 欧美精品在线观看91| 欧美日韩在线一区| 欧美激情视频在线| 亚洲欧美日韩一区在线| 国产精品亚洲综合天堂夜夜| 国产午夜精品全部视频在线播放| 91在线视频成人| 国产视频精品一区二区三区| 97精品国产97久久久久久| 成人福利视频在线观看| 亚洲欧洲美洲在线综合| 欧美野外wwwxxx| 大量国产精品视频| 国产日韩精品电影| 热99精品只有里视频精品| 97国产一区二区精品久久呦| 国产在线精品成人一区二区三区| 亚洲精品第一国产综合精品| 久久久久北条麻妃免费看| 亚洲国产精品国自产拍av秋霞| 亚洲综合第一页| 成人国产精品一区二区| 国产精品第100页| 国产成人鲁鲁免费视频a| 欧美午夜丰满在线18影院| 97久久精品人人澡人人爽缅北| 最新日韩中文字幕| 中文字幕一区二区三区电影| 欧美午夜精品久久久久久久| 亚洲欧美精品中文字幕在线| 91国偷自产一区二区三区的观看方式| 欧美性生交大片免费| 亚洲国产精品国自产拍av秋霞| 精品一区二区三区四区| 国产免费一区二区三区在线能观看| 亚洲美女av在线播放| 成人黄色短视频在线观看| 亚洲美女自拍视频| 国产有码在线一区二区视频| 欧美日韩在线观看视频小说| 国产精品91免费在线| 久久精品国产亚洲一区二区| 国产精品视频免费观看www| 色妞色视频一区二区三区四区| 亚洲人成五月天| 亚洲精品福利免费在线观看| 亚洲成av人乱码色午夜| 一区二区三区四区精品| 蜜臀久久99精品久久久久久宅男| 久久99青青精品免费观看| 日韩在线精品一区| 国产精品激情自拍| 国产日本欧美视频| 久久久噜噜噜久噜久久| 日本aⅴ大伊香蕉精品视频| 亚洲最新视频在线| 日韩成人av在线| 成人av.网址在线网站| 夜夜狂射影院欧美极品| 国内精品免费午夜毛片| 日韩视频在线一区| 欧美特级www| 久久最新资源网| 91精品国产91久久久久久吃药|