在C#中移除CSV指定表头列并生成DataTable
从大型CSV生成指定列和数据类型的DataTable
需求说明
现有超过12000行的CSV文件,需生成DataTable,要求:
- 排除
Comment和Place列 - 保留列对应指定数据类型:
DateTime→DateTimeName→stringAge→double?(可空浮点数)Class→int
实现代码
以下是基于你现有代码的优化实现,兼顾数据类型转换和列过滤:
using System; using System.Collections.Generic; using System.Data; using System.IO; using System.Linq; public DataTable ConvertCsvToDataTable(string fileNameWithPath) { // 定义需要保留的列及其对应数据类型 var columnTypeMap = new Dictionary<string, Type> { {"DateTime", typeof(DateTime)}, {"Name", typeof(string)}, {"Age", typeof(double?)}, {"Class", typeof(int)} }; // 读取CSV所有行(若文件远超12万行,建议改用StreamReader逐行读取) List<string> lines = File.ReadAllLines(Path.ChangeExtension(fileNameWithPath, ".csv")).ToList(); if (lines.Count == 0) return new DataTable(); // 处理表头:分割并去除多余空格,找到目标列的索引 string[] headers = lines[0].Split(',').Select(h => h.Trim().Replace("-->", "").Trim()).ToArray(); var targetColumnIndices = new Dictionary<string, int>(); foreach (var colName in columnTypeMap.Keys) { int index = Array.IndexOf(headers, colName); if (index >= 0) targetColumnIndices.Add(colName, index); } // 初始化DataTable并添加列 DataTable dt = new DataTable(); foreach (var kvp in columnTypeMap) { dt.Columns.Add(kvp.Key, kvp.Value); } // 遍历数据行,解析并添加到DataTable for (int i = 1; i < lines.Count; i++) { string line = lines[i].Trim(); if (string.IsNullOrEmpty(line)) continue; string[] values = line.Split(',').Select(v => v.Trim()).ToArray(); DataRow row = dt.NewRow(); foreach (var kvp in targetColumnIndices) { string colName = kvp.Key; int index = kvp.Value; string value = values[index]; try { // 根据列类型转换值 switch (colName) { case "DateTime": row[colName] = DateTime.ParseExact(value, "dd/MM/yyyy", null); break; case "Name": row[colName] = string.IsNullOrEmpty(value) ? DBNull.Value : (object)value; break; case "Age": row[colName] = string.IsNullOrEmpty(value) ? DBNull.Value : (object)double.Parse(value); break; case "Class": row[colName] = int.Parse(value); break; } } catch (Exception ex) { // 处理转换异常,比如记录错误行号,或设为DBNull Console.WriteLine($"行{i+1}列{colName}转换失败:{ex.Message}"); row[colName] = DBNull.Value; } } dt.Rows.Add(row); } return dt; }
关键说明
- 列索引匹配:通过表头找到目标列的位置,避免因列顺序变动导致错误
- 数据类型转换:针对不同列做精准转换,处理可空类型和空值情况
- 异常处理:添加转换异常捕获,避免单个错误行导致整个流程中断
- 性能提示:如果CSV文件远大于当前规模(比如百万行),建议替换
File.ReadAllLines为StreamReader逐行读取,减少内存占用
内容的提问来源于stack exchange,提问作者Micheal
相关产品推荐
相关产品推荐

