java csv 分号问题
java csv semi colon issue
我要修改一个程序。该程序在数据库中创建包含列的 csv 文件,如下所示:
csvBuilder.initCsvFile();
csvBuilder.createRow(headers.toArray(new String[headers.size()]));
while (resultSet.next()) {
String[] row = new String[resultSetColumnCount];
int columnIndex = 1;
while (columnIndex <= resultSetColumnCount) {
Object object = resultSet.getObject(columnIndex);
if (object == null) {
row[columnIndex - 1] = "";
} else {
row[columnIndex - 1] = object.toString();
}
columnIndex++;
}
csvBuilder.createRow(row);
}
initCsvFile 方法:
public void initCsvFile() {
try {
writer = new CSVWriter(new FileWriter(filePath), ';', CSVWriter.NO_QUOTE_CHARACTER);
} catch (IOException e) {
logger.error("CsvBuilder : error when creating {}", filePath, e);
throw new CsvException("Error when creating the file : " + filePath, e);
}
}
createRow 方法:
public void createRow(String[] row) {
writer.writeNext(row);
}
问题是,我有一些数据包含分隔符“;”如下图所示,
id col1 col2
1 US United;States
不幸的是,csv 文件将美国和各州分成两个 .如何在不修改所有程序的情况下检查 resultSet 的内容并转义分隔符以将 United;states 排成一行?
感谢您的帮助
在这些情况下,你需要一些引号字符,否则会产生歧义;在你的情况下,你指示它不要使用引号,因此,它无法处理这些情况。
尝试明确定义引号字符:
public void initCsvFile() {
try {
writer = new CSVWriter(new FileWriter(filePath), ';', '"');
} catch (IOException e) {
logger.error("CsvBuilder : error when creating {}", filePath, e);
throw new CsvException("Error when creating the file : " + filePath, e);
}
}
请记住,在这种情况下,任何可能导致歧义的数据都将包含在引号中:
1;US;"United;States"
这是有效的 CSV,大多数 CSV 解析器在读取时会自动去除引号。
你可以替换“;”在像这样创建 csv 行之前
while (resultSet.next()) {
String[] row = new String[resultSetColumnCount];
int columnIndex = 1;
while (columnIndex <= resultSetColumnCount) {
Object object = resultSet.getObject(columnIndex);
if (object == null) {
row[columnIndex - 1] = "";
} else {
// replace ";" by ""
row[columnIndex - 1] = object.toString().replace(";", "");
}
columnIndex++;
}
csvBuilder.createRow(row);
}
我刚遇到类似的问题。显然,字符串应该用双引号转义,以防止出现此类问题。所以我创建了一个 escapeCSVDatum()
函数:
private static String escapeCSVDatum(String s){
return "\""+s.replace("\"", "\"\"").replace("\n", " ")+"\"";
}
所以在你的情况下,它适用于这里
} else {
row[columnIndex - 1] = escapeCSVDatum(object.toString());
}
但是,正如Haroldo_OK所述,您使用CSVWriter.NO_QUOTE_CHARACTER
使得无法正确处理此类案件。具有此属性的数据中不可能有分号。
因此,您可能需要修改代码以用空格替换分号,例如
} else {
row[columnIndex - 1] = object.toString().replace(";"," ");
}
最后,如果你想惹人生气,把你的分号换成希腊问号。
我要修改一个程序。该程序在数据库中创建包含列的 csv 文件,如下所示:
csvBuilder.initCsvFile();
csvBuilder.createRow(headers.toArray(new String[headers.size()]));
while (resultSet.next()) {
String[] row = new String[resultSetColumnCount];
int columnIndex = 1;
while (columnIndex <= resultSetColumnCount) {
Object object = resultSet.getObject(columnIndex);
if (object == null) {
row[columnIndex - 1] = "";
} else {
row[columnIndex - 1] = object.toString();
}
columnIndex++;
}
csvBuilder.createRow(row);
}
initCsvFile 方法:
public void initCsvFile() {
try {
writer = new CSVWriter(new FileWriter(filePath), ';', CSVWriter.NO_QUOTE_CHARACTER);
} catch (IOException e) {
logger.error("CsvBuilder : error when creating {}", filePath, e);
throw new CsvException("Error when creating the file : " + filePath, e);
}
}
createRow 方法:
public void createRow(String[] row) {
writer.writeNext(row);
}
问题是,我有一些数据包含分隔符“;”如下图所示,
id col1 col2
1 US United;States
不幸的是,csv 文件将美国和各州分成两个 .如何在不修改所有程序的情况下检查 resultSet 的内容并转义分隔符以将 United;states 排成一行?
感谢您的帮助
在这些情况下,你需要一些引号字符,否则会产生歧义;在你的情况下,你指示它不要使用引号,因此,它无法处理这些情况。
尝试明确定义引号字符:
public void initCsvFile() {
try {
writer = new CSVWriter(new FileWriter(filePath), ';', '"');
} catch (IOException e) {
logger.error("CsvBuilder : error when creating {}", filePath, e);
throw new CsvException("Error when creating the file : " + filePath, e);
}
}
请记住,在这种情况下,任何可能导致歧义的数据都将包含在引号中:
1;US;"United;States"
这是有效的 CSV,大多数 CSV 解析器在读取时会自动去除引号。
你可以替换“;”在像这样创建 csv 行之前
while (resultSet.next()) {
String[] row = new String[resultSetColumnCount];
int columnIndex = 1;
while (columnIndex <= resultSetColumnCount) {
Object object = resultSet.getObject(columnIndex);
if (object == null) {
row[columnIndex - 1] = "";
} else {
// replace ";" by ""
row[columnIndex - 1] = object.toString().replace(";", "");
}
columnIndex++;
}
csvBuilder.createRow(row);
}
我刚遇到类似的问题。显然,字符串应该用双引号转义,以防止出现此类问题。所以我创建了一个 escapeCSVDatum()
函数:
private static String escapeCSVDatum(String s){
return "\""+s.replace("\"", "\"\"").replace("\n", " ")+"\"";
}
所以在你的情况下,它适用于这里
} else {
row[columnIndex - 1] = escapeCSVDatum(object.toString());
}
但是,正如Haroldo_OK所述,您使用CSVWriter.NO_QUOTE_CHARACTER
使得无法正确处理此类案件。具有此属性的数据中不可能有分号。
因此,您可能需要修改代码以用空格替换分号,例如
} else {
row[columnIndex - 1] = object.toString().replace(";"," ");
}
最后,如果你想惹人生气,把你的分号换成希腊问号。