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(";"," ");
}

最后,如果你想惹人生气,把你的分号换成希腊问号。