【问题标题】:Unwanted double quotes in generated csv file生成的 csv 文件中不需要的双引号
【发布时间】:2012-12-07 19:13:23
【问题描述】:

我使用下面的 Java 代码创建了一个 CSV 文件:

String csv = rs.getString("UPLOAD_FOLDER_PATH")+".csv";
CSVWriter writer = new CSVWriter(new FileWriter(csv));
String [] filevalues = new String[filevaluesarray.size()];

filevalues=filevaluesarray.toArray(filevalues);

writer.writeNext(filevalues);

writer.close();

我正在获取 CSV 文件,但文件内容包含不需要的双引号。

例如。 "ABC","123","KDNJ"

我不知道这些双引号是从哪里添加的。

【问题讨论】:

  • 您知道 CSV 通常具有文本识别字符(在您的情况下为双引号)。这可能是CSVWriter 的默认值,您可以更改它。
  • 是什么导致了问题?生成的 CSV 文件应该可以被任何带有这些的软件正确打开。

标签: java csv file-io opencsv supercsv


【解决方案1】:

这对我有用

CSVWriter writer = 
    new CSVWriter(new FileWriter(csv), ',', CSVWriter.NO_QUOTE_CHARACTER);

CSVWriter javadoc

【讨论】:

  • 仅供参考,此构造函数已被弃用,@giainel 的答案似乎有效。
  • v5.2 CSVWriter 构造函数中的只接受两种格式。 1- 新 CSVWriter(新 FileWriter(filePath))。 2- new CSVWriter(new FileWriter(filePath), CSVWriter.DEFAULT_SEPARATOR, CSVWriter.NO_QUOTE_CHARACTER, CSVWriter.DEFAULT_ESCAPE_CHARACTER, CSVWriter.DEFAULT_LINE_END)
【解决方案2】:

您可能应该澄清“不需要的”引号是什么意思。

  1. 我不希望它引用所有内容,只引用包含 嵌入的逗号、引号和换行符(引用所有内容是不必要的,并且 使我的文件更大),或

  2. 我不希望引用任何内容,并且我了解如果我的 CSV 包含嵌入的逗号、引号和换行符,它将无效

如果它是第一个选项,那么 opencsv 不支持这个 - 它要么引用所有内容,要么什么都不引用。如果您想要一个仅在必要时引用的开源 CSV 库,请查看 Super CSV(如果需要,也可以使用 quote everything too)。

如果是第二个选项,那么请选择 Sheldon 的答案,但请注意,如果您的 CSV 包含嵌入的逗号、引号和换行符,它将是无效的。

例如,如果我正在阅读您的 CSV 文件,我怎么知道以下内容实际上只是包含 2 个字段的单个记录?

P Sherman, 42 Wallaby Way,
Sydney, AUSTRALIA

而如果引用正确,那将是显而易见的,即

P Sherman, "42 Wallaby Way,
Sydney, AUSTRALIA"

仅供参考,以下是与 RFC4180(CSV 的 MIME 类型定义)的引用相关的规则。

5 每个字段可以用双引号括起来,也可以不用双引号括起来(但是 某些程序(例如 Microsoft Excel)不使用双引号 完全)。如果字段没有用双引号括起来,那么 双引号可能不会出现在字段内。例如:

   "aaa","bbb","ccc" CRLF
   zzz,yyy,xxx

6 包含换行符 (CRLF)、双引号和逗号的字段 应该用双引号括起来。例如:

   "aaa","b CRLF
   bb","ccc" CRLF
   zzz,yyy,xxx

7 如果使用双引号将字段括起来,则使用双引号 出现在字段内必须通过在它前面加上 另一个双引号。例如:

   "aaa","b""bb","ccc"

【讨论】:

  • +1 表示 SuperCSV 链接。我试图完全按照您在回答中的场景#1 中描述的方式进行操作。 SuperCSV 完美地做到了这一点。我已经确认它可以处理我最常见的问题字符(阅读和写作):逗号、单引号/撇号、双引号。谢谢推荐!
  • 自去年以来的报价就不是这样了。现在在 CSVWriter.writeNext(String[] nextLine, boolean applyQuotesToAll) 中有一个选项,其中 applyQuotesToAll 是“如果要引用所有值,则为 True。False 仅将引号应用于包含分隔符、转义符、引号或换行符的值。” (javadoc)。项目在不断发展,但我不会对 SuperCSV 这么说。
【解决方案3】:

如果您不希望生成的 CSV 文件的值中包含引号,则必须以这种方式创建 CSVWriter 对象:

CSVWriter writer = new CSVWriter(new FileWriter(filePath),
    CSVWriter.DEFAULT_SEPARATOR,
    CSVWriter.NO_QUOTE_CHARACTER,
    CSVWriter.DEFAULT_ESCAPE_CHARACTER,
    CSVWriter.RFC4180_LINE_END);

密钥是CSVWriter.NO_QUOTE_CHARACTER。您可以自定义其他构造函数参数的值。

【讨论】:

  • 最佳答案,因为没有恼人的弃用警告;
【解决方案4】:

private void writeFile(String fileAbsolutePath , ListcsvLines) 抛出 IOException{

    final char csvDelimeter = ',';
    CSVWriter csvWriter = new CSVWriter(new FileWriter(new File(fileAbsolutePath)),csvDelimeter,CSVWriter
                                                                                               .NO_QUOTE_CHARACTER);
    CSVParser parser = new CSVParser();

    for(String csvLine  : csvLines){
        String[] csvVals = parser.parseLine(csvLine);
        csvWriter.writeNext(csvVals);
    }
    csvWriter.flush();
}

调用:writeFile(fileAbsolutePath,csvLinesList);

Shamis 回答的工作示例,对我来说效果很好。

【讨论】:

    【解决方案5】:

    我在打开 csv 时也面临同样的问题,为了解决我使用转义字符的问题。

    例如:

    CSVReader csvReader = new CSVReader(new FileReader(fileName), seprator,escaped_character);
    

    在这里打开的csv默认使用双引号作为转义字符(据我所知)

    在我的例子中,我使用分隔符作为管道符号 (|)

    A2|G A A|Thilina|9022V|1|2|3|4|"Rubasingha"|'Abc|MATARA"|'No'|2012|1668.88

    在这里 "Rubasingha" 打开和关闭双引号,在 'No' 也打开和关闭单引号。这两个在默认打开的 csv 中完美运行

    但是当我们使用 'Abc - 只打开单引号 - 这也可以正常工作

    但是 MATARA""MATARA - 在这里我们有一个双引号 - 在我的情况下,这会在使用 open csv 读取 CSV 时产生错误

    为了解决这个问题,我参考了这个页面 (http://cs.swan.ac.uk/~csbob/teaching/java/JavaDemoNetbeans/opencsv-2.3/doc/)

    有些构造函数可以提供您自己的分隔符和引号字符。假设您使用制表符作为分隔符,您可以执行以下操作:

    CSVReader reader = new CSVReader(new FileReader("yourfile.csv"), '\t');
    

    如果你单引用你的转义字符而不是双引号,你可以使用三个 arg 构造函数:

    CSVReader reader = new CSVReader(new FileReader("yourfile.csv"), '\t', '\'');
    

    如果您知道内容直到文件后面才开始,您也可以跳过文件的前几行。因此,例如,您可以通过以下方式跳过前两行:

    CSVReader reader = new CSVReader(new FileReader("yourfile.csv"), '\t', '\'', 2);
    

    所以我将默认转义字符更改为 (^) 符号,而不使用双引号作为转义字符。

    CSVReader csvReader = new CSVReader(new FileReader(fileName), '|','^');
    

    这是我解决问题的方法。谢谢

    【讨论】:

      【解决方案6】:

      我遇到的情况是,我的 .csv 文件中显示的数据两边各有三个引号。这是由于我的数据在 excel 中有引号。第二个我创建了一个 .csv 文件,我会打开以查看更多所需的报价。在网上大量搜索后,我找到了一些代码并进行了如下调整以适合我: -

       Public Sub OutputQuotedCSV()
       Const QSTR As String = ""
       Dim myRecord As Range
       Dim myField As Range
       Dim nFileNum As Long
       Dim sOut As String
      
         nFileNum = FreeFile
         Open "TheNameOfYourFile.txt" For Output As #nFileNum
         For Each myRecord In Range("A1:A" & _
                Range("A" & Rows.Count).End(xlUp).Row)
            With myRecord
               For Each myField In Range(.Cells(1), _
                   Cells(.Row, 256).End(xlToLeft))
                 'I didn't want my Header Row touched but wanted it added into the csv file
                 'There's probably an easier way but this worked perfectly for me
                  If myField.Text = "HEADER 1" Then 
                              sOut = sOut & QSTR & _
                              Replace(myField.Text, QSTR, QSTR & QSTR) & "  "
                          ElseIf myField.Text = "HEADER 2" Then
                              sOut = sOut & QSTR & _
                              Replace(myField.Text, QSTR, QSTR & QSTR) & "  "
                          ElseIf myField.Text = "HEADER 3" Then
                              sOut = sOut & QSTR & _
                              Replace(myField.Text, QSTR, QSTR & QSTR) & "  "
                          ElseIf myField.Text = "HEADER 4" Then
                              sOut = sOut & QSTR & _
                              Replace(myField.Text, QSTR, QSTR & QSTR) & "  "
                          ElseIf myField.Text = "HEADER 5" Then
                              sOut = sOut & QSTR & _
                              Replace(myField.Text, QSTR, QSTR & QSTR) & "  "
                          ElseIf myField.Text = "HEADER 6" Then
                              sOut = sOut & QSTR & _
                              Replace(myField.Text, QSTR, QSTR & QSTR) & "  "
                          Else
                     'I didn't want my first column to start with "," so I added the code below
                              If myField.Cells.Column = 1 Then
                                  sOut = sOut & QSTR & _
                                  Replace(myField.Text, QSTR, QSTR & QSTR) & QSTR
                              Else
                                  sOut = sOut & "," & QSTR & _
                                  Replace(myField.Text, QSTR, QSTR & QSTR) & QSTR
                              End If
                          End If
                  Next myField
                  Print #nFileNum, Mid(sOut, 1)
                  sOut = Empty
              End With
          Next myRecord
          Close #nFileNum
      End Sub
      

      此代码将去掉多余的引号,并在数据的开头和结尾留下单引号。我希望这对某人有所帮助,如果我在格式上做错了什么或没有正确显示数据,请原谅我。我只是想帮助别人。请记住,这根本不是我的代码。我刚刚让它为我工作,我怀疑其他人正试图获得我在这里取得的成就。 原始代码可以在这里找到http://www.mcgimpsey.com/excel/textfiles.html#csvwithquotes

      【讨论】:

      • 虽然此代码在某些情况下可能会有所帮助,但它不是对 OP 问题的回答。 OP 询问双引号为什么以及如何进入他的 CSV 文件。您没有回答这个问题,发布了可以删除它们的代码。
      【解决方案7】:

      我遇到了同样的问题,但在实施开放 csv 库 5.3 版的解决方案后仍然发现了一些问题。

      它将我需要转换为包含默认转义字符的 csv 文件的数据。因此,为了正确完成实施,我需要抑制转义字符。因此,如果您在 Libre office 或 Microsoft excel 中打开文件时由于出现转义字符而仍然遇到问题,请使用此解决方案:

      new CSVWriter(new FileWriter(path),
                  CSVWriter.DEFAULT_SEPARATOR,
                  CSVWriter.NO_QUOTE_CHARACTER,
                  CSVWriter.NO_ESCAPE_CHARACTER,
                  CSVWriter.DEFAULT_LINE_END    
              );
      

      【讨论】:

        【解决方案8】:

        在 5.4 版的 opencsv 上解决了我同样的问题:

        CSVWriter writer = new CSVWriter(new FileWriter(file), ',',
                                                     CSVWriter.NO_QUOTE_CHARACTER,
                                                     CSVWriter.DEFAULT_ESCAPE_CHARACTER,
                                                     CSVWriter.DEFAULT_LINE_END);
        

        【讨论】:

          猜你喜欢
          • 2016-02-02
          • 1970-01-01
          • 2015-04-24
          • 2019-01-30
          • 2014-02-19
          • 1970-01-01
          • 1970-01-01
          • 2017-09-28
          • 2017-06-13
          相关资源
          最近更新 更多