使用C# EPPlus导入CSV至Excel时数据末尾零丢失问题求助
问题根因
导入后数值末尾零被丢弃的核心原因是EPPlus的LoadFromText方法默认会自动识别字段类型,将符合数值规则的字符串转为double类型存入单元格。数值类型本身不存储末尾的占位零,即使提前给单元格设置了文本格式,只要值被识别为数值类型写入,末尾零就会被丢弃。
你原有实现存在两个明显错误:
- 手动给字段加双引号的逻辑只在逗号后补充了前引号,没有补全后引号,完全无法达到强制文本识别的效果,遇到字段内本身包含逗号的场景还会出现解析错位。
- 传入
LoadFromText的format参数没有配置字段类型规则,自动类型转换逻辑默认生效,导致提前设置的文本格式没有起到作用。
修复方案
方案1:正确配置LoadFromText的解析规则(改动最小)
保留原有整体流程,移除手动替换逗号加引号的逻辑,正确初始化文本导入格式配置,强制所有字段按字符串类型解析,示例代码如下:
string[] csvInputfile = File.ReadAllLines(filePathName); // 初始化导入格式配置 var format = new ExcelTextFormat { Delimiter = ',', // 核心配置:所有字段按字符串处理,关闭自动数值识别 DataTypes = Enumerable.Repeat(eDataTypes.String, 100).ToArray() }; for (int i = 0; i < csvInputfile.Length; i++) { ExcelWorksheet curWorksheet = excelPackage.Workbook.Worksheets.Add(csvInputfile[outerLoopCnt]); // 提前将整张工作表的单元格格式设为文本,必须在写入值前设置 curWorksheet.Cells.Style.Numberformat.Format = "@"; for (int j = 0; j < csvInputfile.Length; j++) { innerLoopCnt++; // 按配置的文本格式加载行内容,不会自动转换数值类型 curWorksheet.Cells[j + 1, 1].LoadFromText(csvInputfile[innerLoopCnt], format); if (innerLoopCnt + 1 >= csvInputfile.Length || csvInputfile[innerLoopCnt + 1] == "") { outerLoopCnt = innerLoopCnt + 2; innerLoopCnt += 2; break; } } if (innerLoopCnt >= csvInputfile.Length) { break; } } excelPackage.SaveAs(file);
方案2:逐字段手动写入(可控性最高)
完全绕开LoadFromText的自动解析逻辑,逐行拆分字段后直接给单元格赋值字符串,适合CSV格式规则简单的场景:
string[] csvInputfile = File.ReadAllLines(filePathName); for (int i = 0; i < csvInputfile.Length; i++) { ExcelWorksheet curWorksheet = excelPackage.Workbook.Worksheets.Add(csvInputfile[outerLoopCnt]); curWorksheet.Cells.Style.Numberformat.Format = "@"; for (int j = 0; j < csvInputfile.Length; j++) { innerLoopCnt++; string currentLine = csvInputfile[innerLoopCnt]; // 拆分当前行字段,注意:如果CSV存在字段内含逗号、双引号的复杂场景,不要直接用Split,建议用TextFieldParser或CsvHelper做专业CSV解析 string[] fields = currentLine.Split(','); // 逐单元格写入字符串值 for (int colIndex = 0; colIndex < fields.Length; colIndex++) { curWorksheet.Cells[j + 1, colIndex + 1].Value = fields[colIndex]; } if (innerLoopCnt + 1 >= csvInputfile.Length || csvInputfile[innerLoopCnt + 1] == "") { outerLoopCnt = innerLoopCnt + 2; innerLoopCnt += 2; break; } } if (innerLoopCnt >= csvInputfile.Length) { break; } } excelPackage.SaveAs(file);
注意事项:单元格文本格式必须在给单元格赋值前设置,如果先写入值再修改格式,值已经被转为数值类型,丢失的末尾零无法恢复。
内容的提问来源于stack exchange,提问作者bluejuggernaut
相关产品推荐
相关产品推荐

