本文目录导读:

我来为您提供几个Java文件导出的提速案例及优化方案:
大数据量Excel导出优化
优化前 - 使用POI SXSSFWorkbook(慢)
// 慢的方式:全部数据在内存中处理
public void exportSlow(List<Data> dataList, OutputStream out) {
try (XSSFWorkbook workbook = new XSSFWorkbook()) {
XSSFSheet sheet = workbook.createSheet("数据");
for (int i = 0; i < dataList.size(); i++) {
XSSFRow row = sheet.createRow(i);
Data data = dataList.get(i);
row.createCell(0).setCellValue(data.getId());
row.createCell(1).setCellValue(data.getName());
// ... 更多字段
}
workbook.write(out);
}
}
优化后 - 使用SXSSFWorkbook(流式写入)
public void exportFast(List<Data> dataList, OutputStream out) {
// SXSSFWorkbook:流式写入,内存中只保留100行
SXSSFWorkbook workbook = new SXSSFWorkbook(100);
SXSSFSheet sheet = workbook.createSheet("数据");
// 批量写入
int rowNum = 0;
for (Data data : dataList) {
SXSSFRow row = sheet.createRow(rowNum++);
row.createCell(0).setCellValue(data.getId());
row.createCell(1).setCellValue(data.getName());
}
// 写入磁盘
workbook.write(out);
workbook.dispose(); // 清理临时文件
}
多线程并发导出
public class ConcurrentExportService {
public void exportLargeData(List<Integer> ids, OutputStream out) {
// 分片处理
int batchSize = 1000;
List<List<Integer>> batches = partition(ids, batchSize);
// 使用线程池并行处理
ExecutorService executor = Executors.newFixedThreadPool(
Runtime.getRuntime().availableProcessors()
);
List<CompletableFuture<byte[]>> futures = new ArrayList<>();
for (List<Integer> batch : batches) {
CompletableFuture<byte[]> future = CompletableFuture.supplyAsync(() -> {
return processBatch(batch);
}, executor);
futures.add(future);
}
// 合并结果
try {
// 使用临时文件存储
Path tempFile = Files.createTempFile("export", ".csv");
try (FileOutputStream fos = new FileOutputStream(tempFile.toFile())) {
for (CompletableFuture<byte[]> future : futures) {
byte[] data = future.get();
fos.write(data);
fos.flush();
}
}
// 复制到输出流
Files.copy(tempFile, out);
// 清理临时文件
Files.deleteIfExists(tempFile);
} catch (Exception e) {
// 异常处理
} finally {
executor.shutdown();
}
}
private byte[] processBatch(List<Integer> ids) {
// 查询数据库获取数据
List<Data> dataList = queryData(ids);
// 转换为CSV格式
StringBuilder sb = new StringBuilder();
for (Data data : dataList) {
sb.append(data.getId()).append(",")
.append(data.getName()).append(",")
.append(data.getValue()).append("\n");
}
return sb.toString().getBytes(StandardCharsets.UTF_8);
}
}
文件分批写入(CSV示例)
public class BatchFileExport {
private static final int BATCH_SIZE = 5000;
public void exportLargeCsv(List<Data> dataList, OutputStream out) {
try (BufferedWriter writer = new BufferedWriter(
new OutputStreamWriter(out, StandardCharsets.UTF_8))) {
// 写入表头
writer.write("ID,Name,Value,Date");
writer.newLine();
// 分批写入
int counter = 0;
for (Data data : dataList) {
StringBuilder line = new StringBuilder();
line.append(data.getId()).append(",")
.append(escapeCsv(data.getName())).append(",")
.append(data.getValue()).append(",")
.append(data.getDate());
writer.write(line.toString());
writer.newLine();
counter++;
// 每批刷新一次缓冲区
if (counter % BATCH_SIZE == 0) {
writer.flush();
}
}
writer.flush();
} catch (IOException e) {
throw new RuntimeException("导出失败", e);
}
}
private String escapeCsv(String value) {
if (value == null) return "";
if (value.contains(",") || value.contains("\"") || value.contains("\n")) {
return "\"" + value.replace("\"", "\"\"") + "\"";
}
return value;
}
}
使用NIO零拷贝(大文件复制)
public class ZeroCopyExport {
public void exportUsingNIO(File source, OutputStream out) throws IOException {
try (FileChannel sourceChannel = new FileInputStream(source).getChannel();
WritableByteChannel targetChannel = Channels.newChannel(out)) {
// 使用transferTo进行零拷贝
long position = 0;
long size = sourceChannel.size();
while (position < size) {
long transferred = sourceChannel.transferTo(
position,
Math.min(size - position, 1024 * 1024 * 10), // 每次10MB
targetChannel
);
position += transferred;
}
}
}
}
数据库分页+游标查询
public class CursorExportService {
public void exportWithCursor(OutputStream out) {
// 使用JDBC游标或MyBatis游标
try (SqlSession session = sqlSessionFactory.openSession(ExecutorType.SIMPLE)) {
DataMapper mapper = session.getMapper(DataMapper.class);
// 使用游标查询,避免内存溢出
Cursor<Data> cursor = mapper.scanAllData();
try (BufferedWriter writer = new BufferedWriter(
new OutputStreamWriter(out, StandardCharsets.UTF_8))) {
writer.write("ID,Name,Value\n");
for (Data data : cursor) {
writer.write(String.format("%d,%s,%s\n",
data.getId(), data.getName(), data.getValue()));
writer.flush(); // 定期刷新
}
}
}
}
}
压缩输出(减少传输时间)
public class CompressedExport {
public void exportCompressed(List<Data> dataList, OutputStream out) {
try (GZIPOutputStream gzipOut = new GZIPOutputStream(out);
BufferedWriter writer = new BufferedWriter(
new OutputStreamWriter(gzipOut, StandardCharsets.UTF_8))) {
// 写入数据
for (Data data : dataList) {
writer.write(String.format("%s,%s,%s\n",
data.getId(), data.getName(), data.getValue()));
}
writer.flush();
gzipOut.finish();
} catch (IOException e) {
throw new RuntimeException("导出失败", e);
}
}
// 使用ZIP格式支持多个文件
public void exportZip(Map<String, List<Data>> dataMap, OutputStream out) {
try (ZipOutputStream zos = new ZipOutputStream(out)) {
for (Map.Entry<String, List<Data>> entry : dataMap.entrySet()) {
ZipEntry zipEntry = new ZipEntry(entry.getKey() + ".csv");
zos.putNextEntry(zipEntry);
StringBuilder content = new StringBuilder();
for (Data data : entry.getValue()) {
content.append(data.getId()).append(",")
.append(data.getName()).append("\n");
}
zos.write(content.toString().getBytes(StandardCharsets.UTF_8));
zos.closeEntry();
}
} catch (IOException e) {
throw new RuntimeException("导出失败", e);
}
}
}
性能测试对比
public class ExportPerformanceTest {
public static void main(String[] args) {
List<Data> testData = generateTestData(100000); // 10万条数据
// 测试不同方式
testExport("传统POI", () -> {
// 原始方式
exportWithXSSF(testData);
});
testExport("SXSSF流式", () -> {
// 优化方式
exportWithSXSSF(testData);
});
testExport("多线程CSV", () -> {
// 多线程方式
exportWithMultiThread(testData);
});
}
private static void testExport(String name, Runnable task) {
long start = System.currentTimeMillis();
task.run();
long end = System.currentTimeMillis();
System.out.println(name + " 耗时: " + (end - start) + "ms");
}
}
-
选择合适的技术:
- 小数据量 (<1万):POI XSSFWorkbook
- 大数据量 (>1万):SXSSFWorkbook或CSV
- 超大文件:使用CSV + 压缩
-
使用流式处理:
- 避免一次性加载所有数据到内存
- 批量写入并定期刷新
-
并行处理:
- 利用多核CPU进行数据准备
- 分片查询数据库
-
减少I/O操作:
- 使用BufferedWriter缓冲
- 控制刷新频率
-
压缩输出:
使用GZIP或ZIP压缩减少网络传输时间
-
网络传输优化:
- 使用NIO零拷贝
- 分块传输
您可以根据具体的业务场景和数据量选择合适的优化方案。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播