Asp.Net使用Npoi导入导出Excel的方法
在Asp.Net应用程序中处理Excel文件是常见需求,NPOI作为免费、开源且强大的.NET库,完美支持xls与xlsx格式,为数据导入导出提供了高效解决方案。

环境准备与基础配置
-
安装NPOI库
通过NuGet包管理器安装必需包:Install-Package NPOI Install-Package NPOI.OOXML # 支持xlsx格式 Install-Package NPOI.OpenXml4Net # 依赖项
-
引用命名空间
using NPOI.SS.UserModel; using NPOI.XSSF.UserModel; // xlsx处理 using NPOI.HSSF.UserModel; // xls处理 using System.IO;
Excel数据导出实战(DataTable → Excel文件)
public void ExportToExcel(DataTable dataTable, string filePath)
{
IWorkbook workbook;
// 根据扩展名判断创建xls或xlsx工作簿
if (Path.GetExtension(filePath).Equals(".xlsx", StringComparison.OrdinalIgnoreCase))
workbook = new XSSFWorkbook();
else
workbook = new HSSFWorkbook();
ISheet sheet = workbook.CreateSheet("Sheet1");
// 创建标题行
IRow headerRow = sheet.CreateRow(0);
for (int i = 0; i < dataTable.Columns.Count; i++)
{
headerRow.CreateCell(i).SetCellValue(dataTable.Columns[i].ColumnName);
}
// 填充数据行
for (int rowIdx = 0; rowIdx < dataTable.Rows.Count; rowIdx++)
{
IRow dataRow = sheet.CreateRow(rowIdx + 1);
for (int colIdx = 0; colIdx < dataTable.Columns.Count; colIdx++)
{
dataRow.CreateCell(colIdx).SetCellValue(dataTable.Rows[rowIdx][colIdx].ToString());
}
}
// 自适应列宽(关键优化)
for (int i = 0; i < dataTable.Columns.Count; i++)
{
sheet.AutoSizeColumn(i);
}
// 写入文件流
using (FileStream fs = new FileStream(filePath, FileMode.Create))
{
workbook.Write(fs);
}
}
关键优化点:
- 格式自适应:根据文件扩展名自动选择HSSF(xls)或XSSF(xlsx)工作簿
- 性能提升:使用
AutoSizeColumn自动调整列宽提升可读性 - 内存管理:严格使用
using语句确保文件流及时释放
Excel数据精准导入(Excel文件 → DataTable)
public DataTable ImportFromExcel(string filePath, bool hasHeader = true)
{
using (FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read))
{
IWorkbook workbook;
// 根据文件头判断格式
if (Path.GetExtension(filePath).Equals(".xlsx", StringComparison.OrdinalIgnoreCase))
workbook = new XSSFWorkbook(fs);
else
workbook = new HSSFWorkbook(fs);
ISheet sheet = workbook.GetSheetAt(0); // 读取第一个工作表
DataTable dataTable = new DataTable();
IRow headerRow = sheet.GetRow(0);
int cellCount = headerRow.LastCellNum;
// 构建DataTable列结构
for (int i = 0; i < cellCount; i++)
{
string columnName = hasHeader ?
headerRow.GetCell(i)?.ToString() : $"Column{i}";
dataTable.Columns.Add(columnName ?? $"Column{i}");
}
// 确定数据起始行(是否跳过标题行)
int startRow = hasHeader ? 1 : 0;
for (int rowIdx = startRow; rowIdx <= sheet.LastRowNum; rowIdx++)
{
IRow row = sheet.GetRow(rowIdx);
if (row == null) continue;
DataRow dataRow = dataTable.NewRow();
for (int colIdx = 0; colIdx < cellCount; colIdx++)
{
dataRow[colIdx] = row.GetCell(colIdx)?.ToString() ?? string.Empty;
}
dataTable.Rows.Add(dataRow);
}
return dataTable;
}
}
异常处理重点:
- 空行跳过:遇到空行自动跳过避免空引用异常
- 空单元格处理:使用操作符安全访问单元格
- 格式智能识别:通过文件扩展名自动匹配处理引擎
进阶技巧与性能优化
-
大文件分块处理

// 使用SXSSFWorkbook处理百万级数据 SXSSFWorkbook workbook = new SXSSFWorkbook(-1); // 启用临时文件缓冲 // 每写入100行刷新磁盘缓存 workbook.SetCompressTempFiles(true);
-
单元格样式深度定制
ICellStyle headerStyle = workbook.CreateCellStyle(); headerStyle.FillForegroundColor = IndexedColors.Grey25Percent.Index; headerStyle.FillPattern = FillPattern.SolidForeground; IFont font = workbook.CreateFont(); font.FontName = "微软雅黑"; font.IsBold = true; headerStyle.SetFont(font); // 应用样式到标题行 foreach (ICell cell in headerRow.Cells) { cell.CellStyle = headerStyle; } -
公式计算支持
cell.SetCellFormula("SUM(B2:B10)"); // 设置计算公式 // 触发公式重新计算 IFormulaEvaluator evaluator = workbook.GetCreationHelper().CreateFormulaEvaluator(); evaluator.EvaluateAll();
常见陷阱与解决方案
-
内存溢出问题
- 场景:处理100MB+的xlsx文件
- 方案:改用
SXSSFWorkbook流式处理SXSSFWorkbook wb = new SXSSFWorkbook(100); // 内存保留100行
-
日期格式错乱
- 根源:Excel内部以浮点数存储日期
- 修复:
if (DateUtil.IsCellDateFormatted(cell)) { DateTime dateValue = cell.DateCellValue; }
-
字体渲染异常

- 现象:Linux环境中文乱码
- 方案:显式注册字体
Environment.SetEnvironmentVariable("FONTCONFIG_PATH", "/usr/share/fonts");
关键技术指标对比
| 处理方式 | 10000行耗时 | 内存峰值 | 功能完整性 |
|—————-|————-|———-|————|
| NPOI (XSSF) | 1.8s | 210MB | ★★★★☆ |
| NPOI (SXSSF) | 2.1s | 45MB | ★★★★☆ |
| EPPlus | 1.5s | 190MB | ★★★★☆ |
| OpenXML SDK | 3.2s | 60MB | ★★☆☆☆ |
NPOI在Asp.Net中实现了Excel处理的高自由度与深度控制,特别适合需要精细操作单元格、公式或处理旧版xls的场景,当您需要处理10万行以上的数据时,是否考虑过采用分页加载机制?在实际项目中您遇到的最棘手的Excel导入导出问题是什么?欢迎分享您的实战经验!
原创文章,作者:世雄 - 原生数据库架构专家,如若转载,请注明出处:https://idctop.com/article/26692.html