使用@CsvBindByName时如何处理CSV表头的前后空格?
解决OpenCSV 4.6处理带前后空格表头的问题
针对用户上传CSV表头带前后空格导致的CsvRequiredFieldEmptyException,可以通过以下两种方式解决:
方法一:修剪读取到的表头空格
自定义HeaderColumnNameMappingStrategy,重写createHeader方法,对读取到的每个表头进行前后空格修剪:
// 初始化映射策略 HeaderColumnNameMappingStrategy<LineDto> strategy = new HeaderColumnNameMappingStrategy<LineDto>() { @Override public String[] createHeader(CsvReader reader) throws IOException { // 获取原始表头 String[] originalHeaders = super.createHeader(reader); // 遍历修剪每个表头的前后空格 for (int i = 0; i < originalHeaders.length; i++) { if (originalHeaders[i] != null) { originalHeaders[i] = originalHeaders[i].trim(); } } return originalHeaders; } }; strategy.setType(LineDto.class); // 使用该策略构建CsvToBean并解析CSV try (CsvReader reader = new CsvReader(new FileReader("your-file.csv"))) { CsvToBean<LineDto> csvToBean = new CsvToBeanBuilder<LineDto>(reader) .withMappingStrategy(strategy) .build(); List<LineDto> dataList = csvToBean.parse(); }
方法二:自定义表头与列名的比较逻辑
通过设置HeaderColumnNameMappingStrategy的列名比较器,让OpenCSV在匹配表头和@CsvBindByName的column值时自动忽略前后空格:
HeaderColumnNameMappingStrategy<LineDto> strategy = new HeaderColumnNameMappingStrategy<>(); strategy.setType(LineDto.class); // 设置自定义比较器,trim后忽略大小写匹配(可按需调整为严格相等) strategy.setColumnNameComparator((colNameFromDto, headerFromCsv) -> { if (colNameFromDto == null && headerFromCsv == null) return 0; if (colNameFromDto == null) return -1; if (headerFromCsv == null) return 1; return colNameFromDto.trim().equalsIgnoreCase(headerFromCsv.trim()); }); // 后续解析代码同方法一 try (CsvReader reader = new CsvReader(new FileReader("your-file.csv"))) { CsvToBean<LineDto> csvToBean = new CsvToBeanBuilder<LineDto>(reader) .withMappingStrategy(strategy) .build(); List<LineDto> dataList = csvToBean.parse(); }
两种方法的区别:
- 方法一直接修改读取到的表头数据,后续所有基于表头的操作都会使用修剪后的值;
- 方法二仅在匹配列名和表头时忽略空格,原始表头数据不会被修改,更适合需要保留原始表头信息的场景。
内容的提问来源于stack exchange,提问作者Pavel Petrashov
相关产品推荐
相关产品推荐

