ireport打印PDF報表(數據源java bean、List)

最近有個需求,做一個類似如下的報表,打印pdf版。下面的是excel模板,採用的是傳統的方式,替換參數,出現的問題有換行和翻頁顯示不全。所以準備使用ireport工具畫一個模板。

 使用工具:JasperSoft studio,因爲ireport 只支持jdk1.7及以下的。現在生產環境大部分都是1.8+,所以查詢一些資料,發現現在他的升級產品就是jaspersoft .這個工具界面類似eclipse,基本操作這裏不做介紹,只說一些常見問題,下面是我畫的模板

上面大的表頭是一些零碎的參數,下面的是一些子報表,裏面的數據是動態的。 

1:因爲我的數據是後端傳過來的,所以這個模板我結合提供接口參數(list),準備將這個表的數據自定義一個實體,類似下面

 零碎參數用map,子報表數據用list(類型是util.List)(模板定義字段要跟後端保持一致,字段名稱首字母不要大寫。會出現問題)

參數放在parameters裏面,list放在Fields裏面,如下:

2:後端核心代碼

 List<ReimbursePdfVo> mainList = new ArrayList<ReimbursePdfVo>();
            ReimbursePdfVo pdfVo = new ReimbursePdfVo();
           
            //map作爲報表數據源
            Map<String, Object> parameters = new HashMap<String, Object>();
            //。。。零碎數據封裝

//list數據封裝 
 //差旅費用報銷誠信承諾
                if (company.isReimburseSubsidyPromise()) {
                    Staff staff = staffRepository.findByStaffId(reimburse.getStaffId());
                    List<ReimburseSubsidyPromise> reimburseSubsidyPromises = reimburseSubsidyPromiseRepository.findAllByReimburseId(reimburse.getReimburseId());
                    if (reimburseSubsidyPromises != null && reimburseSubsidyPromises.size() > 0) {
                        List<ClfbxcxcnVo> ClfbxcxcnVoList = new ArrayList<>();
                        reimburseSubsidyPromises.forEach(reimburseSubsidyPromise -> {
                            ClfbxcxcnVo clfbxcxcnVo = new ClfbxcxcnVo();
                            clfbxcxcnVo.setStaffUserName(staff.getStaffUserName());
                            clfbxcxcnVo.setStaffType(StaffTypeNumber.setValue(staff.getStaffType()));
                            clfbxcxcnVo.setFromTime(reimburseSubsidyPromise.getStartDate());//------開始時間
                            clfbxcxcnVo.setEndTime(reimburseSubsidyPromise.getEndDate());//--------結束時間
                            clfbxcxcnVo.setOfferCarStr(reimburseSubsidyPromise.getOfferCar() ? "是" : "否");
                            clfbxcxcnVo.setOfferMealStr(reimburseSubsidyPromise.getOfferMeal() ? "是" : "否");
                            clfbxcxcnVo.setOfferHotelStr(reimburseSubsidyPromise.getOfferAccommodation() ? "是" : "否");
                            ClfbxcxcnVoList.add(clfbxcxcnVo);
                        });
                        pdfVo.setClfbxcxcnList(ClfbxcxcnVoList);
                    }
                }


 mainList.add(pdfVo);

 String mainjrxmlPath = DocumentPrintComponent.class.getResource("/template/jrxml/burise_main_test.jrxml").getPath();
            String burise_sub_grzf_Path = DocumentPrintComponent.class.getResource("/template/jrxml/burise_sub_grzf.jrxml").getPath();//個人支付
            String burise_sub_dgzf_Path = DocumentPrintComponent.class.getResource("/template/jrxml/burise_sub_dgzf.jrxml").getPath();//對公支付
            String burise_sub_csjjt_Path = DocumentPrintComponent.class.getResource("/template/jrxml/burise_sub_csjjt.jrxml").getPath();//城市間交通


            String mainjasperPath = DocumentPrintComponent.class.getResource("/template/jasper/burise_main_test.jasper").getPath();
            String jasper_burise_sub_grzf_Path = DocumentPrintComponent.class.getResource("/template/jasper/burise_sub_grzf.jasper").getPath();//個人支付
            String jasper_burise_sub_dgzf_Path = DocumentPrintComponent.class.getResource("/template/jasper/burise_sub_dgzf.jasper").getPath();//對公支付
            String jasper_burise_sub_csjjt_Path = DocumentPrintComponent.class.getResource("/template/jasper/burise_sub_csjjt.jasper").getPath();//城市間交通

 //編譯jrxml生產jasper文件
            JasperCompileManager.compileReportToFile(mainjrxmlPath, mainjasperPath);
            JasperCompileManager.compileReportToFile(burise_sub_grzf_Path, jasper_burise_sub_grzf_Path);//個人支付
            JasperCompileManager.compileReportToFile(burise_sub_dgzf_Path, jasper_burise_sub_dgzf_Path);//對公支付
            JasperCompileManager.compileReportToFile(burise_sub_csjjt_Path, jasper_burise_sub_csjjt_Path);//城市間交通
            JasperPrint jasperPrint = JasperFillManager.fillReport(mainjasperPath, parameters, new JRBeanCollectionDataSource(mainList));
//            JasperExportManager.exportReportToPdfFile(jasperPrint, "D:/HTML/burisePrint(" + reimburse.getReimburseId() + ").pdf");   //生成本地pdf
            byte[] by = JasperExportManager.exportReportToPdf(jasperPrint);
            return by;

代碼可以導出pdf文件(註釋處 是導出pdf文件),也可以以流的形式返回。可以根據自己的情況使用。

打印效果如下:

其中遇到的一些問題:

1:因爲需求模板(excel)上下面子表的數據都是動態的,可能多行,起初只知道把數據放在detail裏面他就能動態遍歷,但是我有多個子表,只能讓數據動態遍歷,表頭合計什麼的不能循環。(查詢資料,使用subreport子報表可以實現,子報表裏面相當於是一個新的模板,我只保留需要的屬性,比如title, column header,detail,summary,foot page),將子報表裏面懂得數據放在detail,不需要循環的放外面,如果有合計功能,最好放在summary裏面,我起初是在coulmn header還是title裏面 寫的表達式,但是出現的問題是隻能合計當前頁面的,如果翻頁之後,就不會合計後面數據。

2:中文問題,默認的jar是不支持中文的,我是自己打的jar添加到項目和工具的,這個網上有很多方法,目前嘗試成功的字體是華文宋體(STSONG.TTF),自己後期嘗試以同樣的方式添加微軟雅黑,但是沒有成功,可能是工具問題bug,也可能是緩存吧。

3:換行問題,因爲我的這個表格是我用static text和text field拼成的,所以,可能某一列換行的時候,別的列不會換行然後會有對不齊的現象。首先某個各自換行的屬性設置是:Stretch with Overflow,需要勾上。想要同行的每一個各自同高度的話,需要設置每個格子的屬性stretch type:relatice to band height。如下

4:翻頁每頁留白的問題, 如下:(我這個是已經調整過的,初期可能會有很大的空白),自己也不清楚,明明已經設置過翻頁了,也確實生效了,但是爲什麼還會留有那麼大的,自己嘗試着又添加了幾條數據,他就排在下面了,那爲什麼在他還有區域可以排列的時候,沒有將第二頁的表頭排上來呢。

我的解決方法是,我覺得是模板設計的問題,每個子報表的margin  上下左右我都設置0了,所以如果排列的話,每個字表肯定是緊密拼在一起的,那麼問題可能是主模板的,我的大模板是如文章上面第一張圖的,我想到的不確定因素是主模板在設置每一個子模板的detail band的高度,應該給多少合適,每一個子報表的高度我是不確定的,因爲他的數據是動態遍歷的 ,這個外層的detail band應該給多少合適,問了一些技術羣也沒人能回答上,網上也沒有想要的答案,自己嘗試的做法是,我給每一個detail band一個最小值,也就是subreport裏面 已知固定的高度,比如title 和column header的高度。下面detail的 不知道先不管,外層的高度就設置成這兩個高度之和。這樣主模板的排列我想應該會盡可能“更”緊湊了,因爲假如子模板的內容沒有撐滿外層detail band的高度,剩餘的內容區域會以空白填充。就這

5:精度 (千分位,保留兩位小數)

這個就是看這個工具的熟練度,可能知道肯定支持但是不好找,在下面位置:

6:合計功能 (使用表達式)     操作如下:其他的設置按照默認的

 

7: 待續。。。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章