using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Data; using System.IO; using System.Text; /// ///ICSVWriterReader 的摘要说明 /// public class ICSVWriterReader { // C# 读写CSV文件到DataTable public interface ICSVWriterReaderDo {//define a interface string CSVFile { get; set; } //csv file DataTable Read();//read csv to DataTable. DataTable ReadTitle();//read csv to DataTable. bool Write(DataTable dt); //convert datatable to csv string WritelineString(DataTable dt);//返回表对应csv的字符串 } public class CSVHelper : ICSVWriterReader { private string _csvFile; public CSVHelper(string csvFile) { this._csvFile = csvFile; } #region ICSVWriterReader Members public string CSVFile { get { return _csvFile; } set { _csvFile = value; } } /// /// 读取CSV文件返回table,出错则返回对应错误 CSV格式分隔符, /// /// /// public void Read(out string Result , out DataTable Table) { Table = new DataTable(); Result = "True"; FileInfo fi = new FileInfo(this._csvFile); if (fi == null || !fi.Exists) Result = "文件不存在!" + this._csvFile; //StreamReader reader = new StreamReader(this._csvFile, Encoding.GetEncoding("GB2312")); StreamReader reader = new StreamReader(this._csvFile, Encoding.GetEncoding("UTF-8")); string line = string.Empty; int lineNumber = 0; try { while ((line = reader.ReadLine()) != null) { if (lineNumber == 0) {//Create Tole Table = CreateDataTable(line); if (Table.Columns.Count == 0) Result = "首行出错!"; } else { bool isSuccess = CreateDataRow(ref Table, line); if (!isSuccess) Result = "第" + lineNumber + "出错!"; } lineNumber++; } } catch (Exception ex) { throw ex; } reader.Close(); } public void Read(out string Result, out DataTable Table, string tag) { Table = new DataTable(); Result = "True"; FileInfo fi = new FileInfo(this._csvFile); if (fi == null || !fi.Exists) Result = "文件不存在!" + this._csvFile; StreamReader reader = new StreamReader(this._csvFile, Encoding.GetEncoding("GB2312")); //StreamReader reader = new StreamReader(this._csvFile, Encoding.GetEncoding("UTF-8")); string line = string.Empty; int lineNumber = 0; try { while ((line = reader.ReadLine()) != null) { if (lineNumber == 0) {//Create Tole Table = CreateDataTable(line); if (Table.Columns.Count == 0) Result = "首行出错!"; } else { bool isSuccess = CreateDataRow(ref Table, line); if (!isSuccess) Result = "第" + lineNumber + "出错!"; } lineNumber++; } } catch (Exception ex) { throw ex; } reader.Close(); } /// /// 读取CSV文件返回table,出错则返回对应错误 CSV格式分隔符; /// /// /// public void ReadTitle(out string Result, out DataTable Table) { Table = new DataTable(); Result = "True"; FileInfo fi = new FileInfo(this._csvFile); if (fi == null || !fi.Exists) Result = "文件不存在!" + this._csvFile; StreamReader reader = new StreamReader(this._csvFile, Encoding.GetEncoding("GB2312")); string line = string.Empty; int lineNumber = 0; try { while ((line = reader.ReadLine()) != null) { if (lineNumber == 0) {//Create Tole Table = CreateDataTableTitle(line); if (Table.Columns.Count == 0) Result = "首行出错!"; } else { bool isSuccess = CreateDataRowTitle(ref Table, line); if (!isSuccess) Result = "第" + lineNumber + "出错!"; } lineNumber++; } } catch (Exception ex) { throw ex; } reader.Close(); } /// /// 传入表datatable返回对应csv格式的字符串 /// /// 需要转换的表 /// 生成的对应的csv格式的字符串 public bool Write(DataTable dt) { FileInfo fi = new FileInfo(this._csvFile); if (fi == null) return false; if (dt == null || dt.Columns.Count == 0 || dt.Rows.Count == 0) return false; StreamWriter writer = new StreamWriter(this._csvFile, false, System.Text.Encoding.Default); string line = string.Empty; line = CreateTitle(dt); writer.WriteLine(line); foreach (DataRow dr in dt.Rows) { line = CretreLine(dr); writer.WriteLine(line); } writer.Close(); return true; } private DataTable CreateDataTable(string line) { DataTable dt = new DataTable(); int i =0; foreach (string field in read_csv(line)[0]) { i++; //如果标题为空则为第几列 if (field == "") { dt.Columns.Add("NO"+i.ToString()); } else { dt.Columns.Add(field); } } return dt; } private bool CreateDataRow(ref DataTable dt, string line) { DataRow dr = dt.NewRow(); string[] fileds = read_csv(line)[0]; if (fileds.Length == 0 || fileds.Length != dt.Columns.Count) return false; for (int i = 0; i < fileds.Length; i++) { dr[i] = fileds[i]; } dt.Rows.Add(dr); return true; } /// /// 传入封号分割的CSV生成表头如:xxx;xxx /// /// 字符串 /// private DataTable CreateDataTableTitle(string line) { DataTable dt = new DataTable(); int i = 0; foreach (string field in read_csvTitle(line)[0]) { i++; //如果标题为空则为第几列 if (field == "") { dt.Columns.Add("NO" + i.ToString()); } else { dt.Columns.Add(field); } } return dt; } private bool CreateDataRowTitle(ref DataTable dt, string line) { DataRow dr = dt.NewRow(); string[] fileds = read_csvTitle(line)[0]; if (fileds.Length == 0 || fileds.Length != dt.Columns.Count) return false; for (int i = 0; i < fileds.Length; i++) { dr[i] = fileds[i]; } dt.Rows.Add(dr); return true; } private string CreateTitle(DataTable dt) { string line = string.Empty; for (int i = 0; i < dt.Columns.Count; i++) { if (dt.Columns[i].ColumnName.ToString().IndexOf(",") != -1) { line = line + "\"" + dt.Columns[i].ColumnName + "\","; } else { line = line + dt.Columns[i].ColumnName + ","; } } line = line.Substring(0, line.Length - 1); return line; } private string CretreLine(DataRow dr) { string line = ""; for (int i = 0; i < dr.ItemArray.Length; i++) { if (dr[i].ToString().IndexOf(",") != -1) { line = line + "\"" + dr[i] + "\","; } else { line = line + dr[i] + ","; } } line = line.Substring(0, line.Length - 1); return line; } /// /// 读取CSV文件到数组中,如xxx;xxx;xxx /// /// 传入需要读取的CSV文件 /// public static string[][] read_csvTitle(string text) { if (text == null) return null; var text_array = new List(); var line = new List(); var field = new StringBuilder(); //是否在双引号内 bool in_quata = false; //字段是否开始 bool field_start = true; for (int i = 0; i < text.Length; i++) { char ch = text[i]; if (in_quata) { //如果已经处于双引号范围内 if (ch == '\"') { //如果是两个引号,则当成一个普通的引号处理 if (i < text.Length - 1 && text[i + 1] == '\"') { field.Append('\"'); i++; } else //否则退出引号范围 in_quata = false; } else //双引号范围内的任何字符(除了双引号)都当成普通字符 { field.Append(ch); } } else { switch (ch) { case ';': //新的字段开始 line.Add(field.ToString()); field.Remove(0, field.Length); field_start = true; break; case '\"'://引号的处理 if (field_start) in_quata = true; else field.Append(ch); break; case '\r': //新的记录行开始 if (field.Length > 0 || field_start) { line.Add(field.ToString()); field.Remove(0, field.Length); } text_array.Add(line.ToArray()); line.Clear(); field_start = true; //在 window 环境下,\r\n通常是成对出现,所以要跳过 if (i < text.Length - 1 && text[i + 1] == '\n') i++; break; default: field_start = false; field.Append(ch); break; } } } //文件结束 if (field.Length > 0 || field_start) line.Add(field.ToString()); if (line.Count > 0) text_array.Add(line.ToArray()); return text_array.ToArray(); } /// /// 读取CSV文件到数组中,如xxx,xxx,xxx /// /// 传入需要读取的CSV文件 /// public static string[][] read_csv(string text) { if (text == null) return null; var text_array = new List(); var line = new List(); var field = new StringBuilder(); //是否在双引号内 bool in_quata = false; //字段是否开始 bool field_start = true; for (int i = 0; i < text.Length; i++) { char ch = text[i]; if (in_quata) { //如果已经处于双引号范围内 if (ch == '\"') { //如果是两个引号,则当成一个普通的引号处理 if (i < text.Length - 1 && text[i + 1] == '\"') { field.Append('\"'); i++; } else //否则退出引号范围 in_quata = false; } else //双引号范围内的任何字符(除了双引号)都当成普通字符 { field.Append(ch); } } else { switch (ch) { case ',': //新的字段开始 line.Add(field.ToString()); field.Remove(0, field.Length); field_start = true; break; case '\"'://引号的处理 if (field_start) in_quata = true; else field.Append(ch); break; case '\r': //新的记录行开始 if (field.Length > 0 || field_start) { line.Add(field.ToString()); field.Remove(0, field.Length); } text_array.Add(line.ToArray()); line.Clear(); field_start = true; //在 window 环境下,\r\n通常是成对出现,所以要跳过 if (i < text.Length - 1 && text[i + 1] == '\n') i++; break; default: field_start = false; field.Append(ch); break; } } } //文件结束 if (field.Length > 0 || field_start) line.Add(field.ToString()); if (line.Count > 0) text_array.Add(line.ToArray()); return text_array.ToArray(); } #endregion } }