ThinkChat2.0新版上线,更智能更精彩,支持会话、画图、阅读、搜索等,送10W Token,即刻开启你的AI之旅 广告
# Spring Boot Web JasperReports 集成 > 原文: [http://zetcode.com/articles/jasperspringbootweb/](http://zetcode.com/articles/jasperspringbootweb/) 在本教程中,我们展示如何在 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` ```java -- SQL for the CARS table CREATE 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`表。 ```java $ $DERBY_HOME/bin/ij ij version 10.11 ij> CONNECT 'jdbc:derby:testdb'; ij> RUN 'cars.sql'; ``` 一种选择是使用`ij`工具从 SQL 脚本创建表。 请参考 [Apache Derby 教程](/db/apachederbytutorial/)以熟悉 Derby。 ```java $ $DERBY_HOME/bin/NetworkServerControl start & ``` 使用`NetworkServerControl`工具启动 Derby 服务器。 ## 应用 以下 Spring Boot 应用从数据库表加载数据,并使用 JasperReports 库从中生成 PDF 报告。 该应用与嵌入式 Tomcat 服务器一起运行。 ```java $ 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` ```java <?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.0 http://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` ```java <?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/jasperreports http://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`目录中。 模板仅包含明细带。 在详细信息区域内,将对数据源提供的每个记录重复每个元素。 ```java <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 的元素。 ```java <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` ```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; } @Override public String toString() { return "Car{" + "id=" + id + ", name=" + name + ", price=" + price + '}'; } } ``` 这是`Car` bean 类。 它包含商品 ID,名称和价格。 `application.yml` ```java datasource: url: jdbc:derby://localhost:1527/testdb username: app password: app driverClassName: org.apache.derby.jdbc.ClientDriver ``` `application.yml`是主要的 Spring Boot 配置文件。 它包含 Derby 数据源。 `AppConfig.java` ```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; @Configuration public class AppConfig { @Bean @Primary @ConfigurationProperties(prefix = "datasource") public DataSource primaryDataSource() { return DataSourceBuilder.create().build(); } } ``` `AppConfig`是 Java 配置类。 它从配置文件创建数据源 bean。 `MyController.java` ```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; @Controller public class MyController { @Autowired private ApplicationContext appContext; @Autowired private 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`中,我们有两种方法可以响应两个请求。 ```java @Autowired private ICarService carService; ``` 我们将`CarService`对象注入到属性中。 服务对象用于从数据库检索数据。 ```java @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` ```java package com.zetcode.service; import com.zetcode.bean.Car; import java.util.List; public interface ICarService { public List<Car> findAll(); } ``` `ICarService`提供了一种从数据源获取所有汽车的契约方法。 `CarService.java` ```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; @Service public class CarService implements ICarService { @Autowired private JdbcTemplate jtm; @Override public List<Car> findAll() { String sql = "SELECT * FROM Cars"; List<Car> cars = jtm.query(sql, new BeanPropertyRowMapper(Car.class)); return cars; } } ``` `CarService`包含`findAll()`方法的实现。 我们借助`JdbcTemplate`从`CARS`表中检索所有汽车。 ```java @Autowired private JdbcTemplate jtm; ``` 注入`JdbcTemplate`。 ```java String sql = "SELECT * FROM Cars"; ``` 这是要执行的 SQL。 我们从`CARS`表中选择所有汽车。 ```java List<Car> cars = jtm.query(sql, new BeanPropertyRowMapper(Car.class)); ``` `BeanPropertyRowMapper`将一行转换为指定映射目标类的新实例。 `index.html` ```java <!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` ```java package com.zetcode; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; @SpringBootApplication public 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 集成](/articles/jasperspringbootcmd/),[使用 JasperReports API 创建报告](/articles/jasperprog/),[使用 JasperReports](/articles/jaspercsv/) 从 CSV 创建报告。 [Java 教程](/lang/java/)。