EPPlus LoadFromText解析CSV含&符号重复键异常解决方案咨询
解决EPPlus LoadFromText解析含重复&值CSV时的重复键异常
这个问题我之前碰到过,核心原因是EPPlus的LoadFromText方法在内部处理数据时,即便你指定了hasHeaderRow: false,某些场景下还是会尝试生成一个内部列映射字典。当数据行里出现重复内容(比如你例子里的两个David & Goliath),就会触发"重复键已添加"的异常——这其实是EPPlus结合特定区域文化设置时容易出现的小问题。
不用修改原始CSV的话,有两个可靠的解决方案:
方案1:手动解析CSV并逐行写入Excel
绕过LoadFromText,自己控制CSV的读取和Excel单元格的填充逻辑,完全避开EPPlus内部的映射冲突:
var format = new ExcelTextFormat(); format.Delimiter = ';'; format.Encoding = System.Text.Encoding.UTF8; format.Culture = System.Globalization.CultureInfo.GetCultureInfo("pt-pt"); using (ExcelPackage package = new ExcelPackage(new FileInfo(excelFilePath))) { ExcelWorksheet worksheet = package.Workbook.Worksheets.Add(worksheetsName); // 手动读取CSV文件内容 var csvLines = File.ReadAllLines(fileName, format.Encoding); int currentRow = 1; foreach (var line in csvLines) { // 按分隔符拆分每行(如果字段包含带分隔符的引号内容,建议用TextFieldParser替代Split) var cellValues = line.Split(format.Delimiter); int currentCol = 1; foreach (var value in cellValues) { worksheet.Cells[currentRow, currentCol].Value = value; currentCol++; } currentRow++; } package.Save(); }
如果你的CSV存在带引号的特殊字段(比如"David; Goliath"),用Microsoft.VisualBasic.FileIO.TextFieldParser解析会更严谨:
using (var parser = new Microsoft.VisualBasic.FileIO.TextFieldParser(fileName, format.Encoding)) { parser.TextFieldType = Microsoft.VisualBasic.FileIO.FieldType.Delimited; parser.SetDelimiters(format.Delimiter.ToString()); parser.HasFieldsEnclosedInQuotes = true; // 支持解析带引号的字段 int currentRow = 1; while (!parser.EndOfData) { var cellValues = parser.ReadFields(); int currentCol = 1; foreach (var value in cellValues) { worksheet.Cells[currentRow, currentCol].Value = value; currentCol++; } currentRow++; } }
方案2:调整EPPlus解析配置,禁用内部列映射
通过明确设置ExcelTextFormat的属性,让EPPlus放弃生成内部列映射字典:
var format = new ExcelTextFormat(); format.Delimiter = ';'; format.Encoding = System.Text.Encoding.UTF8; format.Culture = System.Globalization.CultureInfo.GetCultureInfo("pt-pt"); format.FirstRowIsHeader = false; // 强制声明第一行不是表头 using (ExcelPackage package = new ExcelPackage(new FileInfo(excelFilePath))) { ExcelWorksheet worksheet = package.Workbook.Worksheets.Add(worksheetsName); // 保持hasHeaderRow为false,同时不生成任何Table样式 worksheet.Cells["A1"].LoadFromText(new FileInfo(fileName), format, OfficeOpenXml.Table.TableStyles.None, false); worksheet.Cells.AutoFitColumns(); // 可选:自动调整列宽 package.Save(); }
不过这个方案的稳定性依赖EPPlus版本,旧版本可能依然存在问题,优先推荐方案1。
内容的提问来源于stack exchange,提问作者user995219
相关产品推荐
相关产品推荐

