概述與安裝使用
1. PDF報表概述
概述
在企業級應用開發中,報表生成、報表打印下載是其重要的一個環節。在之前的課程中我們已經學習了報表中比較重要的一種:Excel報表。其實除了Excel報表之外,PDF報表也有廣泛的應用場景,例如貨運詳情,貨運單等。
常見PDF報表的制作方式
目前世面上比較流行的制作PDF報表的工具如下:
- iText PDF:iText是著名的開放項目,是用於生成PDF文檔的一個java類庫。通過iText不僅可以生成PDF或rtf的文檔,而且可以將XML、Html文件轉化為PDF文件。
- Openoffice:openoffice是開源軟件且能在windows和linux平台下運行,可以靈活的將word或者Excel轉化為PDF文檔。
- Jasper Report:是一個強大、靈活的報表生成工具,能夠展示豐富的頁面內容,並將之轉換成PDF
JasperReport框架的介紹
JasperReport是一個強大、靈活的報表生成工具,能夠展示豐富的頁面內容,並將之轉換成PDF,HTML,或者XML格式。該庫完全由Java寫成,可以用於在各種Java應用程序,包括J2EE,Web應用程序中生成動態內容。只需要將JasperReport引入工程中即可完成PDF報表的編譯、顯示、輸出等工作。
在開源的JAVA報表工具中,JASPER Report發展是比較好的,比一些商業的報表引擎做得還好,如支持了十字交叉報表、統計報表、圖形報表,支持多種報表格式的輸出,如PDF、RTF、XML、CSV、XHTML、TEXT、DOCX以及OpenOffice。
數據源支持更多,常用 JDBC SQL查詢、XML文件、CSV文件 、HQL(Hibernate查詢),HBase,JAVA集合等。還允許你義自己的數據源,通過JASPER文件及數據源,JASPER就能生成最終用戶想要的文檔格式。

JasperReport生命周期(重點)
通常我們提到PDF報表的時候,浮現在腦海中的是最終的PDF文檔文件。在JasperReports中,這只是報表生命周期的最后階段。通過JasperReports生成PDF報表一共要經過三個階段,我們稱之為 JasperReport的生命周期,這三個階段為:設計(Design)階段、執行(Execution)階段以及輸出(Export)階段,如下圖所示:

- 設計階段(Design):定義模板
所謂的報表設計就是創建一些模板,模板包含了報表的布局與設計,包括執行計算的復雜公式、可選的從數據源獲取數據的查詢語句、以及其它的一些信息。模板設計完成之后,我們將模板保存為JRXML文件(JR代表JasperReports),其實就是一個XML文件。 - 執行階段(Execution):模板 + 數據
使用以JRXML文件編譯為可執行的二進制文件(即.Jasper文件)結合數據進行執行,填充報表數據 - 輸出階段(Export):展示。 將模板和數據一起展示。
數據填充結束,可以指定輸出為多種形式的報表
JasperReport執行流程(重點+)

- JRXML:報表填充模板,本質是一個XML.
JasperReport已經封裝了一個dtd,只要按照規定的格式寫這個xml文件,那么jasperReport就可以將其解析最終生成報表,但是jasperReport所解析的不是我們常見的.xml文件,而是.jrxml文件,其實跟xml是一樣的,只是后綴不一樣。 - Jasper:由JRXML模板編譯生成的二進制文件,用於代碼填充數據。
解析完成后JasperReport就開始編譯.jrxml文件,將其編譯成.jasper文件,因為JasperReport只可以對.jasper文件進行填充數據和轉換,這步操作就跟我們java中將java文件編譯成class文件是一樣的 - .Jrprint:當用數據填充完Jasper后生成的文件,用於輸出報表。
這一步才是JasperReport的核心所在,它會根據你在xml里面寫好的查詢語句來查詢指定是數據庫,也可以控制在后台編寫查詢語句,參數,數據庫。在報表填充完后,會再生成一個.jrprint格式的文件(讀取jasper文件進行填充,然后生成一個jrprint文件) - Exporter:決定要輸出的報表為何種格式,報表輸出的管理類。
- Jasperreport 可以輸出多種格式的報表文件,常見的有Html,PDF,xls等
2. Jaspersoft Studio 模板工具
概述
Jaspersoft Studio是JasperReports庫和JasperReports服務器的基於Eclipse的報告設計器; 它可以作為Eclipse插件或作為獨立的應用程序使用。Jaspersoft Studio允許您創建包含圖表,圖像,子報表,交叉表等的復雜布局。您可以通過JDBC,TableModels,JavaBeans,XML,Hibernate,大數據(如Hive),CSV,XML / A以及自定義來源等各種來源訪問數據,然后將報告發布為PDF,RTF, XML,XLS,CSV,HTML,XHTML,文本,DOCX或OpenOffice。
Jaspersoft Studio 是一個可視化的報表設計工具,使用該軟件可以方便地對報表進行可視化的設計,設計結果為格式.jrxml 的 XML 文件,並且可以把.jrxml 文件編譯成.jasper 格式文件方便 JasperReport 報表引擎解析、顯示。
安裝配置
- 到JasperReport官網下載 https://community.jaspersoft.com/community-download

-
下載后,安裝:TIB_js-studiocomm_6.5.0.final_windows_x86_64.exe。 直接下一步下一步即可。
-
主界面

基本使用
如何創建模板?
- 打開Jaspersoft Studio ,新建一個project, 步驟: File -> New -> Project-> JasperReports Project

- 下一步,輸入項目名稱:

-
創建JasperReport模板
圖1:

圖2:

圖3:

圖4:

面版說明
- Title(標題):只在整個報表的第一頁的最上端顯示。只在第一頁顯示,其他頁面均不顯示。
- Page Header(頁頭):在整個報表中每一頁都會顯示。在第一頁中,出現的位置在 Title Band的下面。在除了第一頁的其他頁面中Page Header 的內容均在頁面的最上端顯示。
- Page Footer(頁腳):在整個報表中每一頁都會顯示。顯示在頁面的最下端。一般用來顯示頁碼。
- Detail 1(詳細):報表內容,每一頁都會顯示。
- Column Header(列頭):Detail中打印的是一張表的話,這Column Header就是表中列的列頭。
- Column Footer(列腳):Detail中打印的是一張表的話,這Column Footer就是表中列的列腳。
- Summary(統計):表格的合計段,出現在整個報表的最后一頁中,在Detail 1 Band后面。主要是用來做報表的合計顯示。
完善模板、編譯模板
第一步:可以把不需要的面版刪除:這里只留了Title、Summary

第二步:拖入Image到面版中,輸入url地址:http://i1.qhimg.com/t01e0356c940bf0a30c.jpg

第三步:拖入Static Text,靜態文本

第四步:點擊預覽

第四步:現在已經創建了jrxml模板,現在需要編譯它:
注:這里千萬千萬注意要先保存再編譯,不然打印出來的內容會是空白的,還有漢字問題,字體需要選擇系統有的,如果導入到java程序中,最好在包中存放該字體文件

編譯結果:

數據填充
1. 數據填充(一)參數map填充
需求
通過java代碼往jasper模板中傳入參數。
步驟
第一步: 定義模板。先定義模板、在模板中定義一些參數。
模板預覽:

第二步:導出PDF。通過java代碼,往模板中設置參數,導出pdf。
第一步:定義模板
① 拖入frame

② 設置frame邊框

③ 拖入Line到frame、設置寬度與frame一致。

④ 設置h為1px后

⑤ 預覽

⑥設置Parameter
圖1:

圖2:

⑦ 制作模板

⑧ 修改文字大小、修改文字字體、編譯模板生成jasper文件、把jasper文件拷貝到項目中。
第二步:導出PDF
① 拷貝jasper文件到項目中

② 編寫控制器
/**
* 2)帶參數的導出
* @throws Exception
*/
@RequestMapping("/exportPdf")
public void exportPdf() throws Exception{
//1.讀取.japser文件,構建輸入流
InputStream in = session.getServletContext().getResourceAsStream("/jasper/test02_param.jasper");
//2.構建Print對象,用於讓模塊結合數據
//第二個參數就是用來填充模板中的parameters
Map<String, Object> map = new HashMap<>();
map.put("userName","小澤");
map.put("email","ze@qq.com");
map.put("companyName","小澤科技");
map.put("deptName","視頻組");
JasperPrint print = JasperFillManager.fillReport(in,map,new JREmptyDataSource());
//3.使用Exporter導出PDF
JasperExportManager.exportReportToPdfStream(print,response.getOutputStream());
}
2. 數據填充(二)JDBC數據源 A 配置數據源
分析
數據源填充數據分為:JDBC數據源填充數據(數據庫連接)、JavaBean填充數據(list集合)
如圖:

配置數據源
圖1:

圖2:

圖3:配置數據庫連接信息

圖4:選擇驅動、點擊完成

圖5:配置結果

3. 數據填充(三)JDBC數據源 B 制作模板
制作模板
第一步:新建模板
① 新建jasper模板

輸入模板名稱:

下一步,完成

第二步:模板制作
①創建空白模板后,並將不需要的Band刪除, 只留下如下面版:

②新建數據源
圖1:

圖2:


③ 新建數據源后,自動生成如下四個Fields

④ 構造模板

第三步:制作細節
①由於模板數據有空格,需要去除數據的空格
圖1:雙擊空白區域

圖2:

由於沒有邊框,現在設置邊框
圖1:

4. 數據填充(四)JDBC數據源 C 代碼實現
這里的數據是從pe_user表查詢出來的,在jasper模板中配置的數據源。
實現
第一步:拷貝生成的jasper文件到項目中

第二步:實現導出PDF
//注入數據源
@Autowired
private DataSource dataSource;
/**
* 3)使用JDBC數據源導出
* @throws Exception
*/
@RequestMapping("/exportPdf")
public void exportPdf() throws Exception{
//1.讀取.japser文件,構建輸入流
InputStream in = session.getServletContext().getResourceAsStream("/jasper/test03_jdbc.jasper");
//2.構建Print對象,用於讓模塊結合數據
//第三個參數:如果是JDBC數據源,應該設置Connection對象
JasperPrint print = JasperFillManager.fillReport(in,new HashMap<>(),dataSource.getConnection());
//3.使用Exporter導出PDF
JasperExportManager.exportReportToPdfStream(print,response.getOutputStream());
}
5. 數據填充(五)JavaBean數據源(重點)
需求
剛才我們實現了jdbc數據源,直接查詢表中的數據填充jasper模板。但是很多時候我們需要對數據進行處理,再把處理后的數據填充到jasper模板。所以,我們就需要把處理后的數據用javabean封裝,這里就用到了javabean數據源。
我們的實現步驟分為下面2步:
- 制作jasper模板
- 導出pdf
制作模板

導出pdf
先把編譯后的jasper模板文件拷貝到項目中,再在控制器添加如下方法:
/**
* 4)使用JavaBean數據源導出
* @throws Exception
*/
@RequestMapping("/exportPdf")
public void exportPdf() throws Exception{
//1.讀取.japser文件,構建輸入流
InputStream in = session.getServletContext().getResourceAsStream("/jasper/test04_javabean.jasper");
//2.構建Print對象,用於讓模塊結合數據
//注意:JavaBean的屬性名稱和模版的Fileds的名稱一致的
List<User> list = new ArrayList<>();
for(int i=1;i<=10;i++){
User user = new User();
user.setUserName("張三-"+i);
user.setEmail("zhangsan-"+i+"@qq.com");
user.setCompanyName("熊掌科技");
user.setDeptName("開發部");
list.add(user);
}
JRBeanCollectionDataSource dataSource = new JRBeanCollectionDataSource(list);
//第三個參數:JavaBean作為數據源,使用JRBeanCollectionDataSource對象來填充
JasperPrint print = JasperFillManager.fillReport(in,new HashMap<>(),dataSource);
//3.使用Exporter導出PDF
JasperExportManager.exportReportToPdfStream(print,response.getOutputStream());
}
6. 數據填充(六)分組報表
制作模板
① 新建模板:test06_group.jrxml
②新建Fields

③ 新建組
圖1:

圖2:

圖3:

④ 編輯模板 - 組
圖1:按照哪個字段進行分組,就拖入對應字段

圖2:編輯組名稱

圖3:雙擊組名稱

圖4: 再次拖入分組字段到Footer中

圖5:輸入統計信息放入Footer

⑤ 添加Field、完成模板制作

導出pdf
先把編譯后的jasper模板文件拷貝到項目中,再在控制器添加如下方法:
/**
* 5)分組導出
* @throws Exception
*/
@RequestMapping("/exportPdf")
public void exportPdf() throws Exception{
//1.讀取.japser文件,構建輸入流
InputStream in = session.getServletContext().getResourceAsStream("/jasper/test05_group.jasper");
//2.構建Print對象,用於讓模塊結合數據
//注意:JavaBean的屬性名稱和模版的Fileds的名稱一致的
List<User> list = new ArrayList<>();
for(int j=1;j<5;j++) {
for (int i = 1; i <= 10; i++) {
User user = new User();
user.setUserName("張三-" + i);
user.setEmail("zhangsan-" + i + "@qq.com");
user.setCompanyName("熊掌科技-" + j);
user.setDeptName("開發部");
list.add(user);
}
}
JRBeanCollectionDataSource dataSource = new JRBeanCollectionDataSource(list);
//第三個參數:JavaBean作為數據源,使用JRBeanCollectionDataSource對象來填充
JasperPrint print = JasperFillManager.fillReport(in,new HashMap<>(),dataSource);
//3.使用Exporter導出PDF
JasperExportManager.exportReportToPdfStream(print,response.getOutputStream());
}
7. 數據填充(七)圖形報表
制作模板
①創建模板、創建Fields

②添加Charts
圖1:

圖2:

③設置餅圖屬性
圖1:

圖2:

圖3:

圖3:

④最后pdf模板

注意: 設置了標題,一定設置 標題 + 餅圖的字體。
導出pdf
先把編譯后的jasper模板文件拷貝到項目中,再在控制器添加如下方法:
/**
* 6)圖標導出
* @throws Exception
*/
@RequestMapping("/exportPdf")
public void exportPdf() throws Exception{
//1.讀取.japser文件,構建輸入流
InputStream in = session.getServletContext().getResourceAsStream("/jasper/test06_pie.jasper");
//2.構建Print對象,用於讓模塊結合數據
//注意:JavaBean的屬性名稱和模版的Fileds的名稱一致的
List<Map> list = new ArrayList<>();
for (int i = 1; i <= 6; i++) {
Map map = new HashMap();
map.put("title","標題:"+i);
map.put("value",new Random().nextInt(100));
list.add(map);
}
JRBeanCollectionDataSource dataSource = new JRBeanCollectionDataSource(list);
//第三個參數:JavaBean作為數據源,使用JRBeanCollectionDataSource對象來填充
JasperPrint print = JasperFillManager.fillReport(in,new HashMap<>(),dataSource);
//3.使用Exporter導出PDF
JasperExportManager.exportReportToPdfStream(print,response.getOutputStream());
}
