如何使用SpreadsheetLight与C#高效清除表格所有单元格多余空格?
关于SpreadsheetLight清除Excel单元格多余空格的问题解答
原代码的可行性与效率分析
可行性
你的代码仅能在输出时临时去除空格,但存在两个局限:
- 没有修改原Excel文件的单元格内容,只是在
Console.WriteLine时做了Trim,清理效果不会保存到文件中。 - 日期(j=3、5)和数字(j=4)类型的单元格本身是数值型,转字符串后默认不会带前后空格,这里的
Trim()属于无用操作。
效率
这段代码的效率很低:
- 嵌套循环逐单元格调用
GetCellValueXXX方法,每次调用都会访问底层OpenXML对象,频繁IO操作会导致大文件(万行级)处理速度极慢。 - 没有批量处理逻辑,逐单元格操作的性能开销远高于批量读取。
高效的解决方案
根据你的需求分两种场景处理:
场景1:仅读取时清理空格(无需修改原文件)
直接将工作表批量读取为DataTable,再对字符串列批量Trim,性能比逐单元格读取提升数倍:
SLDocument sl1 = new SLDocument(@"D:\sample.xlsx", "Sheet1"); SLWorksheetStatistics st = sl1.GetWorksheetStatistics(); // 批量读取整个工作表到DataTable DataTable dt = sl1.GetWorksheetAsDataTable(1, 1, st.EndRowIndex, st.EndColumnIndex); // 仅对字符串列执行Trim foreach (DataColumn col in dt.Columns) { if (col.DataType == typeof(string)) { foreach (DataRow row in dt.Rows) { if (row[col] != DBNull.Value) { row[col] = ((string)row[col]).Trim(); } } } } // 后续可直接使用清理后的DataTable做业务处理 foreach (DataRow row in dt.Rows) { foreach (var cellValue in row.ItemArray) { Console.WriteLine(cellValue); } }
场景2:清理后写回原文件
同样用DataTable中转,清理后重新写入工作表:
SLDocument sl1 = new SLDocument(@"D:\sample.xlsx", "Sheet1"); SLWorksheetStatistics st = sl1.GetWorksheetStatistics(); // 读取工作表到DataTable DataTable dt = sl1.GetWorksheetAsDataTable(1, 1, st.EndRowIndex, st.EndColumnIndex); // 清理字符串列空格 foreach (DataColumn col in dt.Columns) { if (col.DataType == typeof(string)) { foreach (DataRow row in dt.Rows) { if (row[col] != DBNull.Value) { row[col] = ((string)row[col]).Trim(); } } } } // 清空原工作表并写入清理后的数据 sl1.DeleteWorksheet("Sheet1"); sl1.AddWorksheet("Sheet1"); // 从第2行开始写入(跳过表头),不导入DataTable列名 sl1.ImportDataTable(2, 1, dt, false); // 保存到新文件或覆盖原文件 sl1.SaveAs(@"D:\cleaned_sample.xlsx");
额外优化建议
- 若已知哪些列是字符串类型,可直接指定列处理,无需遍历所有列,进一步提升效率。
- 超大型文件可分块读取(比如每次读1000行),避免内存占用过高。
内容的提问来源于stack exchange,提问作者Jayanta_KMC
相关产品推荐
相关产品推荐

