SpringBoot實(shí)現(xiàn)數(shù)據(jù)導(dǎo)入導(dǎo)出與報(bào)表生成的完整教程

學(xué)習(xí)目標(biāo)與重點(diǎn)提示
學(xué)習(xí)目標(biāo):掌握Spring Boot數(shù)據(jù)導(dǎo)入導(dǎo)出與報(bào)表生成的核心概念與使用方法,包括數(shù)據(jù)導(dǎo)入導(dǎo)出的定義與特點(diǎn)、Spring Boot與數(shù)據(jù)導(dǎo)入導(dǎo)出的集成、Spring Boot與數(shù)據(jù)導(dǎo)入導(dǎo)出的配置、Spring Boot與報(bào)表生成的基本方法、Spring Boot的實(shí)際應(yīng)用場(chǎng)景,學(xué)會(huì)在實(shí)際開(kāi)發(fā)中處理數(shù)據(jù)導(dǎo)入導(dǎo)出與報(bào)表生成問(wèn)題。
重點(diǎn):數(shù)據(jù)導(dǎo)入導(dǎo)出的定義與特點(diǎn)、Spring Boot與數(shù)據(jù)導(dǎo)入導(dǎo)出的集成、Spring Boot與數(shù)據(jù)導(dǎo)入導(dǎo)出的配置、Spring Boot與報(bào)表生成的基本方法、Spring Boot的實(shí)際應(yīng)用場(chǎng)景。
數(shù)據(jù)導(dǎo)入導(dǎo)出概述
數(shù)據(jù)導(dǎo)入導(dǎo)出是Java開(kāi)發(fā)中的重要組件。
數(shù)據(jù)導(dǎo)入導(dǎo)出的定義
定義:數(shù)據(jù)導(dǎo)入導(dǎo)出是指將數(shù)據(jù)從一個(gè)系統(tǒng)導(dǎo)入到另一個(gè)系統(tǒng),或從一個(gè)系統(tǒng)導(dǎo)出到另一個(gè)系統(tǒng)的過(guò)程。
作用:
- 實(shí)現(xiàn)數(shù)據(jù)的遷移。
- 實(shí)現(xiàn)數(shù)據(jù)的備份。
- 實(shí)現(xiàn)數(shù)據(jù)的共享。
常見(jiàn)的數(shù)據(jù)導(dǎo)入導(dǎo)出格式:
- CSV:Comma-Separated Values,逗號(hào)分隔值格式。
- Excel:Microsoft Excel格式。
- JSON:JavaScript Object Notation,JavaScript對(duì)象表示法格式。
- XML:eXtensible Markup Language,可擴(kuò)展標(biāo)記語(yǔ)言格式。
結(jié)論:數(shù)據(jù)導(dǎo)入導(dǎo)出是指將數(shù)據(jù)從一個(gè)系統(tǒng)導(dǎo)入到另一個(gè)系統(tǒng),或從一個(gè)系統(tǒng)導(dǎo)出到另一個(gè)系統(tǒng)的過(guò)程,作用是實(shí)現(xiàn)數(shù)據(jù)的遷移、備份、共享。
數(shù)據(jù)導(dǎo)入導(dǎo)出的特點(diǎn)
定義:數(shù)據(jù)導(dǎo)入導(dǎo)出的特點(diǎn)是指數(shù)據(jù)導(dǎo)入導(dǎo)出的特性。
特點(diǎn):
- 易用性:數(shù)據(jù)導(dǎo)入導(dǎo)出提供易用的編程模型。
- 高效性:數(shù)據(jù)導(dǎo)入導(dǎo)出提供高效的數(shù)據(jù)處理。
- 可擴(kuò)展性:數(shù)據(jù)導(dǎo)入導(dǎo)出可以擴(kuò)展到多個(gè)應(yīng)用程序之間的數(shù)據(jù)通信。
- 可靠性:數(shù)據(jù)導(dǎo)入導(dǎo)出提供可靠的數(shù)據(jù)傳輸。
結(jié)論:數(shù)據(jù)導(dǎo)入導(dǎo)出的特點(diǎn)包括易用性、高效性、可擴(kuò)展性、可靠性。
Spring Boot與數(shù)據(jù)導(dǎo)入導(dǎo)出的集成
Spring Boot與數(shù)據(jù)導(dǎo)入導(dǎo)出的集成是Java開(kāi)發(fā)中的重要內(nèi)容。
集成Apache POI的步驟
定義:集成Apache POI的步驟是指使用Spring Boot與Apache POI集成的方法。
步驟:
- 創(chuàng)建Spring Boot項(xiàng)目。
- 添加所需的依賴。
- 創(chuàng)建數(shù)據(jù)訪問(wèn)層。
- 創(chuàng)建業(yè)務(wù)層。
- 創(chuàng)建控制器類。
- 測(cè)試應(yīng)用。
示例: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數(shù)據(jù)庫(kù)依賴 -->
<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>
<!-- 測(cè)試依賴 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>application.properties文件中的配置:
# 服務(wù)器端口 server.port=8080 # 數(shù)據(jù)庫(kù)連接信息 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數(shù)據(jù)庫(kù)控制臺(tái) spring.h2.console.enabled=true spring.h2.console.path=/h2-console
實(shí)體類:
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(); // 跳過(guò)標(biāo)題行
}
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("數(shù)據(jù)導(dǎo)入成功");
} catch (IOException e) {
e.printStackTrace();
return ResponseEntity.status(500).body("數(shù)據(jù)導(dǎo)入失?。? + 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();
}
}
應(yīng)用啟動(dòng)類:
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) {
// 初始化數(shù)據(jù)
productService.addProduct(new Product("P001", "手機(jī)", 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", "耳機(jī)", 300.0, 150));
}
}
測(cè)試類:
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("數(shù)據(jù)導(dǎo)入成功");
}
@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);
}
}
結(jié)論:集成Apache POI的步驟包括創(chuàng)建Spring Boot項(xiàng)目、添加所需的依賴、創(chuàng)建數(shù)據(jù)訪問(wèn)層、創(chuàng)建業(yè)務(wù)層、創(chuàng)建控制器類、測(cè)試應(yīng)用。
Spring Boot與報(bào)表生成的基本方法
Spring Boot與報(bào)表生成的基本方法包括使用Apache POI、使用JasperReports、使用Excel模板。
使用JasperReports
定義:使用JasperReports是指Spring Boot與報(bào)表生成集成的基本方法之一。
作用:
- 實(shí)現(xiàn)報(bào)表生成。
- 提高應(yīng)用程序的性能。
示例: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數(shù)據(jù)庫(kù)依賴 -->
<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>
<!-- 測(cè)試依賴 -->
<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);
// 設(shè)置參數(shù)
Map<String, Object> parameters = new HashMap<>();
parameters.put("Title", "產(chǎn)品銷售報(bào)表");
// 設(shè)置數(shù)據(jù)源
JRBeanCollectionDataSource dataSource = new JRBeanCollectionDataSource(products);
// 生成報(bào)表
JasperPrint jasperPrint = JasperFillManager.fillReport(jasperReport, parameters, dataSource);
// 導(dǎo)出報(bào)表為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("數(shù)據(jù)導(dǎo)入成功");
} catch (IOException e) {
e.printStackTrace();
return ResponseEntity.status(500).body("數(shù)據(jù)導(dǎo)入失?。? + 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();
}
}
測(cè)試類:
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("數(shù)據(jù)導(dǎo)入成功");
}
@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);
}
}
結(jié)論:使用JasperReports是指Spring Boot與報(bào)表生成集成的基本方法之一,作用是實(shí)現(xiàn)報(bào)表生成、提高應(yīng)用程序的性能。
Spring Boot的實(shí)際應(yīng)用場(chǎng)景
在實(shí)際開(kāi)發(fā)中,Spring Boot數(shù)據(jù)導(dǎo)入導(dǎo)出與報(bào)表生成的應(yīng)用場(chǎng)景非常廣泛,如:
- 實(shí)現(xiàn)產(chǎn)品信息的導(dǎo)入導(dǎo)出。
- 實(shí)現(xiàn)用戶信息的導(dǎo)入導(dǎo)出。
- 實(shí)現(xiàn)訂單信息的導(dǎo)入導(dǎo)出。
- 實(shí)現(xiàn)產(chǎn)品銷售報(bào)表的生成。
示例:
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) {
// 初始化數(shù)據(jù)
productService.addProduct(new Product("P001", "手機(jī)", 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", "耳機(jī)", 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(); // 跳過(guò)標(biāo)題行
}
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("數(shù)據(jù)導(dǎo)入成功");
} catch (IOException e) {
e.printStackTrace();
return ResponseEntity.status(500).body("數(shù)據(jù)導(dǎo)入失?。? + 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();
}
}
// 測(cè)試類
@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("數(shù)據(jù)導(dǎo)入成功");
}
@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);
}
}
輸出結(jié)果:
訪問(wèn)http://localhost:8080/api/products/report:下載產(chǎn)品銷售報(bào)表(PDF格式)。
訪問(wèn)http://localhost:8080/api/products/import:上傳產(chǎn)品信息Excel文件,導(dǎo)入數(shù)據(jù)。
訪問(wèn)http://localhost:8080/api/products/export:下載產(chǎn)品信息Excel文件。
結(jié)論:在實(shí)際開(kāi)發(fā)中,Spring Boot數(shù)據(jù)導(dǎo)入導(dǎo)出與報(bào)表生成的應(yīng)用場(chǎng)景非常廣泛,需要根據(jù)實(shí)際問(wèn)題選擇合適的導(dǎo)入導(dǎo)出格式和報(bào)表生成工具。
總結(jié)
本章我們學(xué)習(xí)了Spring Boot數(shù)據(jù)導(dǎo)入導(dǎo)出與報(bào)表生成,包括數(shù)據(jù)導(dǎo)入導(dǎo)出的定義與特點(diǎn)、Spring Boot與數(shù)據(jù)導(dǎo)入導(dǎo)出的集成、Spring Boot與數(shù)據(jù)導(dǎo)入導(dǎo)出的配置、Spring Boot與報(bào)表生成的基本方法、Spring Boot的實(shí)際應(yīng)用場(chǎng)景,學(xué)會(huì)了在實(shí)際開(kāi)發(fā)中處理數(shù)據(jù)導(dǎo)入導(dǎo)出與報(bào)表生成問(wèn)題。其中,數(shù)據(jù)導(dǎo)入導(dǎo)出的定義與特點(diǎn)、Spring Boot與數(shù)據(jù)導(dǎo)入導(dǎo)出的集成、Spring Boot與數(shù)據(jù)導(dǎo)入導(dǎo)出的配置、Spring Boot與報(bào)表生成的基本方法、Spring Boot的實(shí)際應(yīng)用場(chǎng)景是本章的重點(diǎn)內(nèi)容。
以上就是SpringBoot實(shí)現(xiàn)數(shù)據(jù)導(dǎo)入導(dǎo)出與報(bào)表生成的完整教程的詳細(xì)內(nèi)容,更多關(guān)于SpringBoot數(shù)據(jù)導(dǎo)入導(dǎo)出的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
- 基于SpringBoot+FastExcel的百萬(wàn)級(jí)數(shù)據(jù)導(dǎo)入導(dǎo)出完整方案
- SpringBoot集成EasyExcel實(shí)現(xiàn)百萬(wàn)級(jí)別的數(shù)據(jù)導(dǎo)入導(dǎo)出實(shí)踐指南
- SpringBoot導(dǎo)入導(dǎo)出數(shù)據(jù)實(shí)現(xiàn)方法詳解
- Spring?Boot?+?EasyExcel實(shí)現(xiàn)數(shù)據(jù)導(dǎo)入導(dǎo)出
- 使用VUE+SpringBoot+EasyExcel?整合導(dǎo)入導(dǎo)出數(shù)據(jù)的教程詳解
- SpringBoot整合EasyExcel實(shí)現(xiàn)導(dǎo)入導(dǎo)出數(shù)據(jù)
相關(guān)文章
Java 如何繞過(guò)迭代器遍歷時(shí)的數(shù)據(jù)修改異常
這篇文章主要介紹了Java 繞過(guò)迭代器遍歷時(shí)的數(shù)據(jù)修改異常的方法,幫助大家更好的理解和學(xué)習(xí)使用Java,感興趣的朋友可以了解下2021-02-02
Java數(shù)據(jù)結(jié)構(gòu)之圖的兩種搜索算法詳解
在很多情況下,我們需要遍歷圖,得到圖的一些性質(zhì)。有關(guān)圖的搜索,最經(jīng)典的算法有深度優(yōu)先搜索和廣度優(yōu)先搜索,接下來(lái)我們分別講解這兩種搜索算法,需要的可以參考一下2022-11-11
關(guān)于Java語(yǔ)法糖以及語(yǔ)法糖的原理和用法
這篇文章主要介紹了關(guān)于Java什么是語(yǔ)法糖以及語(yǔ)法糖的種類,也稱糖衣語(yǔ)法,是由英國(guó)計(jì)算機(jī)學(xué)家?Peter.J.Landin?發(fā)明的一個(gè)術(shù)語(yǔ),指在計(jì)算機(jī)語(yǔ)言中添加的某種語(yǔ)法,這種語(yǔ)法對(duì)語(yǔ)言的功能并沒(méi)有影響,但是更方便程序員使用,需要的朋友可以參考下2023-05-05
SpringRunner和SpringJUnit4ClassRunner的區(qū)別及說(shuō)明
這篇文章主要介紹了SpringRunner和SpringJUnit4ClassRunner的區(qū)別及說(shuō)明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-04-04
詳解如何在Spring中為@Value注解設(shè)置默認(rèn)值
在Spring開(kāi)發(fā)中,我們經(jīng)常會(huì)遇到需要從配置文件中讀取屬性的情況,@Value注解是Spring提供的一種便捷方式,能夠讓我們輕松地將配置文件中的屬性注入到Spring Bean中,2024-10-10
SpringMVC結(jié)合Jcrop實(shí)現(xiàn)圖片裁剪
這篇文章主要介紹了SpringMVC結(jié)合Jcrop實(shí)現(xiàn)圖片裁剪的相關(guān)資料,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-12-12

