CSV文件格式标准:
数据源文本 |
目标文本 |
|
英文逗号(,) |
英文逗号(,) |
出现左侧一种或多中情况时,在文本两侧加上英文冒号(“ ) |
英文冒号(“ ) |
替换成两个英文冒号(“”) |
|
换行符(\n) |
换行符(\n) |
|
回车符(\r) |
回车符(\r) |
|
回车换行符(\r\n) |
替换成(\r/\n) |
操作示例:
private DataTable GetData()
{
DataTable dta = new DataTable();
dta.Columns.Add("Code");
dta.Columns.Add("Name");
dta.Columns.Add("Address");
dta.Rows.Add("1", "正常", "中国北京");
dta.Rows.Add("1", "逗号", "中国,北京");
dta.Rows.Add("1", "换行", "中国\n北京");
dta.Rows.Add("1", "回车换行", "中国\r\n北京");
dta.Rows.Add("1", "逗号换行", "中,国北\n京");
dta.Rows.Add("1", "1个单引号", "中国'北京");
dta.Rows.Add("1", "2个单引号", "中国'北'京");
dta.Rows.Add("1", "1个双引号", "中国\"北京");
dta.Rows.Add("1", "2个双引号", "中国\"北\"京");
dta.Rows.Add("1", "1个单双引号", "中国'北\"京");
return dta;
}
private void WCsv_Loaded(object sender, RoutedEventArgs e)
{
string path = $@"C:\Users\Administrator\Desktop\ABC.csv";
string path2 = $@"C:\Users\Administrator\Desktop\ABC2.csv";
DataTable dta = GetData();
string errInfo;
//把数据集写到文件1
bool isOk =FuncCsv. CsvWrite(dta, path, out errInfo);
//读取文件1
DataTable dt2 = FuncCsv.CsvRead(path, out errInfo);
//把文件1的数据写到文件2,比较文件是否一致
bool isOk2= FuncCsv.CsvWrite(dt2, path2, out errInfo);
}
自定义类:
using System;
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.Linq;
using System.Text;
namespace Wpfjsj
{
///
/// CSV自定义类
///
public static class FuncCsv
{
private static readonly object Obj = new object();
///
/// 把数据集写到CSV文件
///
/// 数据集
/// 文件路径
/// 异常信息
/// 编码方式 默认为空(UFT-8)
/// 是否包含标题行(列名) 默认包含
/// 返回值 写入是否成功
public static bool CsvWrite(DataTable dt, string path, out string errInfo, Encoding en = null, bool isConHeader = true)
{
lock (Obj)
{
try
{
errInfo = "";
//以半角逗号(即,)作分隔符,列为空也要表达其存在。
//列内容如存在半角逗号(即,)则用半角引号(即"")将该字段值包含起来。
//列内容如存在半角引号(即")则应替换成半角双引号("")转义,并用半角引号(即"")将该字段值包含起来。
StringBuilder sb = new StringBuilder();
if (isConHeader)
{
for (int m = 0; m < dt.Columns.Count; m++)
{
sb.Append(dt.Columns[m].ColumnName);
if (m != dt.Columns.Count - 1)
sb.Append(",");
}
sb.Append("\r\n");
}
foreach (DataRow row in dt.Rows)
{
for (int i = 0; i < dt.Columns.Count; i++)
{
var colum = dt.Columns[i];
if (i != 0) sb.Append(",");
string str = row[colum].ToString();
sb.Append(colum.DataType == typeof(string) ? ConvStr_CsvWrite(str) : str);
}
sb.Append("\r\n");
}
StreamWriter sw = new StreamWriter(path, false, en ?? Encoding.UTF8);
sw.Write(sb);
sw.Flush();
sw.Close();
return true;
}
catch (Exception ex)
{
errInfo = ex.Message;
return false;
}
}
}
private static readonly object Obj1 = new object();
///
/// 读取CSV文件内容到数据集
///
/// 文件路径
/// 异常信息
/// 编码方式 默认为空(UFT-8)
/// 文件内容是否包含标题行(列名),默认包含
/// 返回的数据集
public static DataTable CsvRead(string path, out string errInfo, Encoding en = null, bool isConHeader = true)
{
lock (Obj1)
{
errInfo = "";
DataTable dt = new DataTable();
try
{
//读取文件
StreamReader sr = new StreamReader(path, en ?? Encoding.UTF8);
string result = sr.ReadToEnd();
sr.Close();
//解析文件
int index = 0;
foreach (string content in result.Split(new[] {"\r\n"}, StringSplitOptions.None))
{
if (string.IsNullOrWhiteSpace(content)) continue;
string[] strCols = StrToStrArray(content);
if (index == 0)
{
if (isConHeader)
{
foreach (string str in strCols)
dt.Columns.Add(str);
index++;
continue;
}
//自定义标题
for (int m = 1; m <= strCols.Length; m++)
dt.Columns.Add($"Col{m}");
index = 1;
}
dt.Rows.Add(strCols);
}
}
catch (Exception ex)
{
errInfo = ex.Message;
}
return dt;
}
}
private static string[] StrToStrArray(string strLine)
{
string[] strFirsts = strLine.Split(',');
List list = new List();
StringBuilder sbCombie = new StringBuilder();
foreach (string str in strFirsts)
{
int indexOneFirst = str.IndexOf('\"');
//常规字符串
if (sbCombie.Length == 0 && indexOneFirst < 0)
{
list.Add(str);
continue;
}
//字符串末尾 冒号连续出现的次数为奇数 则字符串结束
int count = 0;
for (int n = str.Length - 1; n >= 0; n--)
{
if (str[n] == '\"')
count++;
else
break;
}
//源字符串带冒号 不带逗号
if (sbCombie.Length == 0 && indexOneFirst == 0 && count % 2 == 1)
{
list.Add(ConvStr_CsvRead(str));
continue;
}
if (count % 2 == 0)
{
sbCombie.Append($"{str},");
}
else
{
sbCombie.Append(str);
list.Add(ConvStr_CsvRead(sbCombie.ToString()));
sbCombie.Clear();
}
}
return list.ToArray();
}
private static string ConvStr_CsvRead(string str)
{
if (str.Contains('\"'))
{
str = str.Replace("\r/\n", "\r\n").Replace("\"\"", "\"");
return str.Substring(1, str.Length - 2);
}
return str;
}
private static string ConvStr_CsvWrite(string str)
{
if (str.Contains(',') || str.Contains('\n') || str.Contains('\r') || str.Contains('"'))
return $"\"{str.Replace("\r\n", "\r/\n").Replace("\"", "\"\"")}\"";
return str;
}
}
}