目录
1:引入csv依赖
implementation 'com.opencsv:opencsv:5.7.1'
2:实体类
@ExcelProperty("xxxx")
@CsvBindByName(column = "xxxx")
private String capitalAccount;
@ExcelProperty("xxxx")
@CsvBindByName(column = "xxxx")
private String cashOutCapitalAccount;
@ExcelProperty("兑入资金账户")
@CsvBindByName(column = "xxxx")
private String cashInCapitalAccount;
@ExcelProperty("xxxx")
@CsvBindByName(column = "xxxx")
private String name;
@ExcelProperty("xxxx")
@CsvBindByName(column = "xxxx")
private String cashOutCurrencyType;
@ExcelProperty("xxxx")
@CsvBindByName(column = "xxxx")
private String cashOutAmount;
@ExcelProperty("xxxx")
@CsvBindByName(column = "xxxx")
private String referenceRate;
@ExcelProperty("xxxx")
@CsvBindByName(column = "xxxx")
private String cashOutRate;
@ExcelProperty("xxxx")
@CsvBindByName(column = "xxxx")
private String cashInCurrencyType;
@ExcelProperty("xxxx")
@CsvBindByName(column = "xxxx")
private String cashInAmount;
@ExcelProperty("xxxx")
@CsvBindByName(column = "xxxx")
private String remark;
@ExcelProperty(value = "xxxx")
@CsvBindByName(column = "xxxx")
private String approveStatus;
@ExcelProperty("xxxx")
@CsvBindByName(column = "xxxx")
private String approveInfo;
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = NORMAL_DATETIME)
@ExcelProperty(value = "申请时间", converter = LocalDateTimeStringConverter.class)
private LocalDateTime applicationTime;
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = NORMAL_DATETIME)
@ExcelProperty(value = "审批时间", converter = LocalDateTimeStringConverter.class)
private LocalDateTime transferDate;
@ExcelIgnore
@CsvBindByName(column = "xxxx")
private String createTime;
@ExcelIgnore
@CsvBindByName(column = "xxxx")
private String approveTime;
3:列顺序策略类
/**
* 列顺序策略类
*
* @param <T>
*/
public class OrderedColumnMappingStrategy<T> extends HeaderColumnNameMappingStrategy<T> {
//为了加快比较顺序,用Map
private final Map<String, Integer> columnOrderMap = new HashMap<>();
public OrderedColumnMappingStrategy(Class<T> clazz, String[] columnOrder) {
setType(clazz);
for (int i = 0; i < columnOrder.length; i++) {
columnOrderMap.put(columnOrder[i].toUpperCase(), i);
}
setColumnOrderOnWrite(Comparator.comparingInt(c -> columnOrderMap.getOrDefault(c.toUpperCase(), Integer.MAX_VALUE)));
}
@Override
public String[] generateHeader(T bean) throws CsvRequiredFieldEmptyException {
String[] defaultHeaders = super.generateHeader(bean);
List<String> sorted = Arrays.asList(defaultHeaders);
sorted.sort(Comparator.comparingInt(c -> columnOrderMap.getOrDefault(c.toUpperCase(), Integer.MAX_VALUE)));
return sorted.toArray(new String[0]);
}
}
4:导出工具类
public class CsvExportUtils {
/**
* 通用导出方法:支持列顺序 + UTF-8 BOM + 自定义列头
*
* @param outputStream 输出流(例如 response.getOutputStream())
* @param dataList 数据列表
* @param columnOrder 列顺序(要与实体类 @CsvBindByName 的 column 对应)
* @param clazz 实体类类型
*/
public static <T> void exportCsvOrdered(java.io.OutputStream outputStream, List<T> dataList, String[] columnOrder, Class<T> clazz) throws Exception {
// 写入 UTF-8 BOM,防止中文乱码
outputStream.write(0xEF);
outputStream.write(0xBB);
outputStream.write(0xBF);
try (Writer writer = new OutputStreamWriter(outputStream, StandardCharsets.UTF_8)) {
OrderedColumnMappingStrategy<T> strategy = new OrderedColumnMappingStrategy<>(clazz, columnOrder);
StatefulBeanToCsv<T> beanToCsv = new StatefulBeanToCsvBuilder<T>(writer)
.withMappingStrategy(strategy)
.withSeparator(CSVWriter.DEFAULT_SEPARATOR)
.withQuotechar(CSVWriter.NO_QUOTE_CHARACTER) // 防止加引号
.withApplyQuotesToAll(false)
.build();
beanToCsv.write(dataList);
writer.flush();
}
}
/**
* 获取实体类中所有字段的 @CsvBindByName(column = "") 值,按字段声明顺序排列
*/
public static String[] getCsvColumnOrder(Class<?> clazz) {
List<String> columnList = new CopyOnWriteArrayList<>();
for (Field field : clazz.getDeclaredFields()) {
CsvBindByName annotation = field.getAnnotation(CsvBindByName.class);
if (annotation != null) {
columnList.add(annotation.column());
}
}
return columnList.toArray(new String[0]);
}
}
5:使用方式
FileUtils.downloadFileCsvResponse(response, "货币兑换申请");
String[] columnOrder CsvExportUtils.getCsvColumnOrder(CurrencyExchangeExcelCsvDTO.class);
CsvExportUtils.exportCsvOrdered(response.getOutputStream(), csvList,columnOrder, CurrencyExchangeExcelCsvDTO.class);
// 调用方法
public static void downloadFileCsvResponse(HttpServletResponse response, String fileName) throws UnsupportedEncodingException {
String encodedFileName = URLEncoder.encode(fileName, StandardCharsets.UTF_8.toString());
response.setContentType("text/csv;charset=UTF-8");
response.setHeader("Content-Disposition", "attachment; filename*=UTF-8''" + encodedFileName);
}

4077

被折叠的 条评论
为什么被折叠?



