武汉做网站哪家专业网站页面布局和样式设计
iReport 5.6.0 + Jasper 6.8.0 报表生成
- 一、iReport和Jasper介绍
- 二、 iReport的使用
- 1. iReport下载
- 2. 配置JDK
- 3. 配置数据源
- 4. 创建模板
- (1)选择预设模板
- (2)编辑模板
- (3)文本换行处理
- 三、Java集成Jasper
- 1.引入Pom依赖
- 2. Java代码的编写
- 3.中文字符不显示或者乱码解决方案
- 4.Jasper附带参数
- 5. 常见问题(FAQ)
- (1)查询数据列表为空,PDF显示空白页
- (2)查询字段为空,报表显示null
- (3)多表联表查询
一、iReport和Jasper介绍
Jasper:
JasperReport是一个强大、灵活的报表生成工具,能够展示丰富的页面内容,并将之转换成PDF,HTML,或者XML格式。该库完全由Java写成,可以用于在各种Java应用程序,包括J2EE,Web应用程序中生成动态内容。
iReport:
iReport 是为JasperReports Library和JasperReports Server设计的报表可视化设计器
二、 iReport的使用
1. iReport下载
iReport可以到社区里下载:
https://sourceforge.net/projects/ireport/files/iReport/iReport-5.6.0/
推荐下载zip版本的
下载完成后,解压到本地,目录结构如图(其中jdk1.7是我自己解压进去的 原始zip包并不包含):
iReport 5.6.0 由于历史久远,最多支持jdk到1.7 ,如果你的本地jdk环境是1.8,打开会闪退; 所以需要自行准备jdk1.7 。
2. 配置JDK
用记事本打开etc目录下的ireport.conf,修改jdkhome为jdk1.7的根目录。
3. 配置数据源
然后输入本地数据库的url,数据库用户名,数据库密码, 输入完成后,点击Test
如果出现Connection test successful,说明数据库配置的没问题
注意: iReport 只提供了少量的JdbcDriver,比如Oracle驱动它就没有,需要自行导入, 导入步骤:
(a)将要导入的JdbcDriver复制到libs目录下,D:\iReport-5.6.0\ireport\libs
(b)工具-选项,按照如图所示步骤添加JdbcDriver的jar包
此时就可以看到添加数据源时,Oracle的驱动可以用了
4. 创建模板
(1)选择预设模板
因为是入门Demo,我们选择空白的A4即可,选择完后 点击"Open this Templete"
选择工作的workspace,填写完模板名,点击下一步-完成
(2)编辑模板
step1:选择数据源
点击OK后,可以看到我们左侧的Fileds里出现了刚添加sql的字段, 如果需要多表联表查询,查询出的字段也会出现在这里
step2:编辑样式
比如说我们要做一个简单的demo报表,就是加一个报表头,然后把数据库的数据展示出来,我们可以把不需要的编辑栏进行删除,右键"Delete Band" 删除
标题是静态文本,我们选择Static Text,拖到Title里
依次类推,把列名的静态文本加入到 “Column Header” 里
当然我们可以在列名和数据之间加一条线作为区分
Line的pen属性可以选择分割线的样式
step3:填充数据
我们现在需要把数据填充进去,此时拖着Fields里刚才配置的字段到指定位置即可,填写完后,点击Preview即可预览PDF。
(3)文本换行处理
有时我们会遇到,给定的区域太小,但是文本有特别多情况,这样如果文本超出了区域,超出的部分将被截取,不再显示,如:
我们需要它换行显示,则需要设置该文本的几项属性:
这样文本就会换行显示了:
三、Java集成Jasper
1.引入Pom依赖
新建工程,在pom中添加依赖:
<!-- jasper报表依赖 --><dependency><groupId>net.sf.jasperreports</groupId><artifactId>jasperreports</artifactId><version>6.8.0</version><exclusions><exclusion><groupId>com.lowagie</groupId><artifactId>itext</artifactId></exclusion></exclusions></dependency><dependency><groupId>com.lowagie</groupId><artifactId>itext</artifactId><version>2.1.7</version></dependency><dependency><groupId>cn.lesper</groupId><artifactId>iTextAsian</artifactId><version>3.0</version></dependency><dependency><groupId>org.codehaus.groovy</groupId><artifactId>groovy-all</artifactId><version>2.4.15</version></dependency><!-- mysql --><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>5.1.34</version></dependency></dependencies>
2. Java代码的编写
这里给出一个简单的例子
package com.demo.jasper;import net.sf.jasperreports.engine.*;
import net.sf.jasperreports.engine.export.JRPdfExporter;
import net.sf.jasperreports.engine.fill.JRAbstractLRUVirtualizer;
import net.sf.jasperreports.engine.fill.JRGzipVirtualizer;
import net.sf.jasperreports.engine.util.JRLoader;
import net.sf.jasperreports.export.ExporterInput;
import net.sf.jasperreports.export.OutputStreamExporterOutput;
import net.sf.jasperreports.export.SimpleExporterInput;
import net.sf.jasperreports.export.SimpleOutputStreamExporterOutput;import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Properties;/*** @author zhang_hr* @date 2021/8/17 11:29* @description Jasper工具类**/
public class JasperUtils {/*** 编译jrxml格式文件** @param jrXmlPath jrxml文件路径* @param jasperPath jasper文件路径*/public static void compileJrXml(String jrXmlPath, String jasperPath) {try {// 如果文件夹不存在 先创建文件夹File jasperDir = new File(jrXmlPath);if (!(jasperDir.exists())) {jasperDir.mkdirs();}JasperCompileManager.compileReportToFile(jrXmlPath, jasperPath);} catch (JRException e) {e.printStackTrace();}}/*** 根据jasper模板生成pdf报表** @param jasperPath jasper模板路径* @param reportPath pdf报表生成路径* @param parameter 参数集合* @param connection 数据库连接*/public static void creatReport(String jasperPath, String reportPath,HashMap<String, Object> parameter, Connection connection) {InputStream inputStream = null;OutputStreamExporterOutput exporterOutput = null;try {// 1.加载jasper文件JasperReport jasperReport;// 使用FileInputStream时jasperPath要使用绝对路径inputStream = new FileInputStream(new File(jasperPath));// springboot项目中使用以下这个,jasperPath填写resources的相对路径// 如在resources的jasper目录下的demo.jasper jasperPath填写"jasper/demo.jasper"即可// inputStream = JasperUtils.class.getResourceAsStream(jasperPath);if (inputStream == null) {throw new IllegalArgumentException("jasper inputStream is null");}jasperReport = (JasperReport) JRLoader.loadObject(inputStream);// 2.设置参数JRAbstractLRUVirtualizer virtualizer = new JRGzipVirtualizer(2);parameter.put(JRParameter.REPORT_VIRTUALIZER, virtualizer);JasperPrint jasperPrint = JasperFillManager.fillReport(jasperReport, parameter, connection);// 3.报表输入设置ExporterInput exporterInput = new SimpleExporterInput(jasperPrint);File file = new File(reportPath);if (file.exists()) {file.delete();}if (!file.getParentFile().exists() && !file.getParentFile().mkdirs()) {throw new RuntimeException("create dir failed");}exporterOutput = new SimpleOutputStreamExporterOutput(file);// 4.使用导出器导出pdfJRPdfExporter pdf = new JRPdfExporter();pdf.setExporterInput(exporterInput);pdf.setExporterOutput(exporterOutput);pdf.exportReport();} catch (Exception e) {e.printStackTrace();} finally {try {if (inputStream != null) {inputStream.close();}} catch (IOException e) {e.printStackTrace();}if (exporterOutput != null) {exporterOutput.close();}}}/*** 获得带注释的数据库连接** @param url 数据库地址* @param username 数据库用户名* @param password 数据库密码* @return 数据库连接*/public static Connection getConnection(String url, String username, String password) {Connection conn = null;Properties props = new Properties();try {props.setProperty("user", username);props.setProperty("password", password);props.setProperty("remarks", "true"); //设置可以获取remarks信息props.setProperty("useInformationSchema", "true");//设置可以获取tables remarks信息conn = DriverManager.getConnection(url, props);} catch (SQLException e) {e.printStackTrace();}return conn;}public static void main(String[] args) throws SQLException {// 1.编译jrxmlcompileJrXml("D:\\iReport-5.6.0\\wokrspace\\jasper-demo.jrxml","D:\\iReport-5.6.0\\wokrspace\\1.jasper");// 2.生成pdfConnection connection = getConnection("jdbc:mysql://127.0.0.1:3306/test?characterEncoding=UTF8","root", "123");try {creatReport("D:\\iReport-5.6.0\\wokrspace\\1.jasper", "d:/test/666.pdf", new HashMap<String, Object>(),connection);} finally {connection.close();}}
}
打开生成的paf,发现中文不显示
3.中文字符不显示或者乱码解决方案
将图中标记的两处分别选择 :
STSong-Light
UniGB-UCS2-H (Chinese Simplified)
修改过后,重新生成pdf,发现中文字符可以显示了。
4.Jasper附带参数
此时java代码需要修改传入的HashMap
public static void main(String[] args) throws SQLException {// 1.编译jrxmlcompileJrXml("D:\\iReport-5.6.0\\wokrspace\\jasper-demo.jrxml","D:\\iReport-5.6.0\\wokrspace\\1.jasper");// 2.生成pdfConnection connection = getConnection("jdbc:mysql://127.0.0.1:3306/test?characterEncoding=UTF8","root", "123");try {HashMap<String, Object> params = new HashMap<String, Object>();params.put("price","120");creatReport("D:\\iReport-5.6.0\\wokrspace\\1.jasper", "d:/aaaaaa/666.pdf",params,connection);} finally {connection.close();}}
生成的pdf可以根据传入的条件进行显示了,并且是升序排列
5. 常见问题(FAQ)
(1)查询数据列表为空,PDF显示空白页
解决方案:
在iReport界面,右键报表-属性-when no data,选择 "All sections,No Detail "即可,即使查询不到数据,也会导出PDF模板样式。
(2)查询字段为空,报表显示null
解决方案: 字段属性里选中 “blank when null” 即可
(3)多表联表查询
多表联表查询是报表里经常碰到的问题,一般会根据条件进行联表查询, 比如说我们有两张表book、book_type
book表:
id 主键
name 书名
price 价格
book_type表:
id 主键
name 书名
type 书籍种类 || a-科普类 b-历史类 c-故事类 d-其他类
现在我们的需求:
1.把两个表根据name字段来连起来
2.book_type表的type字段要转义
3.获得记录的总条数
4.生成从1开始的自增序列id
5.根据id增序排列
6.要指定价格
7.书籍的价格要保留两位小数(整数的话要输出xxx.00)
其实就是考验sql的基本功(我的sql写的比较烂,各位大神有更好的方式欢迎留言):
SELECT @ROW:=@ROW+1 as id,t1.name,format(t1.price,2) as price,
case
when t2.type='a' then '科普类'
when t2.type='b' then '历史类'
when t2.type='c' then '故事类'
else '其他类' end as type,
(select count(1) from book,book_type where book.name = book_type.name and book.price = '150') as total_num
from book t1,book_type t2,(select @ROW:=0) t3
where t1.name = t2.name and t1.price = '150'
order by id asc;
跟上文描述步骤一样,修改SQL、添加参数
修改报表模板:
运行jJava代码,生成pdf报表: