Spring Boot 数据导入导出与报表生成的基本方法

 更新时间:2026年07月10日 15:01:35   作者:程序山海  
这篇文章给大家介绍Spring Boot数据导入导出与报表生成的基本方法,本文结合实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧

Spring Boot 数据导入导出与报表生成

24.1 学习目标与重点提示

学习目标:掌握Spring Boot数据导入导出与报表生成的核心概念与使用方法,包括数据导入导出的定义与特点、Spring Boot与数据导入导出的集成、Spring Boot与数据导入导出的配置、Spring Boot与报表生成的基本方法、Spring Boot的实际应用场景,学会在实际开发中处理数据导入导出与报表生成问题。
重点:数据导入导出的定义与特点Spring Boot与数据导入导出的集成Spring Boot与数据导入导出的配置Spring Boot与报表生成的基本方法Spring Boot的实际应用场景

24.2 数据导入导出概述

数据导入导出是Java开发中的重要组件。

24.2.1 数据导入导出的定义

定义:数据导入导出是指将数据从一个系统导入到另一个系统,或从一个系统导出到另一个系统的过程。
作用

  • 实现数据的迁移。
  • 实现数据的备份。
  • 实现数据的共享。

常见的数据导入导出格式

  • CSV:Comma-Separated Values,逗号分隔值格式。
  • Excel:Microsoft Excel格式。
  • JSON:JavaScript Object Notation,JavaScript对象表示法格式。
  • XML:eXtensible Markup Language,可扩展标记语言格式。

✅ 结论:数据导入导出是指将数据从一个系统导入到另一个系统,或从一个系统导出到另一个系统的过程,作用是实现数据的迁移、备份、共享。

24.2.2 数据导入导出的特点

定义:数据导入导出的特点是指数据导入导出的特性。
特点

  • 易用性:数据导入导出提供易用的编程模型。
  • 高效性:数据导入导出提供高效的数据处理。
  • 可扩展性:数据导入导出可以扩展到多个应用程序之间的数据通信。
  • 可靠性:数据导入导出提供可靠的数据传输。

✅ 结论:数据导入导出的特点包括易用性、高效性、可扩展性、可靠性。

24.3 Spring Boot与数据导入导出的集成

Spring Boot与数据导入导出的集成是Java开发中的重要内容。

24.3.1 集成Apache POI的步骤

定义:集成Apache POI的步骤是指使用Spring Boot与Apache POI集成的方法。
步骤

  1. 创建Spring Boot项目。
  2. 添加所需的依赖。
  3. 创建数据访问层。
  4. 创建业务层。
  5. 创建控制器类。
  6. 测试应用。

示例
pom.xml文件中的依赖:

<dependencies>
    <!-- Web依赖 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <!-- Data JPA依赖 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-jpa</artifactId>
    </dependency>
    <!-- H2数据库依赖 -->
    <dependency>
        <groupId>com.h2database</groupId>
        <artifactId>h2</artifactId>
        <scope>runtime</scope>
    </dependency>
    <!-- Apache POI依赖 -->
    <dependency>
        <groupId>org.apache.poi</groupId>
        <artifactId>poi</artifactId>
        <version>4.1.2</version>
    </dependency>
    <dependency>
        <groupId>org.apache.poi</groupId>
        <artifactId>poi-ooxml</artifactId>
        <version>4.1.2</version>
    </dependency>
    <!-- 测试依赖 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
</dependencies>

application.properties文件中的配置:

# 服务器端口
server.port=8080
# 数据库连接信息
spring.datasource.url=jdbc:h2:mem:testdb
spring.datasource.driver-class-name=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=password
# JPA配置
spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true
# H2数据库控制台
spring.h2.console.enabled=true
spring.h2.console.path=/h2-console

实体类:

import javax.persistence.*;
@Entity
@Table(name = "product")
public class Product {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String productId;
    private String productName;
    private double price;
    private int sales;
    public Product() {
    }
    public Product(String productId, String productName, double price, int sales) {
        this.productId = productId;
        this.productName = productName;
        this.price = price;
        this.sales = sales;
    }
    // Getter和Setter方法
    public Long getId() {
        return id;
    }
    public void setId(Long id) {
        this.id = id;
    }
    public String getProductId() {
        return productId;
    }
    public void setProductId(String productId) {
        this.productId = productId;
    }
    public String getProductName() {
        return productName;
    }
    public void setProductName(String productName) {
        this.productName = productName;
    }
    public double getPrice() {
        return price;
    }
    public void setPrice(double price) {
        this.price = price;
    }
    public int getSales() {
        return sales;
    }
    public void setSales(int sales) {
        this.sales = sales;
    }
    @Override
    public String toString() {
        return "Product{" +
                "id=" + id +
                ", productId='" + productId + '\'' +
                ", productName='" + productName + '\'' +
                ", price=" + price +
                ", sales=" + sales +
                '}';
    }
}

Repository接口:

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
@Repository
public interface ProductRepository extends JpaRepository<Product, Long> {
}

Service类:

import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
@Service
public class ProductService {
    @Autowired
    private ProductRepository productRepository;
    @Transactional
    public void importProducts(MultipartFile file) throws IOException {
        List<Product> products = new ArrayList<>();
        Workbook workbook = new XSSFWorkbook(file.getInputStream());
        Sheet sheet = workbook.getSheetAt(0);
        Iterator<Row> iterator = sheet.iterator();
        if (iterator.hasNext()) {
            iterator.next(); // 跳过标题行
        }
        while (iterator.hasNext()) {
            Row currentRow = iterator.next();
            Product product = new Product();
            product.setProductId(currentRow.getCell(0).getStringCellValue());
            product.setProductName(currentRow.getCell(1).getStringCellValue());
            product.setPrice(currentRow.getCell(2).getNumericCellValue());
            product.setSales((int) currentRow.getCell(3).getNumericCellValue());
            products.add(product);
        }
        productRepository.saveAll(products);
        workbook.close();
    }
    @Transactional(readOnly = true)
    public byte[] exportProducts() throws IOException {
        List<Product> products = productRepository.findAll();
        Workbook workbook = new XSSFWorkbook();
        Sheet sheet = workbook.createSheet("Products");
        Row headerRow = sheet.createRow(0);
        Cell headerCell0 = headerRow.createCell(0);
        headerCell0.setCellValue("Product ID");
        Cell headerCell1 = headerRow.createCell(1);
        headerCell1.setCellValue("Product Name");
        Cell headerCell2 = headerRow.createCell(2);
        headerCell2.setCellValue("Price");
        Cell headerCell3 = headerRow.createCell(3);
        headerCell3.setCellValue("Sales");
        int rowNum = 1;
        for (Product product : products) {
            Row row = sheet.createRow(rowNum++);
            row.createCell(0).setCellValue(product.getProductId());
            row.createCell(1).setCellValue(product.getProductName());
            row.createCell(2).setCellValue(product.getPrice());
            row.createCell(3).setCellValue(product.getSales());
        }
        for (int i = 0; i < 4; i++) {
            sheet.autoSizeColumn(i);
        }
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        workbook.write(outputStream);
        workbook.close();
        return outputStream.toByteArray();
    }
    @Transactional
    public Product addProduct(Product product) {
        return productRepository.save(product);
    }
    @Transactional(readOnly = true)
    public List<Product> getAllProducts() {
        return productRepository.findAll();
    }
}

控制器类:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
import java.util.List;
@RestController
@RequestMapping("/api/products")
public class ProductController {
    @Autowired
    private ProductService productService;
    @PostMapping("/import")
    public ResponseEntity<String> importProducts(@RequestParam("file") MultipartFile file) {
        try {
            productService.importProducts(file);
            return ResponseEntity.ok("数据导入成功");
        } catch (IOException e) {
            e.printStackTrace();
            return ResponseEntity.status(500).body("数据导入失败:" + e.getMessage());
        }
    }
    @GetMapping("/export")
    public ResponseEntity<byte[]> exportProducts() {
        try {
            byte[] bytes = productService.exportProducts();
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.parseMediaType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"));
            headers.setContentDispositionFormData("attachment", "products.xlsx");
            headers.setCacheControl("must-revalidate, post-check=0, pre-check=0");
            return ResponseEntity.ok().headers(headers).body(bytes);
        } catch (IOException e) {
            e.printStackTrace();
            return ResponseEntity.status(500).body(null);
        }
    }
    @PostMapping("/")
    public Product addProduct(@RequestBody Product product) {
        return productService.addProduct(product);
    }
    @GetMapping("/")
    public List<Product> getAllProducts() {
        return productService.getAllProducts();
    }
}

应用启动类:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class ProductApplication {
    public static void main(String[] args) {
        SpringApplication.run(ProductApplication.class, args);
    }
    @Autowired
    private ProductService productService;
    public void run(String... args) {
        // 初始化数据
        productService.addProduct(new Product("P001", "手机", 1000.0, 100));
        productService.addProduct(new Product("P002", "电脑", 5000.0, 50));
        productService.addProduct(new Product("P003", "电视", 3000.0, 80));
        productService.addProduct(new Product("P004", "手表", 500.0, 200));
        productService.addProduct(new Product("P005", "耳机", 300.0, 150));
    }
}

测试类:

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.web.client.TestRestTemplate;
import org.springframework.boot.web.server.LocalServerPort;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.commons.CommonsMultipartFile;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import static org.assertj.core.api.Assertions.assertThat;
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
class ProductApplicationTests {
    @LocalServerPort
    private int port;
    @Autowired
    private TestRestTemplate restTemplate;
    @Test
    void contextLoads() {
    }
    @Test
    void testAddProduct() {
        Product product = new Product("P006", "平板", 2000.0, 70);
        Product savedProduct = restTemplate.postForObject("http://localhost:" + port + "/api/products/", product, Product.class);
        assertThat(savedProduct).isNotNull();
        assertThat(savedProduct.getProductId()).isEqualTo("P006");
    }
    @Test
    void testGetAllProducts() {
        List<Product> products = restTemplate.getForObject("http://localhost:" + port + "/api/products/", List.class);
        assertThat(products).isNotNull();
        assertThat(products.size()).isGreaterThanOrEqualTo(5);
    }
    @Test
    void testImportProducts() throws IOException {
        File file = new File("src/test/resources/products.xlsx");
        InputStream inputStream = new FileInputStream(file);
        MultipartFile multipartFile = new CommonsMultipartFile(inputStream);
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.MULTIPART_FORM_DATA);
        MultiValueMap<String, Object> body = new LinkedMultiValueMap<>();
        body.add("file", multipartFile);
        HttpEntity<MultiValueMap<String, Object>> requestEntity = new HttpEntity<>(body, headers);
        ResponseEntity<String> response = restTemplate.exchange("http://localhost:" + port + "/api/products/import", HttpMethod.POST, requestEntity, String.class);
        assertThat(response.getStatusCodeValue()).isEqualTo(200);
        assertThat(response.getBody()).contains("数据导入成功");
    }
    @Test
    void testExportProducts() {
        ResponseEntity<byte[]> response = restTemplate.getForEntity("http://localhost:" + port + "/api/products/export", byte[].class);
        assertThat(response.getStatusCodeValue()).isEqualTo(200);
        assertThat(response.getBody()).isNotNull();
        assertThat(response.getBody().length).isGreaterThan(0);
    }
}

✅ 结论:集成Apache POI的步骤包括创建Spring Boot项目、添加所需的依赖、创建数据访问层、创建业务层、创建控制器类、测试应用。

24.4 Spring Boot与报表生成的基本方法

Spring Boot与报表生成的基本方法包括使用Apache POI、使用JasperReports、使用Excel模板。

24.4.1 使用JasperReports

定义:使用JasperReports是指Spring Boot与报表生成集成的基本方法之一。
作用

  • 实现报表生成。
  • 提高应用程序的性能。

示例
pom.xml文件中的依赖:

<dependencies>
    <!-- Web依赖 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <!-- Data JPA依赖 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-jpa</artifactId>
    </dependency>
    <!-- H2数据库依赖 -->
    <dependency>
        <groupId>com.h2database</groupId>
        <artifactId>h2</artifactId>
        <scope>runtime</scope>
    </dependency>
    <!-- JasperReports依赖 -->
    <dependency>
        <groupId>net.sf.jasperreports</groupId>
        <artifactId>jasperreports</artifactId>
        <version>6.17.0</version>
    </dependency>
    <dependency>
        <groupId>net.sf.jasperreports</groupId>
        <artifactId>jasperreports-fonts</artifactId>
        <version>6.17.0</version>
    </dependency>
    <!-- 测试依赖 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
</dependencies>

Service类:

import net.sf.jasperreports.engine.*;
import net.sf.jasperreports.engine.data.JRBeanCollectionDataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Service
public class ReportService {
    @Autowired
    private ProductRepository productRepository;
    @Transactional(readOnly = true)
    public byte[] generateProductReport() throws JRException {
        List<Product> products = productRepository.findAll();
        // 加载Jasper模板
        InputStream templateStream = getClass().getResourceAsStream("/reports/product-report.jasper");
        JasperReport jasperReport = (JasperReport) JRLoader.loadObject(templateStream);
        // 设置参数
        Map<String, Object> parameters = new HashMap<>();
        parameters.put("Title", "产品销售报表");
        // 设置数据源
        JRBeanCollectionDataSource dataSource = new JRBeanCollectionDataSource(products);
        // 生成报表
        JasperPrint jasperPrint = JasperFillManager.fillReport(jasperReport, parameters, dataSource);
        // 导出报表为PDF
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        JasperExportManager.exportReportToPdfStream(jasperPrint, outputStream);
        return outputStream.toByteArray();
    }
}

控制器类:

import net.sf.jasperreports.engine.JRException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
import java.util.List;
@RestController
@RequestMapping("/api/products")
public class ProductController {
    @Autowired
    private ProductService productService;
    @Autowired
    private ReportService reportService;
    @GetMapping("/report")
    public ResponseEntity<byte[]> generateProductReport() {
        try {
            byte[] bytes = reportService.generateProductReport();
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.parseMediaType("application/pdf"));
            headers.setContentDispositionFormData("attachment", "product-report.pdf");
            headers.setCacheControl("must-revalidate, post-check=0, pre-check=0");
            return ResponseEntity.ok().headers(headers).body(bytes);
        } catch (JRException e) {
            e.printStackTrace();
            return ResponseEntity.status(500).body(null);
        }
    }
    @PostMapping("/import")
    public ResponseEntity<String> importProducts(@RequestParam("file") MultipartFile file) {
        try {
            productService.importProducts(file);
            return ResponseEntity.ok("数据导入成功");
        } catch (IOException e) {
            e.printStackTrace();
            return ResponseEntity.status(500).body("数据导入失败:" + e.getMessage());
        }
    }
    @GetMapping("/export")
    public ResponseEntity<byte[]> exportProducts() {
        try {
            byte[] bytes = productService.exportProducts();
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.parseMediaType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"));
            headers.setContentDispositionFormData("attachment", "products.xlsx");
            headers.setCacheControl("must-revalidate, post-check=0, pre-check=0");
            return ResponseEntity.ok().headers(headers).body(bytes);
        } catch (IOException e) {
            e.printStackTrace();
            return ResponseEntity.status(500).body(null);
        }
    }
    @PostMapping("/")
    public Product addProduct(@RequestBody Product product) {
        return productService.addProduct(product);
    }
    @GetMapping("/")
    public List<Product> getAllProducts() {
        return productService.getAllProducts();
    }
}

测试类:

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.web.client.TestRestTemplate;
import org.springframework.boot.web.server.LocalServerPort;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.commons.CommonsMultipartFile;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import static org.assertj.core.api.Assertions.assertThat;
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
class ProductApplicationTests {
    @LocalServerPort
    private int port;
    @Autowired
    private TestRestTemplate restTemplate;
    @Test
    void contextLoads() {
    }
    @Test
    void testAddProduct() {
        Product product = new Product("P006", "平板", 2000.0, 70);
        Product savedProduct = restTemplate.postForObject("http://localhost:" + port + "/api/products/", product, Product.class);
        assertThat(savedProduct).isNotNull();
        assertThat(savedProduct.getProductId()).isEqualTo("P006");
    }
    @Test
    void testGetAllProducts() {
        List<Product> products = restTemplate.getForObject("http://localhost:" + port + "/api/products/", List.class);
        assertThat(products).isNotNull();
        assertThat(products.size()).isGreaterThanOrEqualTo(5);
    }
    @Test
    void testImportProducts() throws IOException {
        File file = new File("src/test/resources/products.xlsx");
        InputStream inputStream = new FileInputStream(file);
        MultipartFile multipartFile = new CommonsMultipartFile(inputStream);
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.MULTIPART_FORM_DATA);
        MultiValueMap<String, Object> body = new LinkedMultiValueMap<>();
        body.add("file", multipartFile);
        HttpEntity<MultiValueMap<String, Object>> requestEntity = new HttpEntity<>(body, headers);
        ResponseEntity<String> response = restTemplate.exchange("http://localhost:" + port + "/api/products/import", HttpMethod.POST, requestEntity, String.class);
        assertThat(response.getStatusCodeValue()).isEqualTo(200);
        assertThat(response.getBody()).contains("数据导入成功");
    }
    @Test
    void testExportProducts() {
        ResponseEntity<byte[]> response = restTemplate.getForEntity("http://localhost:" + port + "/api/products/export", byte[].class);
        assertThat(response.getStatusCodeValue()).isEqualTo(200);
        assertThat(response.getBody()).isNotNull();
        assertThat(response.getBody().length).isGreaterThan(0);
    }
    @Test
    void testGenerateProductReport() {
        ResponseEntity<byte[]> response = restTemplate.getForEntity("http://localhost:" + port + "/api/products/report", byte[].class);
        assertThat(response.getStatusCodeValue()).isEqualTo(200);
        assertThat(response.getBody()).isNotNull();
        assertThat(response.getBody().length).isGreaterThan(0);
    }
}

✅ 结论:使用JasperReports是指Spring Boot与报表生成集成的基本方法之一,作用是实现报表生成、提高应用程序的性能。

24.5 Spring Boot的实际应用场景

在实际开发中,Spring Boot数据导入导出与报表生成的应用场景非常广泛,如:

  • 实现产品信息的导入导出。
  • 实现用户信息的导入导出。
  • 实现订单信息的导入导出。
  • 实现产品销售报表的生成。

示例

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class ProductApplication {
    public static void main(String[] args) {
        SpringApplication.run(ProductApplication.class, args);
    }
    @Autowired
    private ProductService productService;
    public void run(String... args) {
        // 初始化数据
        productService.addProduct(new Product("P001", "手机", 1000.0, 100));
        productService.addProduct(new Product("P002", "电脑", 5000.0, 50));
        productService.addProduct(new Product("P003", "电视", 3000.0, 80));
        productService.addProduct(new Product("P004", "手表", 500.0, 200));
        productService.addProduct(new Product("P005", "耳机", 300.0, 150));
    }
}
@Service
class ProductService {
    @Autowired
    private ProductRepository productRepository;
    @Transactional
    public void importProducts(MultipartFile file) throws IOException {
        List<Product> products = new ArrayList<>();
        Workbook workbook = new XSSFWorkbook(file.getInputStream());
        Sheet sheet = workbook.getSheetAt(0);
        Iterator<Row> iterator = sheet.iterator();
        if (iterator.hasNext()) {
            iterator.next(); // 跳过标题行
        }
        while (iterator.hasNext()) {
            Row currentRow = iterator.next();
            Product product = new Product();
            product.setProductId(currentRow.getCell(0).getStringCellValue());
            product.setProductName(currentRow.getCell(1).getStringCellValue());
            product.setPrice(currentRow.getCell(2).getNumericCellValue());
            product.setSales((int) currentRow.getCell(3).getNumericCellValue());
            products.add(product);
        }
        productRepository.saveAll(products);
        workbook.close();
    }
    @Transactional(readOnly = true)
    public byte[] exportProducts() throws IOException {
        List<Product> products = productRepository.findAll();
        Workbook workbook = new XSSFWorkbook();
        Sheet sheet = workbook.createSheet("Products");
        Row headerRow = sheet.createRow(0);
        Cell headerCell0 = headerRow.createCell(0);
        headerCell0.setCellValue("Product ID");
        Cell headerCell1 = headerRow.createCell(1);
        headerCell1.setCellValue("Product Name");
        Cell headerCell2 = headerRow.createCell(2);
        headerCell2.setCellValue("Price");
        Cell headerCell3 = headerRow.createCell(3);
        headerCell3.setCellValue("Sales");
        int rowNum = 1;
        for (Product product : products) {
            Row row = sheet.createRow(rowNum++);
            row.createCell(0).setCellValue(product.getProductId());
            row.createCell(1).setCellValue(product.getProductName());
            row.createCell(2).setCellValue(product.getPrice());
            row.createCell(3).setCellValue(product.getSales());
        }
        for (int i = 0; i < 4; i++) {
            sheet.autoSizeColumn(i);
        }
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        workbook.write(outputStream);
        workbook.close();
        return outputStream.toByteArray();
    }
    @Transactional
    public Product addProduct(Product product) {
        return productRepository.save(product);
    }
    @Transactional(readOnly = true)
    public List<Product> getAllProducts() {
        return productRepository.findAll();
    }
}
@RestController
@RequestMapping("/api/products")
class ProductController {
    @Autowired
    private ProductService productService;
    @Autowired
    private ReportService reportService;
    @GetMapping("/report")
    public ResponseEntity<byte[]> generateProductReport() {
        try {
            byte[] bytes = reportService.generateProductReport();
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.parseMediaType("application/pdf"));
            headers.setContentDispositionFormData("attachment", "product-report.pdf");
            headers.setCacheControl("must-revalidate, post-check=0, pre-check=0");
            return ResponseEntity.ok().headers(headers).body(bytes);
        } catch (JRException e) {
            e.printStackTrace();
            return ResponseEntity.status(500).body(null);
        }
    }
    @PostMapping("/import")
    public ResponseEntity<String> importProducts(@RequestParam("file") MultipartFile file) {
        try {
            productService.importProducts(file);
            return ResponseEntity.ok("数据导入成功");
        } catch (IOException e) {
            e.printStackTrace();
            return ResponseEntity.status(500).body("数据导入失败:" + e.getMessage());
        }
    }
    @GetMapping("/export")
    public ResponseEntity<byte[]> exportProducts() {
        try {
            byte[] bytes = productService.exportProducts();
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.parseMediaType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"));
            headers.setContentDispositionFormData("attachment", "products.xlsx");
            headers.setCacheControl("must-revalidate, post-check=0, pre-check=0");
            return ResponseEntity.ok().headers(headers).body(bytes);
        } catch (IOException e) {
            e.printStackTrace();
            return ResponseEntity.status(500).body(null);
        }
    }
    @PostMapping("/")
    public Product addProduct(@RequestBody Product product) {
        return productService.addProduct(product);
    }
    @GetMapping("/")
    public List<Product> getAllProducts() {
        return productService.getAllProducts();
    }
}
// 测试类
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
class ProductApplicationTests {
    @LocalServerPort
    private int port;
    @Autowired
    private TestRestTemplate restTemplate;
    @Test
    void contextLoads() {
    }
    @Test
    void testAddProduct() {
        Product product = new Product("P006", "平板", 2000.0, 70);
        Product savedProduct = restTemplate.postForObject("http://localhost:" + port + "/api/products/", product, Product.class);
        assertThat(savedProduct).isNotNull();
        assertThat(savedProduct.getProductId()).isEqualTo("P006");
    }
    @Test
    void testGetAllProducts() {
        List<Product> products = restTemplate.getForObject("http://localhost:" + port + "/api/products/", List.class);
        assertThat(products).isNotNull();
        assertThat(products.size()).isGreaterThanOrEqualTo(5);
    }
    @Test
    void testImportProducts() throws IOException {
        File file = new File("src/test/resources/products.xlsx");
        InputStream inputStream = new FileInputStream(file);
        MultipartFile multipartFile = new CommonsMultipartFile(inputStream);
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.MULTIPART_FORM_DATA);
        MultiValueMap<String, Object> body = new LinkedMultiValueMap<>();
        body.add("file", multipartFile);
        HttpEntity<MultiValueMap<String, Object>> requestEntity = new HttpEntity<>(body, headers);
        ResponseEntity<String> response = restTemplate.exchange("http://localhost:" + port + "/api/products/import", HttpMethod.POST, requestEntity, String.class);
        assertThat(response.getStatusCodeValue()).isEqualTo(200);
        assertThat(response.getBody()).contains("数据导入成功");
    }
    @Test
    void testExportProducts() {
        ResponseEntity<byte[]> response = restTemplate.getForEntity("http://localhost:" + port + "/api/products/export", byte[].class);
        assertThat(response.getStatusCodeValue()).isEqualTo(200);
        assertThat(response.getBody()).isNotNull();
        assertThat(response.getBody().length).isGreaterThan(0);
    }
    @Test
    void testGenerateProductReport() {
        ResponseEntity<byte[]> response = restTemplate.getForEntity("http://localhost:" + port + "/api/products/report", byte[].class);
        assertThat(response.getStatusCodeValue()).isEqualTo(200);
        assertThat(response.getBody()).isNotNull();
        assertThat(response.getBody().length).isGreaterThan(0);
    }
}

输出结果

  • 访问http://localhost:8080/api/products/report:下载产品销售报表(PDF格式)。
  • 访问http://localhost:8080/api/products/import:上传产品信息Excel文件,导入数据。
  • 访问http://localhost:8080/api/products/export:下载产品信息Excel文件。

✅ 结论:在实际开发中,Spring Boot数据导入导出与报表生成的应用场景非常广泛,需要根据实际问题选择合适的导入导出格式和报表生成工具。

总结

本章我们学习了Spring Boot数据导入导出与报表生成,包括数据导入导出的定义与特点、Spring Boot与数据导入导出的集成、Spring Boot与数据导入导出的配置、Spring Boot与报表生成的基本方法、Spring Boot的实际应用场景,学会了在实际开发中处理数据导入导出与报表生成问题。其中,数据导入导出的定义与特点、Spring Boot与数据导入导出的集成、Spring Boot与数据导入导出的配置、Spring Boot与报表生成的基本方法、Spring Boot的实际应用场景是本章的重点内容。从下一章开始,我们将学习Spring Boot的其他组件、微服务等内容。

到此这篇关于Spring Boot 数据导入导出与报表生成的基本方法的文章就介绍到这了,更多相关Spring Boot 数据导入导出内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 基于Java实现的Dijkstra算法示例

    基于Java实现的Dijkstra算法示例

    这篇文章主要介绍了基于Java实现的Dijkstra算法示例,一个比较典型的算法示例,需要的朋友可以参考下
    2014-07-07
  • Springboot es包版本异常解决方案

    Springboot es包版本异常解决方案

    这篇文章主要介绍了springboot 项目依赖 es包版本异常,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-03-03
  • java基础之Object类

    java基础之Object类

    这篇文章主要介绍了java基础之Object类 的相关资料,需要的朋友可以参考下
    2015-06-06
  • Java Swing JComboBox下拉列表框的示例代码

    Java Swing JComboBox下拉列表框的示例代码

    这篇文章主要介绍了Java Swing JComboBox下拉列表框的示例代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-12-12
  • 关于Spring Boot WebSocket整合以及nginx配置详解

    关于Spring Boot WebSocket整合以及nginx配置详解

    这篇文章主要给大家介绍了关于Spring Boot WebSocket整合以及nginx配置的相关资料,文中通过示例代码给大家介绍的非常详细,相信对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习下吧。
    2017-09-09
  • SpringBoot启动后初始化的几种方式汇总

    SpringBoot启动后初始化的几种方式汇总

    这篇文章主要介绍了SpringBoot启动后初始化的几种方式汇总,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2025-04-04
  • Java中抽象类和接口的用法详解

    Java中抽象类和接口的用法详解

    这篇文章主要为大家详细介绍了Java中抽象类和接口的使用,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你带来帮助
    2022-08-08
  • Springmvc异常处理器及拦截器实现代码

    Springmvc异常处理器及拦截器实现代码

    这篇文章主要介绍了Springmvc异常处理器及拦截器实现代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-10-10
  • java 数据结构与算法 (快速排序法)

    java 数据结构与算法 (快速排序法)

    这篇文章主要介绍了java 数据结构与算法(快速排序法),,快速排序法是实践中的一种快速的排序算法,在c++或对java基本类型的排序中特别有用,下面我们一起进入文章学习更详细的内容吧,需要的朋友可以参考下
    2022-02-02
  • Java分支结构和循环结构原理与用法详解

    Java分支结构和循环结构原理与用法详解

    这篇文章主要介绍了Java分支结构和循环结构原理与用法,结合实例形式分析了java分支结构、循环结构、跳转语句等相关概念、原理、使用技巧与操作注意事项,需要的朋友可以参考下
    2020-02-02

最新评论