You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

496 lines
16 KiB
C#

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Data;
using System.IO;
using System.Text;
/// <summary>
///ICSVWriterReader 的摘要说明
/// </summary>
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; }
}
/// <summary>
/// 读取CSV文件返回table出错则返回对应错误 CSV格式分隔符,
/// </summary>
/// <param name="Result"></param>
/// <param name="Table"></param>
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();
}
/// <summary>
/// 读取CSV文件返回table出错则返回对应错误 CSV格式分隔符
/// </summary>
/// <param name="Result"></param>
/// <param name="Table"></param>
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();
}
/// <summary>
/// 传入表datatable返回对应csv格式的字符串
/// </summary>
/// <param name="dt">需要转换的表</param>
/// <returns>生成的对应的csv格式的字符串</returns>
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;
}
/// <summary>
/// 传入封号分割的CSV生成表头如xxx;xxx
/// </summary>
/// <param name="line">字符串</param>
/// <returns></returns>
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;
}
/// <summary>
/// 读取CSV文件到数组中如xxx;xxx;xxx
/// </summary>
/// <param name="text">传入需要读取的CSV文件</param>
/// <returns></returns>
public static string[][] read_csvTitle(string text)
{
if (text == null)
return null;
var text_array = new List<string[]>();
var line = new List<string>();
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();
}
/// <summary>
/// 读取CSV文件到数组中如xxx,xxx,xxx
/// </summary>
/// <param name="text">传入需要读取的CSV文件</param>
/// <returns></returns>
public static string[][] read_csv(string text)
{
if (text == null)
return null;
var text_array = new List<string[]>();
var line = new List<string>();
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
}
}