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

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 

实体类:

importjavax.persistence.*;@Entity@Table(name ="product")publicclassProduct{@Id@GeneratedValue(strategy =GenerationType.IDENTITY)privateLong id;privateString productId;privateString productName;privatedouble price;privateint sales;publicProduct(){}publicProduct(String productId,String productName,double price,int sales){this.productId = productId;this.productName = productName;this.price = price;this.sales = sales;}// Getter和Setter方法publicLonggetId(){return id;}publicvoidsetId(Long id){this.id = id;}publicStringgetProductId(){return productId;}publicvoidsetProductId(String productId){this.productId = productId;}publicStringgetProductName(){return productName;}publicvoidsetProductName(String productName){this.productName = productName;}publicdoublegetPrice(){return price;}publicvoidsetPrice(double price){this.price = price;}publicintgetSales(){return sales;}publicvoidsetSales(int sales){this.sales = sales;}@OverridepublicStringtoString(){return"Product{"+"id="+ id +",+ productId +'\''+",+ productName +'\''+", price="+ price +", sales="+ sales +'}';}}

Repository接口:

importorg.springframework.data.jpa.repository.JpaRepository;importorg.springframework.stereotype.Repository;@RepositorypublicinterfaceProductRepositoryextendsJpaRepository<Product,Long>{}

Service类:

importorg.apache.poi.ss.usermodel.*;importorg.apache.poi.xssf.usermodel.XSSFWorkbook;importorg.springframework.beans.factory.annotation.Autowired;importorg.springframework.stereotype.Service;importorg.springframework.transaction.annotation.Transactional;importorg.springframework.web.multipart.MultipartFile;importjava.io.ByteArrayOutputStream;importjava.io.IOException;importjava.util.ArrayList;importjava.util.Iterator;importjava.util.List;@ServicepublicclassProductService{@AutowiredprivateProductRepository productRepository;@TransactionalpublicvoidimportProducts(MultipartFile file)throwsIOException{List<Product> products =newArrayList<>();Workbook workbook =newXSSFWorkbook(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 =newProduct(); 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)publicbyte[]exportProducts()throwsIOException{List<Product> products = productRepository.findAll();Workbook workbook =newXSSFWorkbook();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 =newByteArrayOutputStream(); workbook.write(outputStream); workbook.close();return outputStream.toByteArray();}@TransactionalpublicProductaddProduct(Product product){return productRepository.save(product);}@Transactional(readOnly =true)publicList<Product>getAllProducts(){return productRepository.findAll();}}

控制器类:

importorg.springframework.beans.factory.annotation.Autowired;importorg.springframework.http.HttpHeaders;importorg.springframework.http.MediaType;importorg.springframework.http.ResponseEntity;importorg.springframework.web.bind.annotation.*;importorg.springframework.web.multipart.MultipartFile;importjava.io.IOException;importjava.util.List;@RestController@RequestMapping("/api/products")publicclassProductController{@AutowiredprivateProductService productService;@PostMapping("/import")publicResponseEntity<String>importProducts(@RequestParam("file")MultipartFile file){try{ productService.importProducts(file);returnResponseEntity.ok("数据导入成功");}catch(IOException e){ e.printStackTrace();returnResponseEntity.status(500).body("数据导入失败:"+ e.getMessage());}}@GetMapping("/export")publicResponseEntity<byte[]>exportProducts(){try{byte[] bytes = productService.exportProducts();HttpHeaders headers =newHttpHeaders(); 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");returnResponseEntity.ok().headers(headers).body(bytes);}catch(IOException e){ e.printStackTrace();returnResponseEntity.status(500).body(null);}}@PostMapping("/")publicProductaddProduct(@RequestBodyProduct product){return productService.addProduct(product);}@GetMapping("/")publicList<Product>getAllProducts(){return productService.getAllProducts();}}

应用启动类:

importorg.springframework.beans.factory.annotation.Autowired;importorg.springframework.boot.SpringApplication;importorg.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplicationpublicclassProductApplication{publicstaticvoidmain(String[] args){SpringApplication.run(ProductApplication.class, args);}@AutowiredprivateProductService productService;publicvoidrun(String... args){// 初始化数据 productService.addProduct(newProduct("P001","手机",1000.0,100)); productService.addProduct(newProduct("P002","电脑",5000.0,50)); productService.addProduct(newProduct("P003","电视",3000.0,80)); productService.addProduct(newProduct("P004","手表",500.0,200)); productService.addProduct(newProduct("P005","耳机",300.0,150));}}

测试类:

importorg.junit.jupiter.api.Test;importorg.springframework.beans.factory.annotation.Autowired;importorg.springframework.boot.test.context.SpringBootTest;importorg.springframework.boot.test.web.client.TestRestTemplate;importorg.springframework.boot.web.server.LocalServerPort;importorg.springframework.http.HttpEntity;importorg.springframework.http.HttpHeaders;importorg.springframework.http.HttpMethod;importorg.springframework.http.ResponseEntity;importorg.springframework.util.LinkedMultiValueMap;importorg.springframework.util.MultiValueMap;importorg.springframework.web.multipart.MultipartFile;importorg.springframework.web.multipart.commons.CommonsMultipartFile;importjava.io.File;importjava.io.FileInputStream;importjava.io.IOException;importjava.io.InputStream;importstaticorg.assertj.core.api.Assertions.assertThat;@SpringBootTest(webEnvironment =SpringBootTest.WebEnvironment.RANDOM_PORT)classProductApplicationTests{@LocalServerPortprivateint port;@AutowiredprivateTestRestTemplate restTemplate;@TestvoidcontextLoads(){}@TestvoidtestAddProduct(){Product product =newProduct("P006","平板",2000.0,70);Product savedProduct = restTemplate.postForObject("http://localhost:"+ port +"/api/products/", product,Product.class);assertThat(savedProduct).isNotNull();assertThat(savedProduct.getProductId()).isEqualTo("P006");}@TestvoidtestGetAllProducts(){List<Product> products = restTemplate.getForObject("http://localhost:"+ port +"/api/products/",List.class);assertThat(products).isNotNull();assertThat(products.size()).isGreaterThanOrEqualTo(5);}@TestvoidtestImportProducts()throwsIOException{File file =newFile("src/test/resources/products.xlsx");InputStream inputStream =newFileInputStream(file);MultipartFile multipartFile =newCommonsMultipartFile(inputStream);HttpHeaders headers =newHttpHeaders(); headers.setContentType(MediaType.MULTIPART_FORM_DATA);MultiValueMap<String,Object> body =newLinkedMultiValueMap<>(); body.add("file", multipartFile);HttpEntity<MultiValueMap<String,Object>> requestEntity =newHttpEntity<>(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("数据导入成功");}@TestvoidtestExportProducts(){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类:

importnet.sf.jasperreports.engine.*;importnet.sf.jasperreports.engine.data.JRBeanCollectionDataSource;importorg.springframework.beans.factory.annotation.Autowired;importorg.springframework.stereotype.Service;importorg.springframework.transaction.annotation.Transactional;importjava.io.ByteArrayOutputStream;importjava.io.InputStream;importjava.util.HashMap;importjava.util.List;importjava.util.Map;@ServicepublicclassReportService{@AutowiredprivateProductRepository productRepository;@Transactional(readOnly =true)publicbyte[]generateProductReport()throwsJRException{List<Product> products = productRepository.findAll();// 加载Jasper模板InputStream templateStream =getClass().getResourceAsStream("/reports/product-report.jasper");JasperReport jasperReport =(JasperReport)JRLoader.loadObject(templateStream);// 设置参数Map<String,Object> parameters =newHashMap<>(); parameters.put("Title","产品销售报表");// 设置数据源JRBeanCollectionDataSource dataSource =newJRBeanCollectionDataSource(products);// 生成报表JasperPrint jasperPrint =JasperFillManager.fillReport(jasperReport, parameters, dataSource);// 导出报表为PDFByteArrayOutputStream outputStream =newByteArrayOutputStream();JasperExportManager.exportReportToPdfStream(jasperPrint, outputStream);return outputStream.toByteArray();}}

控制器类:

importnet.sf.jasperreports.engine.JRException;importorg.springframework.beans.factory.annotation.Autowired;importorg.springframework.http.HttpHeaders;importorg.springframework.http.MediaType;importorg.springframework.http.ResponseEntity;importorg.springframework.web.bind.annotation.*;importorg.springframework.web.multipart.MultipartFile;importjava.io.IOException;importjava.util.List;@RestController@RequestMapping("/api/products")publicclassProductController{@AutowiredprivateProductService productService;@AutowiredprivateReportService reportService;@GetMapping("/report")publicResponseEntity<byte[]>generateProductReport(){try{byte[] bytes = reportService.generateProductReport();HttpHeaders headers =newHttpHeaders(); headers.setContentType(MediaType.parseMediaType("application/pdf")); headers.setContentDispositionFormData("attachment","product-report.pdf"); headers.setCacheControl("must-revalidate, post-check=0, pre-check=0");returnResponseEntity.ok().headers(headers).body(bytes);}catch(JRException e){ e.printStackTrace();returnResponseEntity.status(500).body(null);}}@PostMapping("/import")publicResponseEntity<String>importProducts(@RequestParam("file")MultipartFile file){try{ productService.importProducts(file);returnResponseEntity.ok("数据导入成功");}catch(IOException e){ e.printStackTrace();returnResponseEntity.status(500).body("数据导入失败:"+ e.getMessage());}}@GetMapping("/export")publicResponseEntity<byte[]>exportProducts(){try{byte[] bytes = productService.exportProducts();HttpHeaders headers =newHttpHeaders(); 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");returnResponseEntity.ok().headers(headers).body(bytes);}catch(IOException e){ e.printStackTrace();returnResponseEntity.status(500).body(null);}}@PostMapping("/")publicProductaddProduct(@RequestBodyProduct product){return productService.addProduct(product);}@GetMapping("/")publicList<Product>getAllProducts(){return productService.getAllProducts();}}

测试类:

importorg.junit.jupiter.api.Test;importorg.springframework.beans.factory.annotation.Autowired;importorg.springframework.boot.test.context.SpringBootTest;importorg.springframework.boot.test.web.client.TestRestTemplate;importorg.springframework.boot.web.server.LocalServerPort;importorg.springframework.http.HttpEntity;importorg.springframework.http.HttpHeaders;importorg.springframework.http.HttpMethod;importorg.springframework.http.ResponseEntity;importorg.springframework.util.LinkedMultiValueMap;importorg.springframework.util.MultiValueMap;importorg.springframework.web.multipart.MultipartFile;importorg.springframework.web.multipart.commons.CommonsMultipartFile;importjava.io.File;importjava.io.FileInputStream;importjava.io.IOException;importjava.io.InputStream;importstaticorg.assertj.core.api.Assertions.assertThat;@SpringBootTest(webEnvironment =SpringBootTest.WebEnvironment.RANDOM_PORT)classProductApplicationTests{@LocalServerPortprivateint port;@AutowiredprivateTestRestTemplate restTemplate;@TestvoidcontextLoads(){}@TestvoidtestAddProduct(){Product product =newProduct("P006","平板",2000.0,70);Product savedProduct = restTemplate.postForObject("http://localhost:"+ port +"/api/products/", product,Product.class);assertThat(savedProduct).isNotNull();assertThat(savedProduct.getProductId()).isEqualTo("P006");}@TestvoidtestGetAllProducts(){List<Product> products = restTemplate.getForObject("http://localhost:"+ port +"/api/products/",List.class);assertThat(products).isNotNull();assertThat(products.size()).isGreaterThanOrEqualTo(5);}@TestvoidtestImportProducts()throwsIOException{File file =newFile("src/test/resources/products.xlsx");InputStream inputStream =newFileInputStream(file);MultipartFile multipartFile =newCommonsMultipartFile(inputStream);HttpHeaders headers =newHttpHeaders(); headers.setContentType(MediaType.MULTIPART_FORM_DATA);MultiValueMap<String,Object> body =newLinkedMultiValueMap<>(); body.add("file", multipartFile);HttpEntity<MultiValueMap<String,Object>> requestEntity =newHttpEntity<>(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("数据导入成功");}@TestvoidtestExportProducts(){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);}@TestvoidtestGenerateProductReport(){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数据导入导出与报表生成的应用场景非常广泛,如:

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

示例

importorg.springframework.beans.factory.annotation.Autowired;importorg.springframework.boot.SpringApplication;importorg.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplicationpublicclassProductApplication{publicstaticvoidmain(String[] args){SpringApplication.run(ProductApplication.class, args);}@AutowiredprivateProductService productService;publicvoidrun(String... args){// 初始化数据 productService.addProduct(newProduct("P001","手机",1000.0,100)); productService.addProduct(newProduct("P002","电脑",5000.0,50)); productService.addProduct(newProduct("P003","电视",3000.0,80)); productService.addProduct(newProduct("P004","手表",500.0,200)); productService.addProduct(newProduct("P005","耳机",300.0,150));}}@ServiceclassProductService{@AutowiredprivateProductRepository productRepository;@TransactionalpublicvoidimportProducts(MultipartFile file)throwsIOException{List<Product> products =newArrayList<>();Workbook workbook =newXSSFWorkbook(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 =newProduct(); 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)publicbyte[]exportProducts()throwsIOException{List<Product> products = productRepository.findAll();Workbook workbook =newXSSFWorkbook();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 =newByteArrayOutputStream(); workbook.write(outputStream); workbook.close();return outputStream.toByteArray();}@TransactionalpublicProductaddProduct(Product product){return productRepository.save(product);}@Transactional(readOnly =true)publicList<Product>getAllProducts(){return productRepository.findAll();}}@RestController@RequestMapping("/api/products")classProductController{@AutowiredprivateProductService productService;@AutowiredprivateReportService reportService;@GetMapping("/report")publicResponseEntity<byte[]>generateProductReport(){try{byte[] bytes = reportService.generateProductReport();HttpHeaders headers =newHttpHeaders(); headers.setContentType(MediaType.parseMediaType("application/pdf")); headers.setContentDispositionFormData("attachment","product-report.pdf"); headers.setCacheControl("must-revalidate, post-check=0, pre-check=0");returnResponseEntity.ok().headers(headers).body(bytes);}catch(JRException e){ e.printStackTrace();returnResponseEntity.status(500).body(null);}}@PostMapping("/import")publicResponseEntity<String>importProducts(@RequestParam("file")MultipartFile file){try{ productService.importProducts(file);returnResponseEntity.ok("数据导入成功");}catch(IOException e){ e.printStackTrace();returnResponseEntity.status(500).body("数据导入失败:"+ e.getMessage());}}@GetMapping("/export")publicResponseEntity<byte[]>exportProducts(){try{byte[] bytes = productService.exportProducts();HttpHeaders headers =newHttpHeaders(); 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");returnResponseEntity.ok().headers(headers).body(bytes);}catch(IOException e){ e.printStackTrace();returnResponseEntity.status(500).body(null);}}@PostMapping("/")publicProductaddProduct(@RequestBodyProduct product){return productService.addProduct(product);}@GetMapping("/")publicList<Product>getAllProducts(){return productService.getAllProducts();}}// 测试类@SpringBootTest(webEnvironment =SpringBootTest.WebEnvironment.RANDOM_PORT)classProductApplicationTests{@LocalServerPortprivateint port;@AutowiredprivateTestRestTemplate restTemplate;@TestvoidcontextLoads(){}@TestvoidtestAddProduct(){Product product =newProduct("P006","平板",2000.0,70);Product savedProduct = restTemplate.postForObject("http://localhost:"+ port +"/api/products/", product,Product.class);assertThat(savedProduct).isNotNull();assertThat(savedProduct.getProductId()).isEqualTo("P006");}@TestvoidtestGetAllProducts(){List<Product> products = restTemplate.getForObject("http://localhost:"+ port +"/api/products/",List.class);assertThat(products).isNotNull();assertThat(products.size()).isGreaterThanOrEqualTo(5);}@TestvoidtestImportProducts()throwsIOException{File file =newFile("src/test/resources/products.xlsx");InputStream inputStream =newFileInputStream(file);MultipartFile multipartFile =newCommonsMultipartFile(inputStream);HttpHeaders headers =newHttpHeaders(); headers.setContentType(MediaType.MULTIPART_FORM_DATA);MultiValueMap<String,Object> body =newLinkedMultiValueMap<>(); body.add("file", multipartFile);HttpEntity<MultiValueMap<String,Object>> requestEntity =newHttpEntity<>(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("数据导入成功");}@TestvoidtestExportProducts(){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);}@TestvoidtestGenerateProductReport(){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的其他组件、微服务等内容。

Read more

医疗AI场景下算法编程的深度解析(2026新生培训讲稿)(八)

医疗AI场景下算法编程的深度解析(2026新生培训讲稿)(八)

第15章 模型融合与集成策略 在机器学习竞赛和实际应用中,模型融合(Model Ensemble)是提升预测性能的利器。通过组合多个不同的基模型,集成策略能够综合各个模型的优势,抵消单个模型的偏差和方差,从而获得比任何单一模型更稳定、更准确的预测结果。在医疗AI领域,模型融合同样具有重要价值——面对复杂多模态的医疗数据,单一模型往往难以全面捕捉所有信息,而融合多个异质模型可以提升诊断的鲁棒性和准确性。本章将从集成学习的基本思想出发,系统介绍常见的模型融合方法,包括投票法、平均法、Stacking、Blending等,并通过实战案例展示如何构建融合模型来提升疾病预测性能。 15.1 集成学习的基本思想 集成学习(Ensemble Learning)的核心思想是“三个臭皮匠,顶个诸葛亮”——通过结合多个学习器来完成学习任务,通常可以获得比单一学习器更优越的泛化性能。根据个体学习器的生成方式,集成学习主要分为两大类: * Bagging:并行训练多个独立的基学习器,然后通过平均或投票进行结合。典型代表是随机森林。Bagging主要降低方差。 * Boosting:串行训练基学习

By Ne0inhk
人工智能:自然语言处理高级应用与前沿发展

人工智能:自然语言处理高级应用与前沿发展

人工智能:自然语言处理高级应用与前沿发展 学习目标 💡 理解自然语言处理(NLP)的前沿技术和发展趋势 💡 掌握高级NLP应用(如文本生成、情感分析、机器翻译) 💡 学会使用前沿NLP模型(如GPT-3、BERT、T5) 💡 理解NLP在多模态融合、零样本学习、少样本学习中的应用 💡 通过实战项目,开发一个高级文本生成应用 重点内容 * NLP前沿技术和发展趋势 * 高级NLP应用(文本生成、情感分析、机器翻译) * 前沿NLP模型(GPT-3、BERT、T5) * 多模态融合、零样本学习、少样本学习 * 实战项目:高级文本生成应用开发 一、NLP前沿技术和发展趋势 1.1 多模态融合 1.1.1 多模态融合的基本概念 多模态融合是将不同模态的数据(如文本、图像、音频)结合起来,进行处理和分析的过程。它可以提高模型的性能和准确性。

By Ne0inhk
OpenClaw接入企业微信全攻略:从0到1打通企业AI协作通道

OpenClaw接入企业微信全攻略:从0到1打通企业AI协作通道

摘要:本文详细介绍了将OpenClaw AI框架接入企业微信的完整方案。通过两种主流接入方式(API模式机器人和自建应用),企业可以快速实现智能问答、流程自动化等AI能力落地。文章重点讲解了从前期准备、核心接入流程到生产环境部署的全套实操步骤,包括权限配置、网络设置、参数对接等关键环节。同时提供了进阶优化建议,如后台守护、HTTPS加固、权限管控等企业级功能配置,以及常见问题排查方法。该方案能有效解决企业信息孤岛问题,将AI能力无缝嵌入员工日常办公场景,在保障数据安全的同时显著提升工作效率。 目录 一、前言:为什么要将OpenClaw接入企业微信? 二、接入前置准备 OpenClaw介绍 接入准备工作 三、核心接入流程(两种方案任选) 方案一:API模式机器人接入(新手首选,快速上手) 步骤1:企业微信后台创建API模式机器人 步骤2:OpenClaw安装企微插件并配置参数 步骤3:完成机器人创建并测试联调 方案二:企业微信自建应用接入(企业级进阶方案) 步骤1:企业微信创建自建应用并获取核心凭证 步骤2:OpenClaw配置自建应用核心参数 步骤3:启用应

By Ne0inhk