74

我正在编写一个 Java 应用程序来将数据从 Oracle 导出到 csv 文件

不幸的是,数据的内容可能相当棘手。逗号仍然是分隔符,但一行中的一些数据可能是这样的:

| ID    |   FN    |   LN   |  AGE   |  COMMENT                   |
|----------------------------------------------------------------|
| 123   |  John   |  Smith |   39   | I said "Hey, I am 5'10"."  |
|----------------------------------------------------------------|

所以这是comment列上的字符串之一:

我说“嘿,我是 5'10”。

不开玩笑,我需要在 Excel 中显示上述评论,或者从 Java 生成的 CSV 文件中打开办公室,当然不能弄乱其他常规转义情况(即常规双引号和元组中的常规逗号)。我知道正则表达式很强大,但是我们如何在如此复杂的情况下实现目标呢?

4

7 回答 7

119

有几个图书馆。这里有两个例子:


❐ Apache Commons Lang

Apache Commons Lang包含一个特殊的类来转义或取消转义字符串(CSV、EcmaScript、HTML、Java、Json、XML)org.apache.commons.lang3.StringEscapeUtils:.

  • 转至CSV

    String escaped = StringEscapeUtils
        .escapeCsv("I said \"Hey, I am 5'10\".\""); // I said "Hey, I am 5'10"."
    
    System.out.println(escaped); // "I said ""Hey, I am 5'10""."""
    
  • 从 CSV 中转义

    String unescaped = StringEscapeUtils
        .unescapeCsv("\"I said \"\"Hey, I am 5'10\"\".\"\"\""); // "I said ""Hey, I am 5'10""."""
    
    System.out.println(unescaped); // I said "Hey, I am 5'10"."
    

*你可以从 这里下载。


❐ OpenCSV

如果您使用OpenCSV,则无需担心转义或取消转义,仅用于写入或读取内容。

  • 写入文件:

    FileOutputStream fos = new FileOutputStream("awesomefile.csv"); 
    OutputStreamWriter osw = new OutputStreamWriter(fos, "UTF-8");
    CSVWriter writer = new CSVWriter(osw);
    ...
    String[] row = {
        "123", 
        "John", 
        "Smith", 
        "39", 
        "I said \"Hey, I am 5'10\".\""
    };
    writer.writeNext(row);
    ...
    writer.close();
    osw.close();
    os.close();
    
  • 读取文件:

    FileInputStream fis = new FileInputStream("awesomefile.csv"); 
    InputStreamReader isr = new InputStreamReader(fis, "UTF-8");
    CSVReader reader = new CSVReader(isr);
    
    for (String[] row; (row = reader.readNext()) != null;) {
        System.out.println(Arrays.toString(row));
    }
    
    reader.close();
    isr.close();
    fis.close();
    

*你可以从 这里下载。

于 2012-05-04T16:13:14.530 回答
35

Excel 必须能够处理完全相同的情况。

将这些东西放入 Excel,将它们保存为 CSV,然后使用文本编辑器检查文件。然后你就会知道 Excel 适用于这些情况的规则。

使 Java 产生相同的输出。

顺便说一下,Excel 使用的格式已发布...

****编辑 1:**** 这是 Excel 所做的
****编辑 2:**** 请注意,fputcsv如果您使用 " 作为附件,php 的功能与 excel 完全相同。

rdeslonde@mydomain.com
Richard
"This is what I think"

变成这样:

Email,Fname,Quoted  
rdeslonde@mydomain.com,Richard,"""This is what I think"""
于 2012-05-04T15:34:31.783 回答
15

感谢 Tony 和 Paul 的快速反馈,这非常有帮助。我实际上通过 POJO 找到了解决方案。这里是:

if (cell_value.indexOf("\"") != -1 || cell_value.indexOf(",") != -1) {
    cell_value = cell_value.replaceAll("\"", "\"\"");
    row.append("\"");
    row.append(cell_value);
    row.append("\"");
} else {
    row.append(cell_value);
}

简而言之,如果单元格内部的字符串中有逗号或双引号等特殊字符,则首先"\""通过添加额外的双引号(如"\"\"")来转义双引号(),然后将整个内容放入双引号中(如"\""+theWholeThing+"\""

于 2012-05-07T13:40:25.253 回答
4

如果您使用的是 CSVWriter。检查您是否没有该选项

.withQuotechar(CSVWriter.NO_QUOTE_CHARACTER)

当我删除它时,逗号按预期显示,而不是将其视为新列

于 2019-09-20T16:21:50.283 回答
3

您还可以查看Python 如何编写与 Excel 兼容的csv文件。

我相信 Excel 的默认设置是为文字引号字符加倍 - 也就是说,文字引号"写为"".

于 2012-05-07T13:47:30.777 回答
2
"cell one","cell "" two","cell "" ,three"

将此保存到 csv 文件并查看结果,因此使用双引号将其自身转义

重要的提示

"cell one","cell "" two", "cell "" ,three"

会给你一个不同的结果,因为逗号后面有一个空格,这将被视为“

于 2016-01-06T11:24:05.520 回答
-1
String stringWithQuates = "\""+ "your,comma,separated,string" + "\"";

这将在 CSV 文件中保留逗号

于 2017-08-03T05:41:51.993 回答