Java11下使用OpenCSV仅写入指定Bean属性到CSV文件的实现方法
解决方案
核心思路
不需要为每个导出场景单独定义DTO,通过OpenCSV提供的动态字段映射策略,按需指定当前场景要导出的属性列表即可实现,全程复用同一个MyEntry类。
实现步骤
步骤1:给实体类加OpenCSV注解(可选但推荐)
给MyEntry的每个属性加@CsvBindByName注解,确保OpenCSV可以正确匹配属性:
public class MyEntry { @CsvBindByName private String propOne; @CsvBindByName private Long propTwo; @CsvBindByName private int propThree; @CsvBindByName private String propFour; // 其他属性同理加注解,原有getter、setter保持不变 }
步骤2:按场景定义要导出的字段列表
不同场景只需要定义对应的字段数组即可,不需要新建类:
- 导出propFour到propTen的场景:
String[] exportFields = {"propFour", "propFive", "propSix", "propSeven", "propEight", "propNine", "propTen"}; - 导出全部字段的场景:
String[] allFields = {"propOne", "propTwo", "propThree", "propFour", ..., "propFifteen"};
如果需要自定义显示表头,同步定义表头数组即可:String[] headers = {"属性四", "属性五", ..., "属性十"};
步骤3:动态构造映射策略并写入CSV
核心是用ColumnPositionMappingStrategy绑定当前场景的字段列表,再通过StatefulBeanToCsv写入:
import com.opencsv.CSVWriter; import com.opencsv.bean.ColumnPositionMappingStrategy; import com.opencsv.bean.StatefulBeanToCsv; import com.opencsv.bean.StatefulBeanToCsvBuilder; import java.io.FileWriter; import java.io.Writer; import java.util.List; public class CsvExporter { public <T> void exportCsv(List<T> dataList, Class<T> clazz, String[] exportFields, String[] headers, String filePath) throws Exception { // 初始化字段映射策略 ColumnPositionMappingStrategy<T> strategy = new ColumnPositionMappingStrategy<>(); strategy.setType(clazz); strategy.setColumnMapping(exportFields); try (Writer writer = new FileWriter(filePath)) { StatefulBeanToCsv<T> beanToCsv = new StatefulBeanToCsvBuilder<T>(writer) .withMappingStrategy(strategy) .withSeparator(CSVWriter.DEFAULT_SEPARATOR) .withHeader(headers) // 不需要自定义表头可以去掉这行,默认用字段名当表头 .withApplyQuotesToAll(false) .build(); beanToCsv.write(dataList); } } }
步骤4:不同场景调用示例
// 场景1:导出propFour到propTen List<MyEntry> data = getMyEntryData(); String[] fields = {"propFour", "propFive", "propSix", "propSeven", "propEight", "propNine", "propTen"}; String[] headers = {"属性4", "属性5", "属性6", "属性7", "属性8", "属性9", "属性10"}; new CsvExporter().exportCsv(data, MyEntry.class, fields, headers, "场景1导出.csv"); // 场景2:导出全部字段 String[] allFields = {"propOne", "propTwo", "propThree", "propFour", "propFive", ..., "propFifteen"}; String[] allHeaders = {"属性1", "属性2", "属性3", ..., "属性15"}; new CsvExporter().exportCsv(data, MyEntry.class, allFields, allHeaders, "全字段导出.csv");
注意事项
- 字段名必须和
MyEntry类的属性名完全一致,保证符合JavaBean命名规范,getter/setter方法正常生成,否则OpenCSV无法识别对应属性。 - 如果有特殊类型转换需求(如日期格式化、数字格式自定义),可通过
withConverter方法为指定字段配置自定义转换器,无需修改实体类。
内容的提问来源于stack exchange,提问作者miroana
相关产品推荐
相关产品推荐

