当前位置:首页 > 行业动态 > 正文

如何用C高效读取Excel数据并同步至数据库?

C#可通过EPPlus或Microsoft.Office.Interop.Excel库读取Excel数据,支持解析单元格内容并转换为DataSet或对象集合,需处理文件格式兼容性及数据类型转换,结合ADO.NET可实现Excel与数据库的批量导入导出操作。

在开发过程中,经常需要将Excel表格作为数据源进行读取,以下是C#处理Excel数据的完整方案,采用主流的EPPlusNPOI两种库实现,并针对不同场景提供最佳实践。


准备工作

  1. 安装NuGet包:

    Install-Package EPPlus       # 适用于.xlsx格式(Office 2007+)
    Install-Package NPOI         # 支持.xls和.xlsx格式
  2. 引用命名空间:

    using OfficeOpenXml;        // EPPlus
    using NPOI.SS.UserModel;    // NPOI
    using System.Data.OleDb;    // OleDB方式

OleDB读取(传统方式)

适用于简单的数据导入,要求安装Microsoft Access Database Engine:

string connectionString = @"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:data.xlsx;
                          Extended Properties='Excel 12.0;HDR=YES;IMEX=1;'";
using (OleDbConnection conn = new OleDbConnection(connectionString))
{
    conn.Open();
    OleDbDataAdapter da = new OleDbDataAdapter("SELECT * FROM [Sheet1$]", conn);
    DataTable dt = new DataTable();
    da.Fill(dt);
    foreach (DataRow row in dt.Rows)
    {
        Console.WriteLine(row["姓名"] + " | " + row["成绩"]);
    }
}

注意:HDR=YES表示首行为列头,IMEX=1强制混合数据为文本


EPPlus高效处理(推荐)

现代Excel处理方案,支持LINQ操作:

FileInfo file = new FileInfo(@"C:data.xlsx");
using (ExcelPackage package = new ExcelPackage(file))
{
    ExcelWorksheet worksheet = package.Workbook.Worksheets[0];
    int rowCount = worksheet.Dimension.Rows;
    for (int row = 2; row <= rowCount; row++) 
    {
        string name = worksheet.Cells[row, 1].GetValue<string>();
        DateTime date = worksheet.Cells[row, 2].GetValue<DateTime>();
        double score = worksheet.Cells[row, 3].GetValue<double>();
        // 处理业务逻辑
        Console.WriteLine($"{name} 于 {date:yyyy-MM-dd} 获得 {score} 分");
    }
}

高级功能

  • 公式计算:worksheet.Calculate()
  • 条件格式读取:worksheet.Cells[row,col].Style.Font.Bold
  • 数据验证:worksheet.DataValidations

NPOI跨格式支持

同时兼容.xls和.xlsx文件:

using (FileStream fs = new FileStream("data.xls", FileMode.Open))
{
    IWorkbook workbook = WorkbookFactory.Create(fs);
    ISheet sheet = workbook.GetSheetAt(0);
    for (int row = 1; row <= sheet.LastRowNum; row++)
    {
        IRow currentRow = sheet.GetRow(row);
        ICell nameCell = currentRow.GetCell(0);
        ICell scoreCell = currentRow.GetCell(1);
        // 处理不同单元格类型
        string name = nameCell?.ToString() ?? "未知";
        double score = scoreCell?.CellType == CellType.Numeric 
                      ? scoreCell.NumericCellValue 
                      : 0;
    }
}

提示:使用CellType判断单元格类型可避免格式异常


常见问题解决方案

  1. 日期格式错误

    // EPPlus处理日期
    double oaValue = worksheet.Cells[row,2].GetValue<double>();
    DateTime date = DateTime.FromOADate(oaValue);
    // NPOI处理日期
    if (DateUtil.IsCellDateFormatted(cell))
        DateTime date = cell.DateCellValue;
  2. 大文件内存优化

    // EPPlus配置
    ExcelPackage.LicenseContext = LicenseContext.NonCommercial;
    var config = new ExcelReaderConfiguration()
    {
        UseCellCache = true  // 启用单元格缓存
    };
    // NPOI事件模型
    using (var stream = new FileStream("large.xlsx", FileMode.Open))
    {
        var reader = new XSSFReader(stream);
        var sheetIterator = reader.Sheets;
        while (sheetIterator.MoveNext())
        {
            var sheet = (XSSFSheet)reader.GetSheet(sheetIterator.Current);
            var rowIterator = sheet.GetRowEnumerator();
        }
    }
  3. 合并单元格处理

    // EPPlus方式
    var mergeCells = worksheet.MergedCells;
    foreach (var range in mergeCells)
    {
        ExcelRangeBase range = worksheet.Cells[range];
        string mergedValue = range.First().Text;
    }

注意事项

  1. 数据验证

    • 检查文件扩展名有效性
    • 验证用户上传权限
    • 设置最大文件尺寸限制
  2. 异常处理

    try {
        // 文件操作代码
    }
    catch (IOException ex) {
        // 处理文件占用异常
    }
    catch (InvalidOperationException ex) {
        // 处理格式错误
    }
  3. 版本兼容性
    | 文件格式 | 推荐库 | 特点 |
    |———-|————|————————|
    | .xlsx | EPPlus | 高性能,功能丰富 |
    | .xls | NPOI | 旧版兼容 |
    | 两者 | ClosedXML | 语法更简洁 |


引用说明

  • EPPlus官方文档:https://epplussoftware.com/
  • NPOI GitHub仓库:https://github.com/nissl-lab/npoi
  • Microsoft OleDB参考:https://learn.microsoft.com/odbc
0