【问题标题】:Write CSV with text in quotes, but numerical values without quotes [duplicate]用引号中的文本编写CSV,但不带引号的数值[重复]
【发布时间】:2014-08-14 09:01:51
【问题描述】:

使用 OpenCSV,我正在尝试编写一个 CSV 文件,其中

  • 文本值用" 引号括起来。
  • 数值用引号括起来(因为它们应该被最终读取 CSV 文件的程序视为数字,而不是字符串)。

所需输出示例:

读取 CSV 文件的程序所需的格式:

"Header 1","Header 2","Header 3"
123.4,234.6,999.8
456456.32,1222.4,2222.2

尝试的解决方案:

到目前为止我最好的尝试是:

CSVWriter csvWriter = new CSVWriter(new FileWriter(csvFile),',','\0');

其中引号字符设置为'\0',即空字符(并且分隔符像往常一样保留为,)。

这不会在任何值周围加上引号。为了弥补文本值周围缺少" 引号,我“手动”在每个文本值前添加并附加一个乱七八糟的引号"\""(这很容易管理,因为我的标题实际上只是唯一具有文本)。

    for (int i=0;i<headers.length;++i) {
        headers[i] = "\"" + headers[i] + "\"";
    }

实际输出:

我真的认为这会成功,但输出看起来像这样:

""Header 1"",""Header 2"",""Header 3""
123.4,234.6,999.8
456456.32,1222.4,2222.2

文本值用双引号括起来""!

  • 为什么?
  • 我该如何解决这个问题?

【问题讨论】:

  • 我不太明白你的意思。 CSV 规范指出,包含分隔符的数据可能要么 将该分隔符转义 引用该数据。不需要引用可能包含引号的所有数据。由于这不是 CSV 规范的一部分,OpenCSV 无法处理它。您正在寻找更类似于 JSON 数组的东西。
  • @BoristheSpider 当您说“规范”时,您指的是RFC 4180 吗?如果是这样,请记住 OpenCSV 网站 makes no reference to that RFC。因此,尽管我认为您的 cmets 可能是合理的,但我会谨慎地宣传大多数实现都遵循单一规范的想法。
  • @Duncan,是的 - 我是。我只是假设 OpenCSV 紧随其后。是的,我知道会发生什么when you assume
  • @Duncan:是的,现在只是标题。你之前的评论也是正确的。
  • @Jean-FrançoisCorbett 好地方(在副本上):-)

标签: java csv export-to-csv opencsv


【解决方案1】:

您可以将转义字符指定为'\0',这将阻止 OpenCSV 转义您现有的引号:

CSVWriter csvWriter = new CSVWriter(new OutputStreamWriter(System.out),
        ',', '\0', '\0');
csvWriter.writeNext(new String[] { "\"Header 1\"", "\"Header 2\"",
        "\"Header 3\"" });
csvWriter.writeNext(new String[] { "123.4", "234.6", "999.8" });
csvWriter.close();

输出:

"标题 1","标题 2","标题 3" 123.4,234.6,999.8

当然,您正在迅速达到 OpenCSV 对您无能为力的阶段。如果您处理所有转义和所有引用,那么 OpenCSV 只是用逗号连接字符串数组。

放弃该库并自己编写少量代码可能是明智的 - 这将避免未来的维护者感到困惑,他们认为“嗯,这是我们在这里生成的非常奇怪的 CSV 数据! em>”。

【讨论】:

    【解决方案2】:

    AFAIK CSV 规范 (https://www.rfc-editor.org/rfc/rfc4180) 声明值中的双引号通过将它们加倍来进行转义,因此我假设如果您自己提供双引号,它们会被转义并且 仅当值包含分隔符时 OpenCSV 将其括在双引号中。

    示例(分隔符是逗号):

    Input           CSV
    --------------------------------
    test text    -> test
    test, text   -> "test, text"     (double quotes because of the delimiter in the input)
    "test text"  -> ""test text""    (double quotes are escaped)
    "test, text" -> """test, text""" (double quotes because of delimiter, as well as escaped quotes)
    

    【讨论】:

    • 在我的问题中,我特意指定了所需的输出格式,因为这是我保证链中的下一个程序能够读取的唯一格式。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-06-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-08
    • 2022-10-24
    • 2015-01-05
    相关资源
    最近更新 更多