国产片侵犯亲女视频播放_亚洲精品二区_在线免费国产视频_欧美精品一区二区三区在线_少妇久久久_在线观看av不卡

服務(wù)器之家:專注于服務(wù)器技術(shù)及軟件下載分享
分類導(dǎo)航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術(shù)|正則表達(dá)式|C/C++|IOS|C#|Swift|Android|VB|R語(yǔ)言|JavaScript|易語(yǔ)言|vb.net|

服務(wù)器之家 - 編程語(yǔ)言 - Java教程 - java學(xué)習(xí)之JasperReport踩坑

java學(xué)習(xí)之JasperReport踩坑

2021-03-24 15:27老爺爺 Java教程

本篇文章介紹的是在JAVA學(xué)習(xí)中JasperReport遇到的坑以及解決辦法,有需要的朋友參考下吧。

下面進(jìn)入正題,來(lái)介紹下今天的豬腳JasperReport或者叫它ireport亦或jasperstudio,當(dāng)然后面兩個(gè)是它的可視化工具。

JasperReport是個(gè)什么東西?

這貨其實(shí)在國(guó)內(nèi)用戶也不少,是個(gè)國(guó)外的產(chǎn)品,而且可以說(shuō)在JAVA報(bào)表領(lǐng)域應(yīng)用是相當(dāng)?shù)膹V泛。

我當(dāng)初剛剛接觸這個(gè)報(bào)表的時(shí)候還是相當(dāng)?shù)南矚g的,最主要的是它的可視化工具,真的是讓我欲罷不能,竟然可以通過(guò)簡(jiǎn)單畫圖的方式來(lái)設(shè)計(jì)JAVA報(bào)表。說(shuō)起畫圖就是可以通過(guò)可視化的工具,讓我們可視化的設(shè)計(jì)報(bào)表模板,并且它支持輸出的文件格式很廣泛,包括EXCEL、WORD、PDF、HTML、XML、CSV等等。

看起來(lái)是不是很強(qiáng)大,一次設(shè)計(jì),多次復(fù)用。當(dāng)然強(qiáng)大得的東西,往往都有兩面性,這不就被我遇到了,折磨了我相當(dāng)長(zhǎng)的時(shí)間,后文會(huì)詳細(xì)描述的。

JasperReport的大胸弟

前面我說(shuō),JasperReport或者叫它ireport或jasperstudio,其實(shí)這是不準(zhǔn)確的。二弟ireport、三弟jasperstudio其實(shí)是jasper的輔助視覺設(shè)計(jì)工具,你不用它也能設(shè)計(jì)jasper報(bào)表,多寫點(diǎn)XML白。5.5之前這個(gè)工具叫ireport,5.5之后隨著三弟jasperstudio的出生,ireport就被完全替代了,其實(shí)這兩個(gè)工具基本上是一樣的,一奶同胞。

具體的工作流程:

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

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

java學(xué)習(xí)之JasperReport踩坑

上圖每種類型的band簡(jiǎn)單介紹一下。

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

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

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

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

(5)Detail Band:報(bào)表內(nèi)容段,在這個(gè)Band 中設(shè)計(jì)報(bào)表中需要重復(fù)出現(xiàn)的內(nèi)容,Detail 段中的內(nèi)容每頁(yè)都會(huì)出現(xiàn)。

(6)columnHeader Band:針對(duì)Detail Band的表頭段,一般情況下在這個(gè)段中畫報(bào)表的表頭。

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

(8)Summary Band:表格的合計(jì)段,出現(xiàn)在整個(gè)報(bào)表的最后一頁(yè)中的Detail band 的后面,一般用來(lái)統(tǒng)計(jì)報(bào)表中某一個(gè)或某幾個(gè)字段的合計(jì)值。

上面就是可視化的工具的全部,其實(shí)怎么用很簡(jiǎn)單,上手摸索下就會(huì)了,既然是踩坑實(shí)錄,這個(gè)自然不是重點(diǎn),不說(shuō)了。

代碼中的應(yīng)用

這是我總結(jié)的步驟,可能描述的不是很準(zhǔn)確,大家湊合下

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

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

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

③執(zhí)行報(bào)表(數(shù)據(jù)填充到報(bào)表)

1、 加載模板生成Jasperreport對(duì)象

2、利用JasperFillManager,生成JasperPrint對(duì)象

④最后利用JRXlsxExporter導(dǎo)出類,將報(bào)表導(dǎo)出或者展示

加載模板

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

加載的代碼,返回jasperport對(duì)象

    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!");
    }

獲取報(bào)表中的數(shù)據(jù)源

這里我采用javabean的方式獲取

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

fieldValues 為數(shù)據(jù)庫(kù)中獲取的pojo集合。

執(zhí)行報(bào)表填充

得到j(luò)asperprint對(duì)象

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

最后我們利用JRXlsxExporter導(dǎo)出報(bào)表

這個(gè)也是需要配置參數(shù)最多的一個(gè)地方

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

完成,數(shù)據(jù)已經(jīng)寫入輸出流中了,怎么輸出自己決定,是不是比其他方式代碼簡(jiǎn)介很多。

確實(shí)在代碼書寫中JasperReport有著無(wú)法比擬的優(yōu)勢(shì),各種api已經(jīng)封裝好。但是可能是恰恰做的太多,問(wèn)題也不少。

JasperReport的問(wèn)題

1、兩行前的空白

如果你使用上面的代碼導(dǎo)出EXCEL的話,你會(huì)發(fā)現(xiàn)Excel的背景是白色,沒了Excel一個(gè)個(gè)的小格子,這是因?yàn)閖asper默認(rèn)背景為白色,這樣在導(dǎo)出其他格式時(shí)也好做到兼容,當(dāng)然當(dāng)我們導(dǎo)出EXCEL并不需要。只需要加上下面兩行就可以解決。

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

2、數(shù)據(jù)量很大,title多次寫入

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

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

3、Cell的類型的問(wèn)題

有時(shí)候我們導(dǎo)出的Excel報(bào)表,需要使用Excel的函數(shù)計(jì)算,如果全都是文本格式,自然計(jì)算不了,這種情況下,我們需要使用

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

切記,在報(bào)表設(shè)計(jì)時(shí),F(xiàn)ield字段選擇正確的類型。

4、多Sheet的問(wèn)題

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

只需要將上文中導(dǎo)出步驟換成下面這個(gè)樣子

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

JRExporterParameter.JASPER_PRINT_LIST,傳入一個(gè)listJasperPrint的集合,每個(gè)JasperPrint即一個(gè)Sheet頁(yè)。

5、Linux下啟動(dòng)不報(bào)錯(cuò),但是無(wú)法導(dǎo)出報(bào)表

其實(shí)這個(gè)問(wèn)題也困擾了我很久,后來(lái)在大佬的幫助下才想起來(lái)問(wèn)題所在,因?yàn)樗鼟伋龅母静皇莻€(gè)Exception,而是Error。我看到網(wǎng)上也有同學(xué)問(wèn)這個(gè)問(wèn)題,所以貼出來(lái)。

可以用throwable捕獲,就可以得到錯(cuò)誤信息,報(bào)錯(cuò):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、大數(shù)據(jù)內(nèi)存溢出和內(nèi)存泄露問(wèn)題!!

這里需要說(shuō)一下,EXCEL 03和07版的區(qū)別,03版我記得好像是只支持65532行吧,而07版之后就大的多了,具體數(shù)字我忘了,反正不是一個(gè)數(shù)量級(jí)的。

JRXlsxExporter支持導(dǎo)出xlsx文件,

JRXlsExporter則是xls的文件,很好辨認(rèn),導(dǎo)出的工具和excel的格式一樣。

然后是內(nèi)存溢出和內(nèi)存泄露問(wèn)題,這個(gè)我相信玩JAVA的朋友基本上都遇到過(guò)。

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

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

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

這個(gè)東西是做啥用的呢,其實(shí)它會(huì)根據(jù)你設(shè)置的參數(shù),將數(shù)據(jù)寫到硬盤的臨時(shí)文件上,這樣解決了填充報(bào)表時(shí)內(nèi)存占用過(guò)大溢出的問(wèn)題。

目前JasperReport有3個(gè)仿真器,都是用來(lái)解決這個(gè)問(wèn)題的。

分別是:

①JRFileVirtualizer

②JRSwapFileVirtualizer

③JRGzipVirtualizer

這三個(gè)仿真器又有什么區(qū)別呢?

首先是推出最早的JRFileVirtualizer,我在測(cè)試時(shí),當(dāng)導(dǎo)出30W左右的數(shù)據(jù),就會(huì)報(bào)內(nèi)存溢出,后來(lái)加上這個(gè)后就可以正常導(dǎo)出了。這個(gè)仿真器會(huì)把每一個(gè)對(duì)象生成一個(gè)臨時(shí)文件存放在硬盤上解決內(nèi)存占用的問(wèn)題,但是因?yàn)楫a(chǎn)生的臨時(shí)文件較多,無(wú)形中增加了文件創(chuàng)建和刪除的內(nèi)存消耗,所以并不是很推薦。

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

catchPath為文件緩存路徑,必須真實(shí)存在,否則會(huì)報(bào)錯(cuò)。

然后是JRSwapFileVirtualizer,這個(gè)是為了解決JRFileVirtualizer的問(wèn)題而推出的。這個(gè)仿真器,只會(huì)創(chuàng)建一個(gè)臨時(shí)文件,每個(gè)對(duì)象會(huì)占這個(gè)文件的一部分,所以就減少的文件創(chuàng)建和刪除的內(nèi)存消耗,其實(shí)這個(gè)也不是特別推薦。

//寫單個(gè)文件
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這個(gè),看到Gzip,不知道你是否有聯(lián)系到壓縮這個(gè)詞匯。沒錯(cuò),這個(gè)仿真器就是使用一種特殊的壓縮算法,可以將內(nèi)存占用壓縮到二十分之一還是十分之一來(lái)著,總之很神奇。

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);

說(shuō)了這么多,總之就是三種仿真器解決內(nèi)存溢出問(wèn)題,我也看了很多博客里面寫利用JRFileVirtualizer,解決內(nèi)存大數(shù)據(jù)問(wèn)題。然后我在這里想說(shuō),我最最最不推薦使用JRFileVirtualizer仿真器,因?yàn)樗粌H創(chuàng)建文件消耗大,還有個(gè)很嚴(yán)重的BUG,內(nèi)存泄露!!!還有JRSwapFileVirtualizer也有這個(gè)問(wèn)題。

另外,需要說(shuō)明的是不使用仿真器,也會(huì)有內(nèi)存泄露的問(wèn)題,當(dāng)你導(dǎo)出報(bào)表后,dump出堆棧信息,會(huì)發(fā)現(xiàn)net.sf.jasperreports.engine.fill.JRTemplatePrintText類的實(shí)例特別多,無(wú)法回收,無(wú)法回收!!!并且最新版的japserreport 6.x依舊存在這個(gè)問(wèn)題,在jasper的社區(qū)和Stack Overflow存在很多這樣的問(wèn)題,而沒有解決方案。

這里推薦JRGzipVirtualizer仿真器,雖然依舊存在泄露問(wèn)題,但是因?yàn)楠?dú)特的壓縮算法,已經(jīng)將內(nèi)存泄露問(wèn)題控制在很小的范圍里了,算是一種緩解的方案吧,大概泄露的內(nèi)存占用緩解了九成以上。

總的來(lái)說(shuō),我現(xiàn)在已經(jīng)放棄這種方案了,寫出來(lái)也是為了后來(lái)的兄弟少走彎路。擼了一個(gè)POI的工具類,接下來(lái)準(zhǔn)備把所有的報(bào)表改成POI導(dǎo)出的方式,話說(shuō)POI的大數(shù)據(jù)方案還是挺不錯(cuò)的。

原文鏈接:https://www.cnblogs.com/laoyeye/p/7707149.html

延伸 · 閱讀

精彩推薦
Weibo Article 1 Weibo Article 2 Weibo Article 3 Weibo Article 4 Weibo Article 5 Weibo Article 6 Weibo Article 7 Weibo Article 8 Weibo Article 9 Weibo Article 10 Weibo Article 11 Weibo Article 12 Weibo Article 13 Weibo Article 14 Weibo Article 15 Weibo Article 16 Weibo Article 17 Weibo Article 18 Weibo Article 19 Weibo Article 20 Weibo Article 21 Weibo Article 22 Weibo Article 23 Weibo Article 24 Weibo Article 25 Weibo Article 26 Weibo Article 27 Weibo Article 28 Weibo Article 29 Weibo Article 30 Weibo Article 31 Weibo Article 32 Weibo Article 33 Weibo Article 34 Weibo Article 35 Weibo Article 36 Weibo Article 37 Weibo Article 38 Weibo Article 39 Weibo Article 40
主站蜘蛛池模板: 国产天天操 | 色综合久久久久 | 亚洲网在线 | 亚洲人视频在线 | 国产天天操 | 精品国产乱码久久久久久久软件 | 久久精品一区二区 | 久久久久久亚洲精品 | 羞羞视频免费网站 | 黄色毛片在线视频 | 久久久久综合 | 亚洲国产精品久久久久婷婷老年 | 欧美国产精品一区 | 国产精品成人一区二区三区夜夜夜 | 日韩成人影院 | 成人在线观看网 | 欧美电影在线观看 | 亚洲视频自拍 | 超碰首页| 亚洲免费色| 久久久精品在线 | 成人免费在线观看视频 | 91精品国产一区二区三区免费 | 久久免费精品一区二区三区 | 日韩av一区二区在线观看 | 亚洲专区在线播放 | 欧美精品一区二区三区在线播放 | 色视频网 | 日韩精品视频久久 | 色综合成人 | 精品视频久久 | 国产精品第52页 | 久久xxx | 国产精品久久久久久99999 | 黄色大片在线播放 | 中国a一片一级一片 | 成年人黄色免费网站 | 亚洲精品久久久久久久久久久久久 | 一级黄片毛片 | 国产偷久久9977 | 欧洲精品视频在线观看 |