You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何在ASP.NET中从指定IP路径上传多Sheet Excel至数据库分表存储

嘿,这个需求在ASP.NET里完全可以搞定,我给你拆解成几个核心步骤,每个步骤都带实际代码,你跟着来就行:

1. 先搞定依赖和前置准备

首先得选个靠谱的Excel操作库,我推荐EPPlus——它对.NET友好,支持.xlsx格式,而且免费(非商用场景)。你可以通过NuGet安装:

Install-Package EPPlus

或者用.NET CLI命令:

dotnet add package EPPlus

另外有个非常关键的点:你要访问的指定IP路径(比如\\192.168.1.100\SharedFiles\data.xlsx)是网络共享目录,所以ASP.NET应用池的运行账号必须有这个共享目录的读取权限。不然会直接报权限不足的错误,记得去共享文件夹的权限设置里添加应用池账号(比如IIS AppPool\你的应用池名称)并赋予读取权限。

2. 读取指定IP路径下的Excel文件

直接用网络共享路径的格式(\\[IP]\[共享文件夹]\[文件名])就能访问,然后用EPPlus加载文件:

using OfficeOpenXml;
using System.IO;

// 替换成你的实际IP共享路径
string excelFilePath = @"\\192.168.1.100\SharedFiles\SampleData.xlsx";

// EPPlus 5+版本需要设置LicenseContext,非商用选NonCommercial
ExcelPackage.LicenseContext = LicenseContext.NonCommercial;

try
{
    // 加载Excel文件
    using (var package = new ExcelPackage(new FileInfo(excelFilePath)))
    {
        // 这里后续处理每个Sheet
        ProcessExcelSheets(package);
    }
}
catch (FileNotFoundException)
{
    // 处理文件不存在的情况
    Console.WriteLine("指定路径下的Excel文件不存在");
}
catch (UnauthorizedAccessException)
{
    // 处理权限不足的情况
    Console.WriteLine("没有访问共享目录的权限,请检查权限设置");
}
3. 遍历所有Sheet并读取数据

假设Excel的每个Sheet对应数据库里的一张表(如果Sheet名和表名不一致,可以做个映射字典),我们遍历每个Sheet,把数据转换成实体类或者DataTable:

先定义对应数据库表的实体类(比如Sheet名为Users,对应数据库Users表):

public class User
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string Email { get; set; }
}

然后编写处理Sheet的方法:

private void ProcessExcelSheets(ExcelPackage package)
{
    // 如果Sheet名和表名不一致,这里可以做映射
    var sheetToTableMap = new Dictionary<string, string>
    {
        {"用户信息", "Users"},
        {"订单记录", "Orders"}
    };

    foreach (var worksheet in package.Workbook.Worksheets)
    {
        // 获取对应的数据库表名
        string tableName = sheetToTableMap.ContainsKey(worksheet.Name) 
            ? sheetToTableMap[worksheet.Name] 
            : worksheet.Name;

        int rowCount = worksheet.Dimension.Rows;
        int colCount = worksheet.Dimension.Columns;

        // 跳过表头(假设第一行是表头)
        for (int row = 2; row <= rowCount; row++)
        {
            switch (tableName)
            {
                case "Users":
                    var user = new User
                    {
                        Id = int.TryParse(worksheet.Cells[row, 1].Text, out int id) ? id : 0,
                        Name = worksheet.Cells[row, 2].Text,
                        Email = worksheet.Cells[row, 3].Text
                    };
                    // 插入到数据库
                    InsertUserToDb(user);
                    break;
                case "Orders":
                    // 同理处理Orders表的实体和插入逻辑
                    break;
                // 其他表依次添加case
            }
        }
    }
}
4. 将数据插入到对应数据库表

这里给你两种常用方式,选适合你的就行:

4.1 使用EF Core(简洁易维护)

先配置你的DbContext:

using Microsoft.EntityFrameworkCore;

public class AppDbContext : DbContext
{
    public DbSet<User> Users { get; set; }
    public DbSet<Order> Orders { get; set; }

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        // 替换成你的数据库连接字符串
        optionsBuilder.UseSqlServer("Server=.;Database=YourDb;Trusted_Connection=True;");
    }
}

然后编写插入方法,为了性能,建议批量插入(先收集数据再一次性提交):

private void InsertUserToDb(User user)
{
    using (var context = new AppDbContext())
    {
        context.Users.Add(user);
        context.SaveChanges();
    }

    // 如果是批量插入,先把所有User加到List<User> usersList里,再用:
    // context.Users.AddRange(usersList);
    // context.SaveChanges();
}

4.2 使用ADO.NET(适合底层控制或大数据量)

如果数据量很大,用SqlBulkCopy批量插入效率更高,先把Sheet数据转成DataTable,再导入:

private DataTable ConvertSheetToDataTable(ExcelWorksheet worksheet)
{
    DataTable dt = new DataTable();
    int rowCount = worksheet.Dimension.Rows;
    int colCount = worksheet.Dimension.Columns;

    // 添加列(表头)
    for (int col = 1; col <= colCount; col++)
    {
        dt.Columns.Add(worksheet.Cells[1, col].Text);
    }

    // 添加行数据
    for (int row = 2; row <= rowCount; row++)
    {
        DataRow dr = dt.NewRow();
        for (int col = 1; col <= colCount; col++)
        {
            dr[col - 1] = worksheet.Cells[row, col].Text;
        }
        dt.Rows.Add(dr);
    }
    return dt;
}

// 批量插入方法
private void BulkInsertToTable(string tableName, DataTable dataTable)
{
    string connectionString = "Server=.;Database=YourDb;Trusted_Connection=True;";
    using (var conn = new SqlConnection(connectionString))
    {
        conn.Open();
        using (var bulkCopy = new SqlBulkCopy(conn))
        {
            bulkCopy.DestinationTableName = tableName;
            // 如果DataTable列名和数据库列名一致,自动映射,否则手动添加ColumnMappings
            foreach (DataColumn col in dataTable.Columns)
            {
                bulkCopy.ColumnMappings.Add(col.ColumnName, col.ColumnName);
            }
            bulkCopy.WriteToServer(dataTable);
        }
    }
}
5. 几个避坑提醒
  • 数据验证:读取Excel数据时一定要做格式校验(比如用int.TryParse代替直接int.Parse),避免因为Excel里的脏数据导致程序崩溃。
  • Excel格式兼容:EPPlus只支持.xlsx,如果是旧的.xls格式,建议换成NPOI库来处理。
  • 性能优化:如果Excel数据量超过1万条,一定要用批量插入(EF的AddRange或者SqlBulkCopy),逐条插入会慢到离谱。

内容的提问来源于stack exchange,提问作者Geetha

火山引擎 最新活动