导入Excel文件上传数据到SQL服务器的通用方法

本文介绍了如何通过NPOI库读取Excel文件,创建DataTable,然后利用SQL的BulkCopy方法将数据快速上传到数据库,对比逐条插入和EntityFramework,这种方法具有更高的效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

         实现原理,通过读取上传Excel文件的标题行,创建对应的DataTable标题列(DataColumn),然后遍历Excel表格的数据行,添加到DataTable的数据行(DataRow),生成DataTable后,用SQL的BulkCopy方法,一次性上传到数据服务器,效率比生成逐条Insert into语句和利用DataTable生成List实体后用EF框架更新要高。

1.读取Excel,需要引用NPOI库

        public static DataTable getDataTableFromExcel(string excelFilePath)
        {
            IWorkbook workbook;
            DataTable dt=new DataTable();
            try
            {
                using (FileStream fs = new FileStream(excelFilePath, FileMode.Open, FileAccess.Read))
                {
                    string fileExt = Path.GetExtension(excelFilePath).ToLower(); //获得Excel文件的扩展名,再判断用哪种方式打开
                    if (fileExt == ".xls") workbook = new HSSFWorkbook(fs);
                    else if (fileExt == ".xlsx") workbook = new XSSFWorkbook(fs);
                    else workbook = null;
                }
            }
            catch (Exception)
            {
                //这里可以抛出异常纪录
                throw;
            }
            ISheet sheet = workbook.GetSheetAt(0);//获得Excel的第一个工作表
            IRow headerRow = sheet.GetRow(0);//获得Excel的第一行
            int cellCount = headerRow.LastCellNum;//从第一行获取字段(列)数
            int rowCount = sheet.LastRowNum+1;  //获得行数
            //循环添加DataTabel对应的标题列
            for (int i = headerRow.FirstCellNum; i < cellCount; i++)
            {
                DataColumn col = new DataColumn(headerRow.GetCell(i).StringCellValue);
                dt.Columns.Add(col);
            }
            //循环添加行数据到DataTable中
            for (int i = (sheet.FirstRowNum+1); i < rowCount; i++)
            {
                IRow row = sheet.GetRow(i);
                DataRow drow = dt.NewRow();
                if (row != null)
                {
                    for (int j = row.FirstCellNum; j < cellCount; j++)
                    {
                        ICell cell = row.GetCell(j);
                        if (cell != null)
                        {
                            drow[j] = getCellValue(cell);
                        }
                    }
                }
                dt.Rows.Add(drow);
            }
            return dt;
        }

2.使用SQL的BulkCopy,需要数据库中原表名和DataTable的表名保持一致,可以在上传Excel表时先做个逻辑判断,创建一个事务,用于上传失败时的回滚

public static bool sqlBulkcopyToServer(string ServerTableName, DataTable dt)
        {
            string connString = System.Web.Configuration.WebConfigurationManager.ConnectionStrings["connStr"].ConnectionString;
            bool isSucess = false;
            using (SqlConnection conn = new SqlConnection(connString))
            {
                conn.Open();
                SqlTransaction trans = conn.BeginTransaction();
                using (SqlBulkCopy sbc = new SqlBulkCopy(conn, SqlBulkCopyOptions.CheckConstraints,trans))
                {
                    try
                    {
                        sbc.DestinationTableName = ServerTableName;
                        sbc.BatchSize = 20000;       //每一批次执行的最大行数
                        sbc.BulkCopyTimeout = 0;     //不限制执行时间
                        int cols = dt.Columns.Count;
                        for (int i = 0; i < cols; i++)
                        {
                            string colName = dt.Columns[i].ColumnName;
                            sbc.ColumnMappings.Add(colName, colName);//要求目标数据库表字段名与DataTable字段名一致,可用下载模板限制
                        }
                        sbc.WriteToServer(dt);
                        trans.Commit();
                        isSucess = true;
                    }
                    catch (Exception ex)
                    {
                        trans.Rollback();
                        throw ex;
                    }
                    finally
                    {
                        conn.Close();
                    }
                }
            }
            return isSucess;
        }

一个将excel文件导入到SQLServer表中的程序 一 双击Input.exe运行程序,将弹出一个窗口,这时请你在"数据库名"后面的 输入栏中输入数据库名(如果是千方百剂就是输入帐套名).你如果没对数 据库的登录进行特殊修改的话,那"用户名和密码"就没必要修改了. 二 填好以上输入框后,真接单击"连接数据库",如果连接成功,将弹出"数据库 连接成功,你现在可以导入数据"的对话框,你按"OK"后将弹出新的一个数据 导入的窗口. 三 在这个窗口上单击"打开EXCEL文件"按钮,然后选择你要导入Excel文件, 按打开(这时如果你数据比较多的话你可能要多等一会儿时间),之后就弹 出一个让你选择Excel工作区的窗口,你可以在下拉框中选择你数据所在的 Excel工作区了.选完以后按确定,你可以看到你Excel里的数据已经在"Excel 数据信息"里面了.而且还可以看到多了一列"不导入"的选项了.你如果哪一行 的数据导入的话你可以打勾,这一行将不被导入. 四 做完以上三步后,请在"表名"后面的下拉框中选择你所要导入的表的名称. 选完后,你得到"数据转换信息如下"这一栏配置数据转换的对应关系. 五 双击Excel字段处从下拉框中选择excel的列,双击表字段处从下拉框中选 择SQL表的列,然后看这列是否是"关键字",是的话打勾,不是不打勾.选择 完第一行后,就按方向键的向下键,继续第二行的选择,直到配置完Excel列 和表字段的对应关系为止. 六 按"导入数据"按钮系统会自动将页面转到"转换信息"这一页面.你将可以看 到第几行导入成功,或第几行导入失改的信息.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值