feat add Excel工具类支持更灵活的自定义导出方式,以便用户分批处理导出数据

This commit is contained in:
秋辞未寒 2025-08-30 18:09:01 +08:00
parent 20516758ea
commit 7bb4838132
5 changed files with 258 additions and 0 deletions

View File

@ -27,6 +27,7 @@ import java.io.UnsupportedEncodingException;
import java.util.Collection; import java.util.Collection;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.function.Consumer;
/** /**
* Excel相关处理 * Excel相关处理
@ -203,6 +204,45 @@ public class ExcelUtil {
builder.doWrite(list); builder.doWrite(list);
} }
/**
* 导出excel
*
* @param headType 带Excel注解的类型
* @param os 输出流
* @param options Excel下拉可选项
* @param consumer 导出助手消费函数
*/
public static <T> void exportExcel(Class<T> headType, OutputStream os, List<DropDownOptions> options, Consumer<ExcelWriterHelper> consumer) {
try (ExcelWriter writer = FastExcel.write(os, headType)
.autoCloseStream(false)
// 自动适配
.registerWriteHandler(new LongestMatchColumnWidthStyleStrategy())
// 大数值自动转换 防止失真
.registerConverter(new ExcelBigNumberConvert())
// 批注必填项处理
.registerWriteHandler(new DataWriteHandler(headType))
// 添加下拉框操作
.registerWriteHandler(new ExcelDownHandler(options))
.build()) {
ExcelWriterHelper helper = ExcelWriterHelper.of(writer);
// 执行消费函数
consumer.accept(helper);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* 导出excel
*
* @param headType 带Excel注解的类型
* @param os 输出流
* @param consumer 导出助手消费函数
*/
public static <T> void exportExcel(Class<T> headType, OutputStream os, Consumer<ExcelWriterHelper> consumer) {
exportExcel(headType, os, null, consumer);
}
/** /**
* 单表多数据模板导出 模板格式为 {.属性} * 单表多数据模板导出 模板格式为 {.属性}
* *

View File

@ -0,0 +1,135 @@
package org.dromara.common.excel.utils;
import cn.idev.excel.ExcelWriter;
import cn.idev.excel.FastExcel;
import cn.idev.excel.context.WriteContext;
import cn.idev.excel.write.builder.ExcelWriterSheetBuilder;
import cn.idev.excel.write.builder.ExcelWriterTableBuilder;
import cn.idev.excel.write.metadata.WriteSheet;
import cn.idev.excel.write.metadata.WriteTable;
import cn.idev.excel.write.metadata.fill.FillConfig;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import java.util.Collection;
import java.util.function.Supplier;
/**
* ExcelWriterHelper Excel写出助手
* <br>
* 提供了一组与 ExcelWriter 一一对应的写出方法避免直接提供 ExcelWriter 而导致的一些不可控问题比如提前关闭了IO流等
*
*
* @see ExcelWriter
* @author 秋辞未寒
*/
@RequiredArgsConstructor
public class ExcelWriterHelper {
@Getter(AccessLevel.PRIVATE)
private final ExcelWriter excelWriter;
public void write(Collection<?> data, WriteSheet writeSheet) {
excelWriter.write(data, writeSheet);
}
public void write(Supplier<Collection<?>> supplier, WriteSheet writeSheet) {
excelWriter.write(supplier, writeSheet);
}
public void write(Collection<?> data, WriteSheet writeSheet, WriteTable writeTable) {
excelWriter.write(data, writeSheet, writeTable);
}
public void write(Supplier<Collection<?>> supplier, WriteSheet writeSheet, WriteTable writeTable) {
excelWriter.write(supplier.get(), writeSheet, writeTable);
}
public void fill(Object data, WriteSheet writeSheet) {
excelWriter.fill(data, writeSheet);
}
public void fill(Object data, FillConfig fillConfig, WriteSheet writeSheet) {
excelWriter.fill(data, fillConfig, writeSheet);
}
public void fill(Supplier<Object> supplier, WriteSheet writeSheet) {
excelWriter.fill(supplier, writeSheet);
}
public void fill(Supplier<Object> supplier, FillConfig fillConfig, WriteSheet writeSheet) {
excelWriter.fill(supplier, fillConfig, writeSheet);
}
public WriteContext writeContext() {
return excelWriter.writeContext();
}
/**
* 创建一个 ExcelWriterHelper
*
* @param excelWriter ExcelWriter
* @return ExcelWriterHelper
*/
public static ExcelWriterHelper of(ExcelWriter excelWriter) {
return new ExcelWriterHelper(excelWriter);
}
// -------------------------------- sheet start
public static WriteSheet buildSheet(Integer sheetNo, String sheetName) {
return sheetBuilder(sheetNo, sheetName).build();
}
public static WriteSheet buildSheet(Integer sheetNo) {
return sheetBuilder(sheetNo).build();
}
public static WriteSheet buildSheet(String sheetName) {
return sheetBuilder(sheetName).build();
}
public static WriteSheet buildSheet() {
return sheetBuilder().build();
}
public static ExcelWriterSheetBuilder sheetBuilder(Integer sheetNo, String sheetName) {
return FastExcel.writerSheet(sheetNo, sheetName);
}
public static ExcelWriterSheetBuilder sheetBuilder(Integer sheetNo) {
return FastExcel.writerSheet(sheetNo);
}
public static ExcelWriterSheetBuilder sheetBuilder(String sheetName) {
return FastExcel.writerSheet(sheetName);
}
public static ExcelWriterSheetBuilder sheetBuilder() {
return FastExcel.writerSheet();
}
// -------------------------------- sheet end
// -------------------------------- table start
public static WriteTable buildTable(Integer tableNo) {
return tableBuilder(tableNo).build();
}
public static WriteTable buildTable() {
return tableBuilder().build();
}
public static ExcelWriterTableBuilder tableBuilder(Integer tableNo) {
return FastExcel.writerTable(tableNo);
}
public static ExcelWriterTableBuilder tableBuilder() {
return FastExcel.writerTable();
}
// -------------------------------- table end
}

View File

@ -1,5 +1,6 @@
package org.dromara.demo.controller; package org.dromara.demo.controller;
import cn.dev33.satoken.annotation.SaIgnore;
import cn.hutool.core.collection.CollUtil; import cn.hutool.core.collection.CollUtil;
import jakarta.servlet.http.HttpServletResponse; import jakarta.servlet.http.HttpServletResponse;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
@ -14,6 +15,7 @@ import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
@ -94,6 +96,16 @@ public class TestExcelController {
exportExcelService.exportWithOptions(response); exportExcelService.exportWithOptions(response);
} }
/**
* 自定义导出
*
* @param response /
*/
@GetMapping("/customExport")
public void customExport(HttpServletResponse response) throws IOException {
exportExcelService.customExport(response);
}
/** /**
* 多个sheet导出 * 多个sheet导出
*/ */

View File

@ -2,6 +2,8 @@ package org.dromara.demo.service;
import jakarta.servlet.http.HttpServletResponse; import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
/** /**
* 导出下拉框Excel示例 * 导出下拉框Excel示例
* *
@ -15,4 +17,11 @@ public interface IExportExcelService {
* @param response / * @param response /
*/ */
void exportWithOptions(HttpServletResponse response); void exportWithOptions(HttpServletResponse response);
/**
* 自定义导出
*
* @param response /
*/
void customExport(HttpServletResponse response) throws IOException;
} }

View File

@ -2,17 +2,22 @@ package org.dromara.demo.service.impl;
import cn.hutool.core.util.RandomUtil; import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil; import cn.hutool.core.util.StrUtil;
import cn.idev.excel.write.metadata.WriteSheet;
import jakarta.servlet.http.HttpServletResponse; import jakarta.servlet.http.HttpServletResponse;
import lombok.Data; import lombok.Data;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import org.dromara.common.core.constant.SystemConstants; import org.dromara.common.core.constant.SystemConstants;
import org.dromara.common.core.utils.StreamUtils; import org.dromara.common.core.utils.StreamUtils;
import org.dromara.common.core.utils.file.FileUtils;
import org.dromara.common.excel.core.CellMergeStrategy;
import org.dromara.common.excel.core.DropDownOptions; import org.dromara.common.excel.core.DropDownOptions;
import org.dromara.common.excel.utils.ExcelUtil; import org.dromara.common.excel.utils.ExcelUtil;
import org.dromara.common.excel.utils.ExcelWriterHelper;
import org.dromara.demo.domain.vo.ExportDemoVo; import org.dromara.demo.domain.vo.ExportDemoVo;
import org.dromara.demo.service.IExportExcelService; import org.dromara.demo.service.IExportExcelService;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@ -233,4 +238,61 @@ public class ExportExcelServiceImpl implements IExportExcelService {
this.name = name; this.name = name;
} }
} }
@Override
public void customExport(HttpServletResponse response) throws IOException {
String filename = ExcelUtil.encodingFilename("自定义导出");
FileUtils.setAttachmentResponseHeader(response, filename);
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=UTF-8");
ExcelUtil.exportExcel(ExportDemoVo.class, response.getOutputStream(), helper -> {
// 创建表格数据业务中一般通过数据库查询
List<ExportDemoVo> excelDataList = new ArrayList<>();
for (int i = 0; i < 30; i++) {
// 模拟数据库中的一条数据
ExportDemoVo everyRowData = new ExportDemoVo();
everyRowData.setNickName("用户-" + i);
everyRowData.setUserStatus(SystemConstants.NORMAL);
everyRowData.setGender("1");
everyRowData.setPhoneNumber(String.format("175%08d", i));
everyRowData.setEmail(String.format("175%08d", i) + "@163.com");
everyRowData.setProvinceId(i);
everyRowData.setCityId(i);
everyRowData.setAreaId(i);
excelDataList.add(everyRowData);
}
// 创建表格
WriteSheet sheet = ExcelWriterHelper.sheetBuilder("自定义导出demo")
// 合并单元格
// .registerWriteHandler(new CellMergeStrategy(excelDataList, true))
.build();
helper.write(excelDataList, sheet);
List<ExportDemoVo> excelDataList2 = new ArrayList<>();
for (int i = 0; i < 20; i++) {
int index = 1000 + i;
// 模拟数据库中的一条数据
ExportDemoVo everyRowData = new ExportDemoVo();
everyRowData.setNickName("用户-" + index);
everyRowData.setUserStatus(SystemConstants.NORMAL);
everyRowData.setGender("1");
everyRowData.setPhoneNumber(String.format("175%08d", index));
everyRowData.setEmail(String.format("175%08d", index) + "@163.com");
everyRowData.setProvinceId(index);
everyRowData.setCityId(index);
everyRowData.setAreaId(index);
excelDataList2.add(everyRowData);
}
helper.write(excelDataList2, sheet);
// 或者在同一个excel中创建多个表格
// WriteSheet sheet2 = ExcelWriterHelper.sheetBuilder("自定义导出demo2").build();
// helper.write(excelDataList2, sheet2);
});
}
} }