您的位置:首页 > 新闻 > 会展 > 天津公司网站怎样制作_php程序员_网络营销网站推广_网站搭建源码

天津公司网站怎样制作_php程序员_网络营销网站推广_网站搭建源码

2025/3/7 3:12:30 来源:https://blog.csdn.net/qq_33807380/article/details/146025372  浏览:    关键词:天津公司网站怎样制作_php程序员_网络营销网站推广_网站搭建源码
天津公司网站怎样制作_php程序员_网络营销网站推广_网站搭建源码

一、实现方式

在Java中,导出数据到Excel有多种方式,每种方式都有其优缺点,适用于不同的场景。以下是常见的几种方式及其特点:

1.1 Apache POI

Apache POI 是 Java 中最流行的库,支持读写 Excel 文件(包括 .xls 和 .xlsx 格式)。

  • 特点:
    • 支持 .xls(HSSFWorkbook)和 .xlsx(XSSFWorkbook、SXSSFWorkbook)。
    • 功能强大,支持样式、公式、图表等。
    • SXSSFWorkbook 支持流式写入,适合大数据量导出。
  • 适用场景:
    • 需要导出复杂格式的 Excel 文件。
    • 大数据量导出(使用 SXSSFWorkbook)。
1.2 EasyExcel

EasyExcel 是阿里巴巴开源的 Excel 操作库,基于 Apache POI 封装,专注于大数据量导出和导入。

  • 特点:
    • 支持流式读写,内存占用低。
    • API 简单易用。
    • 支持 .xlsx 格式。
  • 适用场景:
    • 大数据量导出(百万级数据)。
    • 需要高性能和低内存占用的场景。
1.3 OpenCSV

虽然不是直接导出 Excel 文件,但 CSV 文件可以被 Excel 直接打开,适合简单的数据导出。

  • 特点:
    • 轻量级,速度快。
    • 文件格式简单,不支持样式、公式等。
    • 适合纯数据导出。
  • 适用场景:
    • 数据量较大,且不需要复杂格式。
    • 需要快速导出和导入。

二、使用SXSSFWorkbook

2.1 添加依赖

在pom.xml中添加Apache POI依赖:

<dependency><groupId>org.apache.poi</groupId><artifactId>poi-ooxml</artifactId><version>5.2.3</version>
</dependency>
<dependency><groupId>org.apache.poi</groupId><artifactId>poi-ooxml-schemas</artifactId><version>4.1.2</version>
</dependency>
2.2 定义数据模型

创建一个 Java 类表示导出的数据模型。

public class DataModel {private Long id;private String name;private Double value;// 构造方法、Getter 和 Setterpublic DataModel(Long id, String name, Double value) {this.id = id;this.name = name;this.value = value;}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 Double getValue() {return value;}public void setValue(Double value) {this.value = value;}
}
2.3 分页查询数据

使用Spring Data JPA或MyBatis进行分页查询。

import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;@Service
public class DataService {@Autowiredprivate DataRepository dataRepository;public Page<DataEntity> getDataByPage(int page, int size) {Pageable pageable = PageRequest.of(page, size);return dataRepository.findAll(pageable);}
}
2.4 多线程导出数据

使用线程池并行处理分页查询和数据写入。

import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;import java.io.FileOutputStream;
import java.io.IOException;
import java.util.List;
import java.util.concurrent.*;@Service
public class ExcelExportService {@Autowiredprivate DataService dataService;// 线程池配置private final ExecutorService executorService = Executors.newFixedThreadPool(10);public void exportLargeDataToExcel(String filePath, int pageSize) throws IOException, InterruptedException, ExecutionException {// 创建 SXSSFWorkbook,设置内存中保留的行数(默认100)try (SXSSFWorkbook workbook = new SXSSFWorkbook(100)) {Sheet sheet = workbook.createSheet("Sheet1");// 创建表头Row headerRow = sheet.createRow(0);headerRow.createCell(0).setCellValue("ID");headerRow.createCell(1).setCellValue("Name");headerRow.createCell(2).setCellValue("Value");// 计算总页数long totalCount = dataService.getTotalCount();int totalPages = (int) Math.ceil((double) totalCount / pageSize);// 使用 CountDownLatch 等待所有线程完成CountDownLatch latch = new CountDownLatch(totalPages);// 提交任务到线程池for (int page = 0; page < totalPages; page++) {final int currentPage = page;executorService.submit(() -> {try {// 分页查询数据Page<DataModel> dataPage = dataService.getDataByPage(currentPage, pageSize);List<DataModel> dataList = dataPage.getContent();// 写入当前页数据synchronized (sheet) {int startRow = currentPage * pageSize + 1; // 数据从第2行开始for (int i = 0; i < dataList.size(); i++) {DataModel data = dataList.get(i);Row row = sheet.createRow(startRow + i);row.createCell(0).setCellValue(data.getId());row.createCell(1).setCellValue(data.getName());row.createCell(2).setCellValue(data.getValue());}}} finally {latch.countDown(); // 任务完成}});}// 等待所有线程完成latch.await();// 写入文件try (FileOutputStream outputStream = new FileOutputStream(filePath)) {workbook.write(outputStream);}// 清理临时文件workbook.dispose();}// 关闭线程池executorService.shutdown();}
}
2.5 调用导出方法

在Controller或Service中调用导出方法。

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;import java.io.IOException;
import java.util.concurrent.ExecutionException;@RestController
@RequestMapping("/export")
public class ExportController {@Autowiredprivate ExcelExportService excelExportService;@GetMapping("/excel")public String exportToExcel() throws IOException, InterruptedException, ExecutionException {String filePath = "large_data_export.xlsx";excelExportService.exportLargeDataToExcel(filePath, 10000); // 每页查询10000条数据return "Export successful! File saved at: " + filePath;}
}

三、使用EasyExcel

3.1 添加依赖

在 pom.xml 中添加 EasyExcel 依赖:

<dependency><groupId>com.alibaba</groupId><artifactId>easyexcel</artifactId><version>3.3.2</version>
</dependency>
3.2 定义数据模型

创建一个 Java 类表示导出的数据模型。

import com.alibaba.excel.annotation.ExcelProperty;public class DataModel {@ExcelProperty("ID")private Long id;@ExcelProperty("Name")private String name;@ExcelProperty("Value")private Double value;// 构造方法、Getter 和 Setterpublic DataModel(Long id, String name, Double value) {this.id = id;this.name = name;this.value = value;}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 Double getValue() {return value;}public void setValue(Double value) {this.value = value;}
}
3.3 分页查询数据

使用 Spring Data JPA 或 MyBatis 进行分页查询。

import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;@Service
public class DataService {@Autowiredprivate DataRepository dataRepository;public Page<DataModel> getDataByPage(int page, int size) {Pageable pageable = PageRequest.of(page, size);return dataRepository.findAll(pageable);}
}
3.4 多线程导出数据

使用线程池并行处理分页查询和数据写入。

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.write.metadata.WriteSheet;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List;
import java.util.concurrent.*;@Service
public class ExcelExportService {@Autowiredprivate DataService dataService;// 线程池配置private final ExecutorService executorService = Executors.newFixedThreadPool(10);public void exportLargeDataToExcel(HttpServletResponse response, int pageSize) throws IOException, InterruptedException, ExecutionException {// 设置响应头response.setContentType("application/vnd.ms-excel");response.setCharacterEncoding("utf-8");String fileName = "large_data_export.xlsx";response.setHeader("Content-Disposition", "attachment;filename=" + fileName);// 创建 Excel 写入器WriteSheet writeSheet = EasyExcel.writerSheet("Sheet1").head(DataModel.class).build();// 计算总页数int totalPages = (int) Math.ceil((double) dataService.getTotalCount() / pageSize);// 使用 CountDownLatch 等待所有线程完成CountDownLatch latch = new CountDownLatch(totalPages);// 提交任务到线程池for (int page = 0; page < totalPages; page++) {final int currentPage = page;executorService.submit(() -> {try {// 分页查询数据Page<DataModel> dataPage = dataService.getDataByPage(currentPage, pageSize);List<DataModel> dataList = dataPage.getContent();// 写入当前页数据EasyExcel.write(response.getOutputStream(), DataModel.class).sheet("Sheet1").doWrite(dataList);} catch (IOException e) {e.printStackTrace();} finally {latch.countDown(); // 任务完成}});}// 等待所有线程完成latch.await();// 关闭线程池executorService.shutdown();}
}
3.5 Controller 调用导出方法

在 Controller 中调用导出方法。

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.concurrent.ExecutionException;@RestController
@RequestMapping("/export")
public class ExportController {@Autowiredprivate ExcelExportService excelExportService;@GetMapping("/excel")public void exportToExcel(HttpServletResponse response) throws IOException, InterruptedException, ExecutionException {excelExportService.exportLargeDataToExcel(response, 10000); // 每页查询10000条数据}
}

四、使用OpenCSV

4.1 添加依赖

在 pom.xml 中添加 OpenCSV 依赖:

<dependency><groupId>com.opencsv</groupId><artifactId>opencsv</artifactId><version>5.8</version>
</dependency>
4.2 定义数据模型

创建一个 Java 类表示导出的数据模型。

public class DataModel {private Long id;private String name;private Double value;// 构造方法、Getter 和 Setterpublic DataModel(Long id, String name, Double value) {this.id = id;this.name = name;this.value = value;}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 Double getValue() {return value;}public void setValue(Double value) {this.value = value;}
}
4.3 分页查询数据

使用 Spring Data JPA 或 MyBatis 进行分页查询。

import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;@Service
public class DataService {@Autowiredprivate DataRepository dataRepository;public Page<DataModel> getDataByPage(int page, int size) {Pageable pageable = PageRequest.of(page, size);return dataRepository.findAll(pageable);}public long getTotalCount() {return dataRepository.count();}
}
4.4 多线程导出数据

使用线程池并行处理分页查询和数据写入。

import com.opencsv.CSVWriter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.*;@Service
public class CsvExportService {@Autowiredprivate DataService dataService;// 线程池配置private final ExecutorService executorService = Executors.newFixedThreadPool(10);public void exportLargeDataToCsv(String filePath, int pageSize) throws IOException, InterruptedException, ExecutionException {// 创建 CSV 写入器try (CSVWriter writer = new CSVWriter(new FileWriter(filePath))) {// 写入表头writer.writeNext(new String[]{"ID", "Name", "Value"});// 计算总页数long totalCount = dataService.getTotalCount();int totalPages = (int) Math.ceil((double) totalCount / pageSize);// 使用 Future 保存每个线程的查询结果List<Future<List<DataModel>>> futures = new ArrayList<>();// 提交任务到线程池for (int page = 0; page < totalPages; page++) {final int currentPage = page;Future<List<DataModel>> future = executorService.submit(() -> {Page<DataModel> dataPage = dataService.getDataByPage(currentPage, pageSize);return dataPage.getContent();});futures.add(future);}// 合并所有线程的查询结果并写入 CSVfor (Future<List<DataModel>> future : futures) {List<DataModel> dataList = future.get();for (DataModel data : dataList) {writer.writeNext(new String[]{String.valueOf(data.getId()),data.getName(),String.valueOf(data.getValue())});}}}// 关闭线程池executorService.shutdown();}
}
4.5 Controller 调用导出方法

在 Controller 中调用导出方法。

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;import java.io.IOException;
import java.util.concurrent.ExecutionException;@RestController
@RequestMapping("/export")
public class ExportController {@Autowiredprivate CsvExportService csvExportService;@GetMapping("/csv")public String exportToCsv() throws IOException, InterruptedException, ExecutionException {String filePath = "large_data_export.csv";csvExportService.exportLargeDataToCsv(filePath, 10000); // 每页查询10000条数据return "Export successful! File saved at: " + filePath;}
}

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com