关于CSV文件的读写问题(特别是有双引号和逗号的情况)

Posted 十一路客

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了关于CSV文件的读写问题(特别是有双引号和逗号的情况)相关的知识,希望对你有一定的参考价值。

一. 对于CSV的读写既可以像读写txt文件似的读写

/*===================读文件=======================*/
InputStreamReader read = new InputStreamReader(
new FileInputStream(file),encoding);//考虑到编码格式
BufferedReader bufferedReader = new BufferedReader(read);
String lineTxt;
 while((lineTxt = bufferedReader.readLine()) != null )
     if(!lineTxt.trim().equals("")) 
              String[] temp = lineTxt.split("\\t",-1);
              txtList.add(temp);
      


read.close();


/*==================写文件========================*/
File txtFile = new File(filePath);
//追加
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(txtFile, true),encoding));
if(content != null && content.size()>0)
     for(Integer i=0 ; i<content.size(); i++)
           String[] element = content.get(i);//一行元素
           if(element != null && element.length > 0)
                for(Integer j=0; j<element.length; j++)
                     String temp = element[j];
                     if(j == element.length - 1)
                           bw.write(temp + "\\n");
                     else
                           bw.write(temp + separator);
                     
                
       
                   

也可以用java提供的库javacsv和opencsv写,但是注意javacsv不可追加,中文OK;opencsv可追加,但是中文会乱码。两者可写入字段中含有逗号的内容。

二. 用写txt文件的方式写csv时,针对内容中的逗号和双引号要做特殊处理(参考文章):

CSV全称是:Comma Separated Values 或者 Character Separated Values。

尽管第一种说法更常见,但我觉得还是第二种说法更确切一些,因为你可以使用其它字符做分隔符。

使用逗号做分隔符的CSV文件有一个好处:你可以直接用Excel打开。如果使用其它分隔符,比如“|”,你必须告诉Excel该文件使用“|”作分隔符,Excel才能把它导入进来。

前几天,project manager告诉我:我们有许多CSV文件,都是使用“|”做分隔符,用Excel打开的时候比较麻烦,用户想在Excel中直接打开。这样就需要使用“,”做分隔符。但是文件中有些字段含有逗号,必须对这些逗号特殊处理,才能保证CSV文件在Excel中正确打开。他还给了我一个算法:

如果字段中有逗号(,),该字段使用双引号(”)括起来;

如果该字段中有双引号,该双引号前要再加一个双引号,然后把该字段使用双引号括起来。

看完project manager的要求,我真是满头起包啊。在IT业混了十几年了,竟然不知道这样处理逗号。
举几个例子:







字段处理前 字段处理后
abc,d2 "abc,d2"
ab"c,d2 "ab""c,d2"
"abc """abc"
""""""""

如果字段中有两个挨着的双引号,比如:aaa”“ccc。这种情况不用特殊处理。这是我在写这篇博客的时候才想起来的,赶忙使用Excel测试了一下。还好,不用特殊处理就能正常打开,不然我还得改程序。当然了,如果你把它处理成:”aaa”“”“ccc” Excel也能正常打开。事后总结总结真是有好处啊。

另外,如果某字段第一个字符是空格,第二个字符是双引号,这种情况不用特殊处理。Project Manager在给我描述算法的时候,也举了一个字段只有一个双引号的例子,但他不小心在双引号前面加了个空格,把问题掩盖过去了。

因此在写CSV文件时,需要先判断是否有逗号和双引号,并做相应处理

boolean quoteFlag = false;//标记是否添加过双引号
//20161214 若发现有逗号  需前后加引号 否则会出现串列的情况
String value = element[i];
if(value.contains("\\"")) //若发现有双引号  需要将字符串中的一个双引号替换为两个 并且需前后加双引号
        value = value.replaceAll("\\"","\\"\\"");
        value = "\\"" + value + "\\"";
        quoteFlag = true;
 
 if(value.contains(",") && !quoteFlag) //若发现有逗号  需前后加引号
        value = "\\"" + value + "\\"";
 

if(j == fileHeader.size() - 1)
         bw.write(value + "\\n");
 else
         bw.write(value + separator);
 

读这样的csv文件时,需要做类似的处理:

//去掉字符串前后字符串 for csv输出
public static String clearStartAndEndQuote(String str)
        if(str != null && str.length()>=2) 
            if(str.indexOf("\\"")==0) str = str.substring(1,str.length());   //去掉第一个 "
            if(str.lastIndexOf("\\"")==(str.length()-1)) str = str.substring(0,str.length()-1);  //去掉最后一个 "

            str = str.replaceAll("\\"\\"","\\"");//把两个双引号换成一个双引号
        
        return str;
 

String tempValue = ClassUtil.clearStartAndEndQuote(temp[j]);

三. 文本内容的逗号分隔(参考文章)

当大家进行这一操作的时候通常会遇到如下问题。
1: 想分割数据 例如:

"123","Jack jona","Computer science"
"234","Joen Dan", "Philosophy"

//当遇到这种数据的时候可直接用 逗号进行分割。

String[] strArr = str.trim().split(",",-1); 

2: 分割数据如下:

"123", "jack jona", "New York, NY"
"234", "Lee Jack", "Fort myers, FL"

//当遇到这种数据的时候可以直接使用

String[] strArr = str.trim().split(",(?=([^\\\\\\"]*\\\\\\"[^\\\\\\"]*\\\\\\")*[^\\\\\\"]*$)",-1); //双引号内的逗号不分割  双引号外的逗号进行分割

//进行分割。 这种的好处是只对引号外面的逗号进行分割,对引号内的不分割。
//简单的说这种分割得出的结果是
123| jack jona| New York, NY
234| Lee Jack| Fort myers, FL

以上是关于关于CSV文件的读写问题(特别是有双引号和逗号的情况)的主要内容,如果未能解决你的问题,请参考以下文章

CSV文件的双引号怎么去掉。用记事本打开有双引号,EXCEL打开又没有了,怎么样去掉这个双引号,这是个啥

csv文件

CSV文件格式要求

CSV文件格式介绍

正则表达式删除由双引号划定的 CSV 字段中的双引号

opencsv写入时去掉双引号