CSV文件对逗号和引号字符的转义处理,使用EXCEL打开时在一个单元格内

您所在的位置:网站首页 怎么去除整列数据中的逗号 CSV文件对逗号和引号字符的转义处理,使用EXCEL打开时在一个单元格内

CSV文件对逗号和引号字符的转义处理,使用EXCEL打开时在一个单元格内

2024-07-14 12:33| 来源: 网络整理| 查看: 265

CSV文件本质是一种用逗号和(回车)换行符分割的文本文件,可以直接用Excel打开              * CSV (逗号分隔值文件格式)Comma-Separated Values 【每一行的分割符必须是英文的逗号,不能是中文的逗号】              * 逗号分隔值(Comma-Separated Values,CSV,有时也称为字符分隔值,因为分隔字符也可以不是逗号),其文件以纯文本形式存储表格数据(数字和文本)。              * 纯文本意味着该文件是一个字符序列,不含必须像二进制数字那样被解读的数据。              * CSV文件由任意数目的记录组成,记录间以某种换行符分隔;每条记录由字段组成,字段间的分隔符是其它字符或字符串,最常见的是逗号或制表符。              * 通常,所有记录都有完全相同的字段序列。通常都是纯文本文件.              * 建议使用WORDPAD或是记事本来开启,再则先另存新档后用EXCEL开启,也是方法之一。              *               * CSV格式是分隔的数据格式,有字段/列分隔的逗号字符和记录/行分隔换行符。              * 字段包含特殊字符(逗号,换行符,或双引号),必须以双引号括住。行内包含一个项目是空字符串,可以以双引号括住。              * 字段的值包含双引号时,要双写这个双引号(就像把一个双引号当做转义符一样)。              * CSV文件格式并不需要特定的字符编码,字节顺序,或行终止格式。              * 每个记录是一个行终止换行符(ASCII码/LF = 0x0A) 或 回车换行符(ASCII码/CRLF = 0x0D0A)。              * 0x0A【换行符】 在C#中代表字符 '\n'              * 0x0D0A【回车换行】 在C#中代表字符串 "\r\n"               *               * 转义(Escaped)要求:              * 包含逗号, 双引号, 或是换行符的字段必须放在引号内.【使用引号来进行特殊符号 Escaped转义】              * 字段内部的引号必须在其前面增加一个引号来实现文字引号的转码.              *               * 规则:              * 1 开头是不留空,以行为单位。              * 2 可含或不含列名,含列名则居文件第一行。              * 3 一行数据不跨行,无空行。              * 4 以半角英文逗号(即,)作分隔符,列为空也要表达其存在。              * 5 列内容如存在半角引号(即"),替换成半角双引号("")转义,即用半角引号(即"")将该字段值包含起来。              * 6 文件读写时引号,逗号操作规则互逆。              * 7 内码格式不限,可为 ASCII、Unicode 或者其他。              * 8 不支持数字              * 9 不支持特殊字符

我们使用时,如果不对引号 或者 逗号 进行特殊处理,使用Excel打开就会排列不美观,如图:

如果进行转义(Escaped)处理,如图:

对CSV文件的每一项都进行转义处理,关键函数如下:

/// /// 处理csv文件中的双引号和逗号,使其在Excel中完美显示为一个单元格 /// 斯内科 20210321 /// /// /// private static string ProcessPunctuationForCsv(string srcStr) { if (srcStr == null) { return string.Empty; } bool quoteFlag = false;//是否添加过双引号 //如果存在双引号,需要将字符串的一个双引号 替换为 两个双引号。并且需要在字符串的前后加上双引号 if (srcStr.Contains("\"")) { srcStr = srcStr.Replace("\"", "\"\""); srcStr = "\"" + srcStr + "\""; quoteFlag = true; } //如果只存在逗号(不存在引号),将前后加引号即可 if (srcStr.Contains(",") && !quoteFlag) { srcStr = "\"" + srcStr + "\""; } return srcStr; } 下面使用Winform程序进行验证:

新建窗体应用程序CsvFileEscapedDemo,将默认的Form1重命名为 FormCsvFileEscaped

窗体设计如图:

新建测试类Employee.cs using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace CsvFileEscapedDemo { /// /// 员工信息 /// public class Employee { public Employee() { this.ListSkills = new List(); } /// /// 编号 /// public int CoreId { get; set; } /// /// 姓名 /// public string EmployeeName { get; set; } /// /// 地址 /// public string Address { get; set; } /// /// 技能列表 /// public List ListSkills { get; set; } } } 新建读写CSV的相关类CsvUtil

相关程序如下:

using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; namespace CsvFileEscapedDemo { /// /// 对CSV文件进行读写 /// public class CsvUtil { /* * 1:csv与Excel本质区别是文本文件 * 2:每个单元格的数据用,分割 * 3:每行的数据用\r\n分割 */ private static Object thisLock = new Object(); /// /// 创建Csv /// /// 路径 /// 名称 /// public static bool CreateCsv(string _path, string _name) { lock (thisLock) { try { using (File.Create(_path + _name + ".csv")) { } return true; } catch (Exception) { return false; } } } /// /// 删除Csv /// /// 路径 /// 名称 /// public static bool DeleteCsv(string _path, string _name) { string _tmPath = _path + _name + ".csv"; lock (thisLock) { try { if (File.Exists(_tmPath) == true) { File.Delete(_tmPath); return true; } else { return false; } } catch (Exception e) { MessageBox.Show("CSV文件删除失败:" + e.Message); return false; } } } /// /// 读取csv /// /// 路径,如 @"D:\MESLog\ABC\" /// 名称,不带.csv /// 读取到的数据 /// public static bool ReadCsv(string _path, string _name, ref List _recvData) { return ReadCsv(Path.Combine(_path, _name + ".csv"), ref _recvData); } /// /// 读取csv /// /// 路径,如 @"D:\MESLog\ABC\" /// 名称,不带.csv /// 读取到的数据 /// 异常信息 /// public static bool ReadCsv(string _path, string _name, ref List _recvData, ref string errorMsg) { return ReadCsv(Path.Combine(_path, _name + ".csv"), ref _recvData, ref errorMsg); } /// /// 读取csv文件 /// /// 全路径 /// 返回的值 /// public static bool ReadCsv(string fullfilePath, ref List recvData) { string errorMsg = ""; return ReadCsv(fullfilePath, ref recvData, ref errorMsg); } /// /// 读取csv文件 /// /// 全路径 /// 返回的值 /// public static bool ReadCsv(string fullfilePath, ref List recvData, ref string errorMsg) { lock (thisLock) { try { if (!fullfilePath.Contains(".csv")) { errorMsg = "路径中没有.csv后缀"; return false; } string _tmPath = fullfilePath; using (StreamReader reader = new StreamReader(_tmPath, Encoding.Default)) { string _lin = reader.ReadToEnd().Trim(); string[] _str = _lin.Split('\n'); recvData.Clear(); for (int i = 0; i < _str.Length; i++) { _str[i] = _str[i].TrimEnd('\r'); recvData.Add(_str[i].Split(',')); } } return true; } catch (Exception e) { errorMsg = e.Message; MessageBox.Show("CSV文件读取失败:" + e.Message); return false; } } } /// /// 写入csv文件 /// /// 路径,如 @"D:\MESLog\ABC\" /// 名称,不带.csv /// 需要写入的数据 /// 是否拼接 /// public static bool WriteCsv(string _path, string _name, List _writeData, bool _append) { return WriteCsv(Path.Combine(_path, _name + ".csv"), _writeData, _append); } /// /// 写入csv文件 /// /// 路径,如 @"D:\MESLog\ABC\" /// 名称,不带.csv /// 需要写入的数据 /// 是否拼接 /// public static bool WriteCsv(string _path, string _name, List _writeData, bool _append, ref string errorMsg) { return WriteCsv(Path.Combine(_path, _name + ".csv"), _writeData, _append, ref errorMsg); } /// /// 写入csv文件 /// /// 文件全路径 /// 需要写入的数据 /// 是否拼接 /// public static bool WriteCsv(string fullfilePath, List writeData, bool append) { string errorMsg = ""; return WriteCsv(fullfilePath, writeData, append, ref errorMsg); } /// /// 写入csv文件【不使用Escaped转义】 /// /// 文件全路径 /// 需要写入的数据 /// 是否拼接 /// public static bool WriteCsv(string fullfilePath, List _writeData, bool _append, ref string errorMsg) { lock (thisLock) { try { if (fullfilePath.Length < 1) { return false; } string directoryName = System.IO.Path.GetDirectoryName(fullfilePath); //================判断文件夹是否存在,不存在就创建=====================================// DirectoryInfo directoryInfo = new DirectoryInfo(directoryName); if (!directoryInfo.Exists) { directoryInfo.Create(); } //=====================================================// if (!fullfilePath.Contains(".csv")) { errorMsg = "路径中没有.csv后缀"; return false; } string _tmPath = fullfilePath; using (StreamWriter write = new StreamWriter(_tmPath, _append, Encoding.Default)) { foreach (string[] strArr in _writeData) { write.WriteLine(string.Join(",", strArr)); } } return true; } catch (Exception e) { errorMsg = e.Message; MessageBox.Show("CSV文件写入失败:" + e.Message); return false; } } } /// /// 写入csv文件【使用双引号进行Escaped转义】 /// /// /// /// /// /// public static bool WriteCsvWithEscaped(string fullfilePath, List _writeData, bool _append, ref string errorMsg) { errorMsg = ""; if (_writeData == null) { errorMsg = "没有要写入的csv数据"; return false; } //修正所有元素 for (int i = 0; i < _writeData.Count; i++) { string[] dataArray = _writeData[i]; for (int j = 0; dataArray != null && j < dataArray.Length; j++) { dataArray[j] = ProcessPunctuationForCsv(dataArray[j]); } _writeData[i] = dataArray; } return WriteCsv(fullfilePath, _writeData, _append, ref errorMsg); } /// /// 处理csv文件中的双引号和逗号,使其在Excel中完美显示为一个单元格 /// 斯内科 20210321 /// /// /// private static string ProcessPunctuationForCsv(string srcStr) { if (srcStr == null) { return string.Empty; } bool quoteFlag = false;//是否添加过双引号 //如果存在双引号,需要将字符串的一个双引号 替换为 两个双引号。并且需要在字符串的前后加上双引号 if (srcStr.Contains("\"")) { srcStr = srcStr.Replace("\"", "\"\""); srcStr = "\"" + srcStr + "\""; quoteFlag = true; } //如果只存在逗号(不存在引号),将前后加引号即可 if (srcStr.Contains(",") && !quoteFlag) { srcStr = "\"" + srcStr + "\""; } return srcStr; } } } 窗体相关主要程序(忽略设计器自动生成的代码)如下: using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; namespace CsvFileEscapedDemo { public partial class FormCsvFileEscaped : Form { public FormCsvFileEscaped() { InitializeComponent(); } private void btnCsvWithoutEscaped_Click(object sender, EventArgs e) { //添加对 System.Web.Extensions的引用 System.Web.Script.Serialization.JavaScriptSerializer javaScriptSerializer = new System.Web.Script.Serialization.JavaScriptSerializer(); Employee employee = new Employee() { CoreId = 1, EmployeeName = "徐暮云", Address = "洛阳", ListSkills = new List() { "疾风怒涛", "混沌千秋", "寒溟化蛟" } }; string jsonString = javaScriptSerializer.Serialize(employee); string errorMsg = ""; List writeData = new List(); writeData.Add(new string[] { "编号", employee.CoreId.ToString() }); writeData.Add(new string[] { "姓名", employee.EmployeeName }); writeData.Add(new string[] { "地址", employee.Address }); writeData.Add(new string[] { "技能列表", string.Join(",", employee.ListSkills) }); writeData.Add(new string[] { "Json对象", jsonString }); string fileName = AppDomain.CurrentDomain.BaseDirectory + "sword5\\xumuyun.csv"; bool result = CsvUtil.WriteCsv(fileName, writeData, true, ref errorMsg); MessageBox.Show($"写入CSV文件的结果:{result}\n路径:{fileName}"); } private void btnCsvWithEscaped_Click(object sender, EventArgs e) { //添加对 System.Web.Extensions的引用 System.Web.Script.Serialization.JavaScriptSerializer javaScriptSerializer = new System.Web.Script.Serialization.JavaScriptSerializer(); Employee employee = new Employee() { CoreId = 3, EmployeeName = "皇甫朝云", Address = "成都", ListSkills = new List() { "轩辕服太虚", "持国护天" } }; string jsonString = javaScriptSerializer.Serialize(employee); string errorMsg = ""; List writeData = new List(); writeData.Add(new string[] { "编号", employee.CoreId.ToString() }); writeData.Add(new string[] { "姓名", employee.EmployeeName }); writeData.Add(new string[] { "地址", employee.Address }); writeData.Add(new string[] { "技能列表", string.Join(",", employee.ListSkills) }); writeData.Add(new string[] { "Json对象", jsonString }); string fileName = AppDomain.CurrentDomain.BaseDirectory + "sword5\\huangfuzhaoyun.csv"; bool result = CsvUtil.WriteCsvWithEscaped(fileName, writeData, true, ref errorMsg); MessageBox.Show($"写入CSV文件的结果:{result}\n路径:{fileName}"); } } } 程序运行结果:

            



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3