在本教程中,我们展示如何在 Spring Boot 框架中使用 JasperReports。 我们创建一个 Web 应用。
JasperReports 是一个 Java 开源报告库。 它可以创建各种格式的报告,包括 PDF,HTML,XLS 或 CSV。 JasperReports 以一种简单而灵活的方式创建了面向页面的可打印文档。
JdbcTemplate是一个 Spring 库,可以帮助程序员创建与关系数据库和 JDBC 一起使用的应用。 它会处理许多繁琐且容易出错的底层细节,例如处理事务,清理资源以及正确处理异常。 JdbcTemplate在 Spring 的spring-jdbc模块中提供。
Spring 是用于开发 Java 企业应用的 Java 应用框架。 它还有助于集成各种企业组件。 Spring Boot 使创建具有 Spring 动力的生产级应用和服务变得很容易,而对安装的要求却最低。
Apache Derby 是完全用 Java 实现的开源关系数据库。 它占地面积小,易于部署和安装。 它可以在嵌入式和客户端/服务器模式下运行。
CARS表
我们使用下表:
cars.sql
-- SQL for the CARS tableCREATE TABLE CARS(ID BIGINT NOT NULL PRIMARY KEY GENERATED ALWAYS AS IDENTITY(START WITH 1, INCREMENT BY 1), NAME VARCHAR(30), PRICE INT);INSERT INTO CARS(Name, Price) VALUES('Audi', 52642);INSERT INTO CARS(Name, Price) VALUES('Mercedes', 57127);INSERT INTO CARS(Name, Price) VALUES('Skoda', 9000);INSERT INTO CARS(Name, Price) VALUES('Volvo', 29000);INSERT INTO CARS(Name, Price) VALUES('Bentley', 350000);INSERT INTO CARS(Name, Price) VALUES('Citroen', 21000);INSERT INTO CARS(Name, Price) VALUES('Hummer', 41400);INSERT INTO CARS(Name, Price) VALUES('Volkswagen', 21600);
cars.sql文件创建CARS表。
$ $DERBY_HOME/bin/ijij version 10.11ij> CONNECT 'jdbc:derby:testdb';ij> RUN 'cars.sql';
一种选择是使用ij工具从 SQL 脚本创建表。 请参考 Apache Derby 教程以熟悉 Derby。
$ $DERBY_HOME/bin/NetworkServerControl start &
使用NetworkServerControl工具启动 Derby 服务器。
应用
以下 Spring Boot 应用从数据库表加载数据,并使用 JasperReports 库从中生成 PDF 报告。 该应用与嵌入式 Tomcat 服务器一起运行。
$ tree.├── pom.xml└── src├── main│ ├── java│ │ └── com│ │ └── zetcode│ │ ├── Application.java│ │ ├── bean│ │ │ └── Car.java│ │ ├── conf│ │ │ ├── AppConfig.java│ │ │ └── MvcConf.java│ │ ├── controller│ │ │ └── MyController.java│ │ └── service│ │ ├── CarService.java│ │ └── ICarService.java│ └── resources│ ├── application.yml│ ├── report2.jrxml│ └── static│ └── index.html└── test└── java
这是项目结构。
pom.xml
<?xml version="1.0" encoding="UTF-8"?><project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.zetcode</groupId><artifactId>JasperSpringBootWeb</artifactId><version>1.0-SNAPSHOT</version><packaging>war</packaging><properties><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><maven.compiler.source>1.8</maven.compiler.source><maven.compiler.target>1.8</maven.compiler.target></properties><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>1.5.2.RELEASE</version></parent><dependencies><dependency><groupId>org.apache.derby</groupId><artifactId>derbyclient</artifactId><version>10.13.1.1</version></dependency><dependency><groupId>net.sf.jasperreports</groupId><artifactId>jasperreports</artifactId><version>6.4.0</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-context-support</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-jdbc</artifactId></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build></project>
Maven pom.xml文件包含 JasperReports 库,Derby 驱动程序和 Spring Boot 的依赖项。
report2.xml
<?xml version = "1.0" encoding = "UTF-8"?><!DOCTYPE jasperReport PUBLIC "//JasperReports//DTD Report Design//EN""http://jasperreports.sourceforge.net/dtds/jasperreport.dtd"><jasperReport xmlns="http://jasperreports.sourceforge.net/jasperreports"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://jasperreports.sourceforge.net/jasperreportshttp://jasperreports.sourceforge.net/xsd/jasperreport.xsd"name="report2" pageWidth="595" pageHeight="842"columnWidth="555" leftMargin="20" rightMargin="20"topMargin="20" bottomMargin="20"><field name="Id" class="java.lang.Long"><fieldDescription><![CDATA[id]]></fieldDescription></field><field name="Name" class="java.lang.String"><fieldDescription><![CDATA[name]]></fieldDescription></field><field name="Price" class="java.lang.Integer"><fieldDescription><![CDATA[price]]></fieldDescription></field><detail><band height="15"><textField><reportElement x="0" y="0" width="50" height="15" /><textElement textAlignment="Right" verticalAlignment="Middle"/><textFieldExpression class="java.lang.Long"><![CDATA[$F{Id}]]></textFieldExpression></textField><textField><reportElement x="150" y="0" width="100" height="15" /><textElement textAlignment="Left" verticalAlignment="Middle"/><textFieldExpression class="java.lang.String"><![CDATA[$F{Name}]]></textFieldExpression></textField><textField><reportElement x="200" y="0" width="100" height="15"/><textElement textAlignment="Right" verticalAlignment="Middle"/><textFieldExpression class="java.lang.Integer"><![CDATA[$F{Price}]]></textFieldExpression></textField></band></detail></jasperReport>
这是报告模板文件。 它位于src/main/resources目录中。 模板仅包含明细带。 在详细信息区域内,将对数据源提供的每个记录重复每个元素。
<field name="Id" class="java.lang.Long"><fieldDescription><![CDATA[id]]></fieldDescription></field><field name="Name" class="java.lang.String"><fieldDescription><![CDATA[name]]></fieldDescription></field><field name="Price" class="java.lang.Integer"><fieldDescription><![CDATA[price]]></fieldDescription></field>
报告中有三个字段。 这些字段映射到数据源 bean 的元素。
<textField><reportElement x="0" y="0" width="50" height="15" /><textElement textAlignment="Right" verticalAlignment="Middle"/><textFieldExpression class="java.lang.Long"><![CDATA[$F{Id}]]></textFieldExpression></textField>
文本字段是充满动态数据的元素。 我们将一个字段中的值放在文本字段中。 我们使用$F{}语法引用该变量。
Car.java
package com.zetcode.bean;public class Car {private Long id;private String name;private int price;public Car() {}public Car(Long id, String name, int price) {this.id = id;this.name = name;this.price = price;}public Long getId() {return id;}public void setId(Long id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getPrice() {return price;}public void setPrice(int price) {this.price = price;}@Overridepublic String toString() {return "Car{" + "id=" + id + ", name=" + name + ", price=" + price + '}';}}
这是Car bean 类。 它包含商品 ID,名称和价格。
application.yml
datasource:url: jdbc:derby://localhost:1527/testdbusername: apppassword: appdriverClassName: org.apache.derby.jdbc.ClientDriver
application.yml是主要的 Spring Boot 配置文件。 它包含 Derby 数据源。
AppConfig.java
package com.zetcode.conf;import javax.sql.DataSource;import org.springframework.boot.autoconfigure.jdbc.DataSourceBuilder;import org.springframework.boot.context.properties.ConfigurationProperties;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.context.annotation.Primary;@Configurationpublic class AppConfig {@Bean@Primary@ConfigurationProperties(prefix = "datasource")public DataSource primaryDataSource() {return DataSourceBuilder.create().build();}}
AppConfig是 Java 配置类。 它从配置文件创建数据源 bean。
MyController.java
package com.zetcode.controller;import com.zetcode.service.ICarService;import java.util.HashMap;import java.util.Map;import java.util.logging.Level;import java.util.logging.Logger;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.context.ApplicationContext;import org.springframework.stereotype.Controller;import org.springframework.ui.Model;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RequestMethod;import org.springframework.web.servlet.ModelAndView;import org.springframework.web.servlet.view.jasperreports.JasperReportsPdfView;@Controllerpublic class MyController {@Autowiredprivate ApplicationContext appContext;@Autowiredprivate ICarService carService;@RequestMapping(path = "/pdf", method = RequestMethod.GET)public ModelAndView report() {JasperReportsPdfView view = new JasperReportsPdfView();view.setUrl("classpath:report2.jrxml");view.setApplicationContext(appContext);Map<String, Object> params = new HashMap<>();params.put("datasource", carService.findAll());return new ModelAndView(view, params);}}
在MyController中,我们有两种方法可以响应两个请求。
@Autowiredprivate ICarService carService;
我们将CarService对象注入到属性中。 服务对象用于从数据库检索数据。
@RequestMapping(path = "/pdf", method = RequestMethod.GET)public ModelAndView report() {JasperReportsPdfView view = new JasperReportsPdfView();view.setUrl("classpath:report2.jrxml");view.setApplicationContext(appContext);Map<String, Object> params = new HashMap<>();params.put("datasource", carService.getCars());return new ModelAndView(view, params);}
在report()方法中,将生成报告并将其发送回客户端。 JasperReportsPdfView是 Spring 类,可从提供的模板和数据生成 PDF 报告。
ICarService.java
package com.zetcode.service;import com.zetcode.bean.Car;import java.util.List;public interface ICarService {public List<Car> findAll();}
ICarService提供了一种从数据源获取所有汽车的契约方法。
CarService.java
package com.zetcode.service;import com.zetcode.bean.Car;import java.util.List;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.jdbc.core.BeanPropertyRowMapper;import org.springframework.jdbc.core.JdbcTemplate;import org.springframework.stereotype.Service;@Servicepublic class CarService implements ICarService {@Autowiredprivate JdbcTemplate jtm;@Overridepublic List<Car> findAll() {String sql = "SELECT * FROM Cars";List<Car> cars = jtm.query(sql, new BeanPropertyRowMapper(Car.class));return cars;}}
CarService包含findAll()方法的实现。 我们借助JdbcTemplate从CARS表中检索所有汽车。
@Autowiredprivate JdbcTemplate jtm;
注入JdbcTemplate。
String sql = "SELECT * FROM Cars";
这是要执行的 SQL。 我们从CARS表中选择所有汽车。
List<Car> cars = jtm.query(sql, new BeanPropertyRowMapper(Car.class));
BeanPropertyRowMapper将一行转换为指定映射目标类的新实例。
index.html
<!DOCTYPE html><html><head><meta charset="UTF-8"><title>Home Page</title></head><body><a href="/pdf.html">Generate report</a></body></html>
index.html文件包含一个生成 PDF 报告的链接。
Application.java
package com.zetcode;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.EnableAutoConfiguration;@SpringBootApplicationpublic class Application {public static void main(String[] args) {SpringApplication.run(Application.class, args);}}
Application设置 Spring Boot 应用。
在本教程中,我们使用 JasperReports 创建了 PDF 报告。 该应用使用 Spring Boot 框架,并在 Web 环境中运行。 您可能也对这些相关教程感兴趣: Spring Boot JasperReports CMD 集成,使用 JasperReports API 创建报告,使用 JasperReports 从 CSV 创建报告。 Java 教程。
