java如何设置scv列名_java - OpenCSV:如何使用自定义列标题和自定义列位置从POJO创建CSV文件? - 堆栈内存溢出...

本文介绍了如何使用Java的OpenCSV库,通过HeaderColumnNameMappingStrategy和自定义比较器OrderedComparatorIgnoringCase来控制CSV文件在导出时的列顺序,以及如何保证导入的CSV能正确映射到POJO的属性。示例代码展示了如何实现这个功能。
摘要由CSDN通过智能技术生成

我想实现双向导入/导出-能够将生成的CSV导入回POJO,反之亦然。

我无法为此使用@CsvBindByPosition,因为在这种情况下-ColumnPositionMappingStrategy是自动选择的。

我用来实现目标的方法是:

HeaderColumnNameMappingStrategy

mappingStrategy.setColumnOrderOnWrite(Comparator writeOrder)

csvUtils读取/写入csv

import com.opencsv.CSVWriter;

import com.opencsv.bean.*;

import org.springframework.web.multipart.MultipartFile;

import java.io.*;

import java.util.List;

public class CsvUtils {

private CsvUtils() {

}

public static String convertToCsv(List entitiesList, MappingStrategy mappingStrategy) throws Exception {

try (Writer writer = new StringWriter()) {

StatefulBeanToCsv beanToCsv = new StatefulBeanToCsvBuilder(writer)

.withMappingStrategy(mappingStrategy)

.withQuotechar(CSVWriter.NO_QUOTE_CHARACTER)

.build();

beanToCsv.write(entitiesList);

return writer.toString();

}

}

@SuppressWarnings("unchecked")

public static List convertFromCsv(MultipartFile file, Class clazz) throws IOException {

try (Reader reader = new BufferedReader(new InputStreamReader(file.getInputStream()))) {

CsvToBean csvToBean = new CsvToBeanBuilder(reader).withType(clazz).build();

return csvToBean.parse();

}

}

}

POJO导入/导出

public class LocalBusinessTrainingPairDTO {

//this is used for CSV columns ordering on exporting LocalBusinessTrainingPairs

public static final String[] FIELDS_ORDER = {"leftId", "leftName", "rightId", "rightName"};

@CsvBindByName(column = "leftId")

private int leftId;

@CsvBindByName(column = "leftName")

private String leftName;

@CsvBindByName(column = "rightId")

private int rightId;

@CsvBindByName(column = "rightName")

private String rightName;

// getters/setters omitted, do not forget to add them

}

用于预定义字符串排序的自定义比较器:

public class OrderedComparatorIgnoringCase implements Comparator {

private List predefinedOrder;

public OrderedComparatorIgnoringCase(String[] predefinedOrder) {

this.predefinedOrder = new ArrayList<>();

for (String item : predefinedOrder) {

this.predefinedOrder.add(item.toLowerCase());

}

}

@Override

public int compare(String o1, String o2) {

return predefinedOrder.indexOf(o1.toLowerCase()) - predefinedOrder.indexOf(o2.toLowerCase());

}

}

POJO的有序写作(最初问题的答案)

public static void main(String[] args) throws Exception {

List localBusinessTrainingPairsDTO = new ArrayList<>();

LocalBusinessTrainingPairDTO localBusinessTrainingPairDTO = new LocalBusinessTrainingPairDTO();

localBusinessTrainingPairDTO.setLeftId(1);

localBusinessTrainingPairDTO.setLeftName("leftName");

localBusinessTrainingPairDTO.setRightId(2);

localBusinessTrainingPairDTO.setRightName("rightName");

localBusinessTrainingPairsDTO.add(localBusinessTrainingPairDTO);

//Creating HeaderColumnNameMappingStrategy

HeaderColumnNameMappingStrategy mappingStrategy = new HeaderColumnNameMappingStrategy<>();

mappingStrategy.setType(LocalBusinessTrainingPairDTO.class);

//Setting predefined order using String comparator

mappingStrategy.setColumnOrderOnWrite(new OrderedComparatorIgnoringCase(LocalBusinessTrainingPairDTO.FIELDS_ORDER));

String csv = convertToCsv(localBusinessTrainingPairsDTO, mappingStrategy);

System.out.println(csv);

}

将导出的CSV读回POJO(原始答案的补充)

重要提示:CSV可以是无序的,因为我们仍在使用按名称绑定:

public static void main(String[] args) throws Exception {

//omitted code from writing

String csv = convertToCsv(localBusinessTrainingPairsDTO, mappingStrategy);

//Exported CSV should be compatible for further import

File temp = File.createTempFile("tempTrainingPairs", ".csv");

temp.deleteOnExit();

BufferedWriter bw = new BufferedWriter(new FileWriter(temp));

bw.write(csv);

bw.close();

MultipartFile multipartFile = new MockMultipartFile("tempTrainingPairs.csv", new FileInputStream(temp));

List localBusinessTrainingPairDTOList = convertFromCsv(multipartFile, LocalBusinessTrainingPairDTO.class);

}

结论:

无论列顺序如何,我们都可以将CSV读取为POJO-因为我们正在使用@CsvBindByName

我们可以使用自定义比较器在写入时控制列顺序

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值