我正在尝试使用 HeaderColumnNameMappingStrategy 使用 opencsv 读取 csv 文件。 Opencsv 每次都会将我的 csv 第一列填充为 null。 这是我的代码:
实体类:
@Entity
@Table(name = "MyEntity")
public class MyEntity {
@CsvBindByName(column = "status", required = true)
@Column(name = "status", length = 5, nullable = false)
private String status;
@CsvBindByName(column = "type", required = true)
@Column(name = "type", length = 5, nullable = false)
private String type;
@CsvBindByName(column = "percentage", required = true)
@Column(name = "percentage", nullable = false)
private Integer percentage;
@Column(name = "date", nullable = false)
@CsvBindByName(column = "date", required = true)
@CsvDate(value = "yyyy-MM-dd")
private Date date;
}
阅读逻辑:
final HeaderColumnNameMappingStrategy<MyEntity> mpngInfo= new HeaderColumnNameMappingStrategy<>();
mappingInfo.setType(MyEntity.class);
final CsvToBean<MyEntity> csvToBean = new CsvToBean<>();
File file = new File(<path>);
CSVReader reader = new CSVReader(new FileReader(file),';');
final List<MyEntity> list = csvToBean.parse(mpngInfo, reader, true);
//here in list the first column is always populated as null.
我的 CSV :
类型;状态;百分比;日期 活跃;美元;25;2014-01-01 活跃;英镑;25;2014-01-01
注意:即使我将“类型”与“百分比”切换,它也会开始将百分比填充为空,因为“百分比”列成为第一列。
我找出了文件第一个字符的问题。 就我而言,它是“”类型;状态;百分比;日期
问题列在这里: 从文本文件中读取的第一个字符:
如何在 opencsv 中解决这个问题?有什么建议吗?
我遇到了同样的问题。
我再次通过utf-8无BOM保存了csv文件。
然后第一列设置为正确的值。
无需更改任何代码。
我使用名为 sakura 的文本编辑器。选择编码为 utf-8 后,启用了 BOM 复选框。取消选中它并保存 csv 文件。我认为其他编辑器具有相同的 BOM 选项。
BOM 编码的 UTF-8 字符串将从以下三个字节开始。 EFBB BF
添加到 csv 文件的三个字节可能会更改您的第一个列名称。
在 intellij 中,您只需单击文件,然后单击顶部菜单“文件”->“文件属性”->“删除 BOM”。这将为你带来魔力:)
这是从csv文件中删除BOM的解决方案。
String localFilePath = "some_path_inputfile";
String localFilePath_Out = "some_path_outputfile";
try (FileInputStream fis = new FileInputStream(new File(localFilePath));
InputStreamReader isr = new InputStreamReader(fis, "UTF-8");
BufferedReader reader = new BufferedReader(isr);
FileWriter writer = new FileWriter(localFilePath_Out)) {
// Read the file and skip the BOM characters
int firstChar = reader.read();
if (firstChar != 0xFEFF) {
// If the first character is not the BOM, write it to the output
writer.write(firstChar);
}
int nextChar;
while ((nextChar = reader.read()) != -1) {
// Write the remaining characters to the output
writer.write(nextChar);
}
} catch (IOException e) {
e.printStackTrace();
}
此后您可以使用输出文件,因为它没有 BOM。
如果你不想写入文件并在内存中交换,你也可以使用流,对我来说,我只是重新创建了没有 BOM 的流
public static ByteArrayOutputStream removeBOM(InputStream is) {
try {
ByteArrayOutputStream os = new ByteArrayOutputStream();
OutputStreamWriter writer = new OutputStreamWriter(os);
BufferedReader reader = new BufferedReader(new InputStreamReader(is, Charset.forName("UTF-8")));
int firstChar = reader.read();
if (firstChar != 0xFEFF) {
writer.write(firstChar);
}
int nextChar;
while ((nextChar = reader.read()) != -1) {
writer.write(nextChar);
}
writer.close();
return os;
} catch (Exception e) {
throw new BusinessException(ErrorBean.withError(Errors.FILE_TYPE, "Error parsing csv", ""));
}
}
并用作
ByteArrayOutputStream os = removeBOM(file.getInputStream());
Inputstream is = new ByteArrayInputStream(bytes);
我遇到了同样的问题。
对我来说最简单的解决方案是匹配所需的列名称(带或不带 BOM)。
@CsvBindByNames({@CsvBindByName(column = "Column name"), @CsvBindByName(column = "\uFEFFColumn name")})
private String name;