zoukankan      html  css  js  c++  java
  • 用C#写的读写CSV文件

    用C#写的读取CSV文件的源代码

    CSV文件的格子中包含逗号,引号,换行等,都能轻松读取,而且可以把数据转化成DATATABLE格式

    using System;
    using System.Text;
    using System.Collections;
    using System.IO;
    using System.Data;
    using System.Text.RegularExpressions;
    using System.Diagnostics;
     
    namespace CsvLib
    {
     #region 类说明信息
     
     /// <summary>
     ///  <DL>
     ///  <DT><b>读CSV文件类,读取指定的CSV文件,可以导出DataTable</b></DT>
     ///   <DD>
     ///    <UL> 
     ///    </UL>
     ///   </DD>
     ///  </DL>
     ///  <Author>yangzhihong</Author>   
     ///  <CreateDate>2006/01/16</CreateDate>
     ///  <Company></Company>
     ///  <Version>1.0</Version>
     /// </summary>
     #endregion
     public class CsvStreamReader
     {
      private  ArrayList  rowAL;        //行链表,CSV文件的每一行就是一个链
      private  string  fileName;       //文件名
     
      private  Encoding encoding;       //编码
     
      public CsvStreamReader()
      {
       this.rowAL = new ArrayList();   
       this.fileName = "";
       this.encoding = Encoding.Default;
      }
     
      /// <summary>
      ///
      /// </summary>
      /// <param name="fileName">文件名,包括文件路径</param>
      public CsvStreamReader(string fileName)
      {
       this.rowAL = new ArrayList();    
       this.fileName = fileName;
       this.encoding = Encoding.Default;
       LoadCsvFile();
      }
     
      /// <summary>
      ///
      /// </summary>
      /// <param name="fileName">文件名,包括文件路径</param>
      /// <param name="encoding">文件编码</param>
      public CsvStreamReader(string fileName,Encoding encoding)
      {
       this.rowAL = new ArrayList();  
       this.fileName = fileName;
       this.encoding = encoding;
       LoadCsvFile();
      }
     
      /// <summary>
      /// 文件名,包括文件路径
      /// </summary>
      public string FileName
      {
       set
       {
        this.fileName = value;
        LoadCsvFile();
       }
      }
     
      /// <summary>
      /// 文件编码
      /// </summary>
     
      public Encoding FileEncoding
      {
       set
       {
        this.encoding = value;
       }
      }
     
      /// <summary>
      /// 获取行数
      /// </summary>
      public int RowCount
      {
       get
       {
        return this.rowAL.Count;
       }
      }
     
      /// <summary>
      /// 获取列数
      /// </summary>
      public int ColCount
      {
       get
       {
        int maxCol;
     
        maxCol = 0;
        for (int i = 0;i<this.rowAL.Count;i++)
        {
         ArrayList colAL = (ArrayList) this.rowAL[i];
     
         maxCol = (maxCol > colAL.Count)?maxCol:colAL.Count;
        }
     
        return maxCol;
       }
      }
     
     
      /// <summary>
      /// 获取某行某列的数据
     
      /// row:行,row = 1代表第一行
     
      /// col:列,col = 1代表第一列  
      /// </summary>
      public string this[int row,int col]
      {
       get
       {   
        //数据有效性验证
     
        CheckRowValid(row);
        CheckColValid(col);
        ArrayList colAL = (ArrayList) this.rowAL[row-1];
     
        //如果请求列数据大于当前行的列时,返回空值
     
        if (colAL.Count < col)
        {
         return "";
        }
         
                    return colAL[col-1].ToString();    
       }
      }
     
     
      /// <summary>
      /// 根据最小行,最大行,最小列,最大列,来生成一个DataTable类型的数据
     
      /// 行等于1代表第一行
     
      /// 列等于1代表第一列
     
      /// maxrow: -1代表最大行
      /// maxcol: -1代表最大列
      /// </summary>
      public DataTable this[int minRow,int maxRow,int minCol,int maxCol]
      {
       get
       {
        //数据有效性验证
     
        CheckRowValid(minRow);
        CheckMaxRowValid(maxRow);
        CheckColValid(minCol);
        CheckMaxColValid(maxCol);
        if (maxRow == -1)
        {
         maxRow = RowCount;
        }
        if (maxCol == -1)
        {
         maxCol = ColCount;
        }
        if (maxRow < minRow)
        {
         throw new Exception("最大行数不能小于最小行数");
        }
        if (maxCol < minCol)
        {
         throw new Exception("最大列数不能小于最小列数");
        }
        DataTable csvDT = new DataTable();
        int   i;
        int   col;
        int   row;
     
        //增加列
     
        for (i = minCol;i <= maxCol;i++)
        {
         csvDT.Columns.Add(i.ToString());
        }
        for (row = minRow;row <= maxRow;row++)
        {
         DataRow csvDR = csvDT.NewRow();
     
         i = 0;
         for (col = minCol;col <=maxCol;col++)
         {
          csvDR[i] = this[row,col];
          i++;
         }
         csvDT.Rows.Add(csvDR);
        }
     
        return csvDT;
       }
      }
     
     
      /// <summary>
      /// 检查行数是否是有效的
     
      /// </summary>
      /// <param name="col"></param>  
      private void CheckRowValid(int row)
      {
       if (row <= 0)
       {
        throw new Exception("行数不能小于0");    
       } 
       if (row > RowCount)
       {
        throw new Exception("没有当前行的数据");   
       }  
      }
     
      /// <summary>
      /// 检查最大行数是否是有效的
     
      /// </summary>
      /// <param name="col"></param>  
      private void CheckMaxRowValid(int maxRow)
      {
       if (maxRow <= 0 && maxRow != -1)
       {
        throw new Exception("行数不能等于0或小于-1");    
       } 
       if (maxRow > RowCount)
       {
        throw new Exception("没有当前行的数据");   
       }  
      }
     
      /// <summary>
      /// 检查列数是否是有效的
     
      /// </summary>
      /// <param name="col"></param>  
      private void CheckColValid(int col)
      {
       if (col <= 0)
       {
        throw new Exception("列数不能小于0");    
       } 
       if (col > ColCount)
       {
        throw new Exception("没有当前列的数据");   
       }
      }
     
      /// <summary>
      /// 检查检查最大列数是否是有效的
     
      /// </summary>
      /// <param name="col"></param>  
      private void CheckMaxColValid(int maxCol)
      {
       if (maxCol <= 0 && maxCol != -1)
       {
        throw new Exception("列数不能等于0或小于-1");    
       } 
       if (maxCol > ColCount)
       {
        throw new Exception("没有当前列的数据");   
       }
      }
     
      /// <summary>
      /// 载入CSV文件
      /// </summary>
      private void LoadCsvFile()
      {
       //对数据的有效性进行验证
     
       if (this.fileName == null)
       {
        throw new Exception("请指定要载入的CSV文件名");
       }
       else if (!File.Exists(this.fileName))
       {
        throw new Exception("指定的CSV文件不存在");
       }
       else
       {
       }
       if (this.encoding == null)
       {
        this.encoding = Encoding.Default;
       }
     
       StreamReader sr = new StreamReader(this.fileName,this.encoding); 
       string   csvDataLine;
        
       csvDataLine = "";
       while (true)
       {
        string fileDataLine;
     
        fileDataLine = sr.ReadLine();
        if (fileDataLine == null)
        {
         break;
        }
        if (csvDataLine == "")
        {
         csvDataLine = fileDataLine;//GetDeleteQuotaDataLine(fileDataLine);
        }
        else
        {
         csvDataLine += "/r/n" + fileDataLine;//GetDeleteQuotaDataLine(fileDataLine);
        }
        //如果包含偶数个引号,说明该行数据中出现回车符或包含逗号
        if (!IfOddQuota(csvDataLine))
        {
         AddNewDataLine(csvDataLine);
         csvDataLine = "";
        }
       }           
       sr.Close();
       //数据行出现奇数个引号
       if (csvDataLine.Length > 0)
       {
        throw new Exception("CSV文件的格式有错误");
       }
      }
     
      /// <summary>
      /// 获取两个连续引号变成单个引号的数据行
      /// </summary>
      /// <param name="fileDataLine">文件数据行</param>
      /// <returns></returns>
      private string GetDeleteQuotaDataLine(string fileDataLine)
      {
       return fileDataLine.Replace("/"/"","/"");
      }
     
      /// <summary>
      /// 判断字符串是否包含奇数个引号
      /// </summary>
      /// <param name="dataLine">数据行</param>
      /// <returns>为奇数时,返回为真;否则返回为假</returns>
      private bool IfOddQuota(string dataLine)
      {
       int  quotaCount;
       bool oddQuota;
     
       quotaCount = 0;
       for (int i = 0;i < dataLine.Length;i++)
       {
        if (dataLine[i] == '/"')
        {
         quotaCount++;
        }
       }
     
       oddQuota = false;
       if (quotaCount % 2 == 1)
       {
        oddQuota = true;
       }   
     
       return oddQuota;
      }
     
      /// <summary>
      /// 判断是否以奇数个引号开始
     
      /// </summary>
      /// <param name="dataCell"></param>
      /// <returns></returns>
      private bool IfOddStartQuota(string dataCell)
      {
       int  quotaCount;
       bool oddQuota;
     
       quotaCount = 0;
       for (int i = 0;i < dataCell.Length;i++)
       {
        if (dataCell[i] == '/"')
        {
         quotaCount++;
        }
        else
        {
         break;
        }
       }
     
       oddQuota = false;
       if (quotaCount % 2 == 1)
       {
        oddQuota = true;
       }   
     
       return oddQuota;
      }
     
      /// <summary>
      /// 判断是否以奇数个引号结尾
      /// </summary>
      /// <param name="dataCell"></param>
      /// <returns></returns>
      private bool IfOddEndQuota(string dataCell)
      {
       int  quotaCount;
       bool oddQuota;
     
       quotaCount = 0;
       for (int i = dataCell.Length -1;i >= 0;i--)
       {
        if (dataCell[i] == '/"')
        {
         quotaCount++;
        }
        else
        {
         break;
        }
       }
     
       oddQuota = false;
       if (quotaCount % 2 == 1)
       {
        oddQuota = true;
       }   
     
       return oddQuota;
      }
     
      /// <summary>
      /// 加入新的数据行
     
      /// </summary>
      /// <param name="newDataLine">新的数据行</param>
      private void AddNewDataLine(string newDataLine)
      {
       Debug.WriteLine("NewLine:" + newDataLine);
     
       //return;
     
       ArrayList colAL = new ArrayList();
       string[] dataArray = newDataLine.Split(',');
       bool  oddStartQuota;       //是否以奇数个引号开始
     
       string      cellData;
     
       oddStartQuota = false;
       cellData = "";
       for (int i = 0 ;i < dataArray.Length;i++)
       {
        if (oddStartQuota)
        {
         //因为前面用逗号分割,所以要加上逗号
         cellData += "," + dataArray[i];
         //是否以奇数个引号结尾
         if (IfOddEndQuota(dataArray[i]))
         {
          colAL.Add(GetHandleData(cellData));
          oddStartQuota = false;
          continue;
         }
        }
        else
        {
         //是否以奇数个引号开始
     
         if (IfOddStartQuota(dataArray[i]))
         {
          //是否以奇数个引号结尾,不能是一个双引号,并且不是奇数个引号
     
          if (IfOddEndQuota(dataArray[i]) && dataArray[i].Length > 2 && !IfOddQuota(dataArray[i]))
          {
           colAL.Add(GetHandleData(dataArray[i]));
           oddStartQuota = false;
           continue;
          }
          else
          {
     
           oddStartQuota = true;  
           cellData = dataArray[i];
           continue;
          }
         } 
         else
         {
          colAL.Add(GetHandleData(dataArray[i])); 
         }
        }           
       }
       if (oddStartQuota)
       {
        throw new Exception("数据格式有问题");
       }
       this.rowAL.Add(colAL);
      }
     
     
      /// <summary>
      /// 去掉格子的首尾引号,把双引号变成单引号
     
      /// </summary>
      /// <param name="fileCellData"></param>
      /// <returns></returns>
      private string GetHandleData(string fileCellData)
      {
       if (fileCellData == "")
       {
        return "";
       }
       if (IfOddStartQuota(fileCellData))
       {
        if (IfOddEndQuota(fileCellData))
        {
         return fileCellData.Substring(1,fileCellData.Length-2).Replace("/"/"","/""); //去掉首尾引号,然后把双引号变成单引号
        }
        else
        {
         throw new Exception("数据引号无法匹配" + fileCellData);
        }    
       }
       else
       {
        //考虑形如""    """"      """"""   
        if (fileCellData.Length >2 && fileCellData[0] == '/"')
        {
         fileCellData = fileCellData.Substring(1,fileCellData.Length-2).Replace("/"/"","/""); //去掉首尾引号,然后把双引号变成单引号
        }
       }
     
       return fileCellData;
      }
     }
    }
     
      
     
    using System;
    using System.Text;
    using System.Collections;
    using System.IO;
    using System.Data;
     
    namespace CsvLib
    {
     #region 类说明信息
     /// <summary>
     ///  <DL>
     ///  <DT><b>写CSV文件类,首先给CSV文件赋值,最后通过Save方法进行保存操作</b></DT>
     ///   <DD>
     ///    <UL> 
     ///    </UL>
     ///   </DD>
     ///  </DL>
     ///  <Author>yangzhihong</Author>   
     ///  <CreateDate>2006/01/16</CreateDate>
     ///  <Company></Company>
     ///  <Version>1.0</Version>
     /// </summary>
     #endregion
     public class CsvStreamWriter
     {  
      private  ArrayList  rowAL;        //行链表,CSV文件的每一行就是一个链
      private  string  fileName;       //文件名
      private  Encoding encoding;       //编码
     
      public CsvStreamWriter()
      {
       this.rowAL = new ArrayList();   
       this.fileName = "";
       this.encoding = Encoding.Default;
      }
     
      /// <summary>
      ///
      /// </summary>
      /// <param name="fileName">文件名,包括文件路径</param>
      public CsvStreamWriter(string fileName)
      {
       this.rowAL = new ArrayList();    
       this.fileName = fileName;
       this.encoding = Encoding.Default;
      }
     
      /// <summary>
      ///
      /// </summary>
      /// <param name="fileName">文件名,包括文件路径</param>
      /// <param name="encoding">文件编码</param>
      public CsvStreamWriter(string fileName,Encoding encoding)
      {
       this.rowAL = new ArrayList();  
       this.fileName = fileName;
       this.encoding = encoding;
      }
     
      /// <summary>
      /// row:行,row = 1代表第一行
      /// col:列,col = 1代表第一列
      /// </summary>
      public string this[int row,int col]
      {
       set
       {
        //对行进行判断
        if (row <= 0)
        {
         throw new Exception("行数不能小于0");
        }    
        else if (row > this.rowAL.Count) //如果当前列链的行数不够,要补齐
        {
         for (int i = this.rowAL.Count + 1;i <= row;i++)
         {
          this.rowAL.Add(new ArrayList());
         }
        }
        else
        {
        }
        //对列进行判断
        if (col <= 0)
        {
         throw new Exception("列数不能小于0");
        }
        else
        {
         ArrayList colTempAL = (ArrayList) this.rowAL[row-1];
     
         //扩大长度
         if (col > colTempAL.Count)
         {
          for (int i = colTempAL.Count;i <= col;i++)
          {
           colTempAL.Add("");
          }
         }
         this.rowAL[row-1] = colTempAL;
        }
        //赋值
        ArrayList colAL = (ArrayList) this.rowAL[row-1];
     
        colAL[col-1] = value;
        this.rowAL[row-1] = colAL;
       }
      }
     
     
      /// <summary>
      /// 文件名,包括文件路径
      /// </summary>
      public string FileName
      {
       set
       {
        this.fileName = value;
       }
      }
     
      /// <summary>
      /// 文件编码
      /// </summary>
     
      public Encoding FileEncoding
      {
       set
       {
        this.encoding = value;
       }
      }
     
      /// <summary>
      /// 获取当前最大行
      /// </summary>
      public int CurMaxRow
      {
       get
       {
        return this.rowAL.Count;
       }
      }
     
      /// <summary>
      /// 获取最大列
      /// </summary>
      public int CurMaxCol
      {
       get
       {
        int maxCol;
     
        maxCol = 0;
        for (int i = 0;i<this.rowAL.Count;i++)
        {
         ArrayList colAL = (ArrayList) this.rowAL[i];
     
         maxCol = (maxCol > colAL.Count)?maxCol:colAL.Count;
        }
     
        return maxCol;
       }
      }
     
      /// <summary>
      /// 添加表数据到CSV文件中
      /// </summary>
      /// <param name="dataDT">表数据</param>
      /// <param name="beginCol">从第几列开始,beginCol = 1代表第一列</param>
      public void AddData(DataTable dataDT,int beginCol)
      {
       if (dataDT == null)
       {
        throw new Exception("需要添加的表数据为空");
       }
       int curMaxRow;
     
       curMaxRow = this.rowAL.Count;
       for (int i = 0;i < dataDT.Rows.Count;i++)
       {
        for (int j = 0;j <dataDT.Columns.Count;j++)
        {
         this[curMaxRow + i + 1,beginCol + j] = dataDT.Rows[i][j].ToString();     
        }
       }
      }
     
      /// <summary>
      /// 保存数据,如果当前硬盘中已经存在文件名一样的文件,将会覆盖
      /// </summary>
      public void Save()
      {
       //对数据的有效性进行判断
       if (this.fileName == null)
       {
        throw new Exception("缺少文件名");
       }
       else if (File.Exists(this.fileName))
       {
        File.Delete(this.fileName);
       }
       if (this.encoding == null)
       {
        this.encoding = Encoding.Default;
       }
       System.IO.StreamWriter sw = new StreamWriter(this.fileName,false,this.encoding);
     
       for (int i = 0 ;i < this.rowAL.Count;i++)
       {
        sw.WriteLine(ConvertToSaveLine((ArrayList) this.rowAL[i]));    
       }
     
       sw.Close();
      }
     
      /// <summary>
      /// 保存数据,如果当前硬盘中已经存在文件名一样的文件,将会覆盖
      /// </summary>
      /// <param name="fileName">文件名,包括文件路径</param>
      public void Save(string fileName)
      {
       this.fileName = fileName;
       Save();
      }
     
      /// <summary>
      /// 保存数据,如果当前硬盘中已经存在文件名一样的文件,将会覆盖
      /// </summary>
      /// <param name="fileName">文件名,包括文件路径</param>
      /// <param name="encoding">文件编码</param>
      public void Save(string fileName,Encoding encoding)
      {
       this.fileName = fileName;
       this.encoding = encoding;
       Save();
      }
     
     
      /// <summary>
      /// 转换成保存行
      /// </summary>
      /// <param name="colAL">一行</param>
      /// <returns></returns>
      private string ConvertToSaveLine(ArrayList colAL)
      {
       string saveLine;
     
       saveLine = "";
       for (int i = 0;i< colAL.Count;i++)
       {
        saveLine += ConvertToSaveCell(colAL[i].ToString());
        //格子间以逗号分割
        if (i < colAL.Count - 1)
        {
         saveLine += ",";
        }    
       }
     
       return saveLine;
      }
     
      /// <summary>
      /// 字符串转换成CSV中的格子
      /// 双引号转换成两个双引号,然后首尾各加一个双引号
      /// 这样就不需要考虑逗号及换行的问题
      /// </summary>
      /// <param name="cell">格子内容</param>
      /// <returns></returns>
      private string ConvertToSaveCell(string cell)
      {
       cell = cell.Replace("/"","/"/"");
       
       return "/"" + cell + "/"";
      }
     }
    }
  • 相关阅读:
    JS完整获取IE浏览器信息
    C# DataSet和DataTable详解
    linux下mysql导入数据
    Linux上安装mysql
    JDK6+tomcat7+mysql官网下载地址
    Linux常用命令
    mysql 授权
    tomcat7.0学习笔记
    struts2 <s:property/>标签的使用输出时间格式转换
    Linux如何查找软件安装路径?
  • 原文地址:https://www.cnblogs.com/wordgao/p/4571358.html
Copyright © 2011-2022 走看看