我使用open csv来读取只有2列的CSV,例如:
"valueA1","valueB of A1"
,"valueB of A1"
,"valueB of A1"
,"valueB of A1"
"valueA2","valueB of A2"
,"valueB of A2"
,"valueB of A2"
,"valueB of A2"
它一直在继续,到目前为止一切顺利。 当B列上的某些值带有一些字符时,我遇到了麻烦 例如:
"valueA1","va"lueB" of A1"
,"valueB of A1"
,"valueB of A1"
,"valueB of A1"
"valueA2","valueB of A2"
,"valueB of A2"
,"valueB of A2"
,"valueB of A2"
当我的专栏B有类似" 的内容,甚至在某些情况下:时,我的打开csv会丢失所有格式而不是说下一行包含2个值,它显示我疯狂的东西,如36,48,并且它因此丢失了大量内容。
如何指定这些值在列B中,并且不假设他需要创建新列?
我使用简单的构造函数
reader = new CSVReader(new FileReader(arquivo));
通过研究,我看到一些人说要使用不同的构造函数,我试图做
reader = new CSVReader(new FileReader(arquivo), ',','"');
但结果是一样的,因为构造函数只接受char我不能","
答案 0 :(得分:1)
首先,我仍然会明确设置分隔符和引号。你说你遇到了;
的问题。
CSVReader reader = new CSVReader(new FileReader(arquivo), ',', '\"');
然后出现数据错误:文本值va"lueB" of A1
例如Excel将自行转义为:va""lueB"" of A1
。我不知道CSVWriter会对双引号做什么。
侵入性最小的是在阅读时纠正数据:
CSVReader reader = new CSVReader(new RepairingReader(new FileReader(arquivo)),
',', '\"', '\\');
这里我还指定了分隔符和引号的转义字符。
CSVReader
使用BufferedReader
传递,或自行添加并调用readLine
。
public class RepairingReader extends BufferedReader {
public RepairingReader(Reader reader, int capacity) {
super(reader, capacity);
}
public RepairingReader(Reader reader) {
super(reader);
}
@Override
public String readLine() throws IOException {
String line = super.readLine();
if (line != null) {
line = line.replaceAll("([^,\\\\])\"([^,])", "$1\\\\\"$2");
}
return line;
}
}
这只会覆盖readLine
。它会重新声明前面有一个字符(不是反斜杠,不是逗号)和后面(不是逗号)的任何引号。替换应该是反斜杠后跟引号。
这不是一个完整的解析器,因为那时人们会自己实现一个CSV读取器。
顺便说一句:FileReader
没有选项可以设置用于将文件转换为Unicode字符串的编码。使用默认平台编码。因此代码不可移植,文件应该是本地编码。使用new InputStreamReader(new FileInputStream(file), encoding)
代替便携式软件。
答案 1 :(得分:0)
CSV没有官方标准,但有一个非官方标准,您展示的样本不符合它。应引用包含双引号字符的值,并且值中的双引号字符应加倍。
valueA1,"va""lueB"" of A1"
(在此示例中允许但不要求在“valueA1”周围加上双引号。)由于您自己创建了CSV文件,因此您应该从转换中修复问题。
如果您保存为“CSV(MS-DOS)(* .csv)”,则Excel 2007会正确执行此操作。我记得旧版本的Excel有一个您可能需要使用的CSV选项屏幕。