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#

2 months ago
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
}
}