NET.MVC:利用NPOI大数据的导入方式

7 篇文章 0 订阅
这篇博客介绍了如何在MVC应用中使用NPOI库高效导入大量数据到SQL数据库,避免了传统方式在处理大数据时的性能问题。通过创建内存流并利用SqlBulkCopy进行批量导入,显著提升了导入速度。同时,文章提供了详细的视图和控制器代码示例,展示了从Excel文件读取数据到匹配和验证学院、专业、年级、班级ID的完整流程。
摘要由CSDN通过智能技术生成

文献种类:专题技术文献;
开发工具与关键技术: Vs2015 C#
作者:Eric;年级:1901 ;撰写时间: 2020 年 9 月 23 日

MVC:利用NPOI大数据的导入方式

导入说明:
关于在MVC中用NPOI导入数据之前也有写过一篇,但那种方 式只适合数据比较小的情况,当导入数据大于1000条的时候,那 么那中方式的导入速度是很慢的,甚至会报错。而接下来这种原 理是利用SQL中的导入,所以就算你导入数据很庞大,甚至超过一万条到时候,也不用担心导入速度

视图代码:

 //NPOI大数据导入
function uploadExcelFile() {
    var fileExcel = $("#fileExcel").get(0).files[0];
    var formData = new FormData();
    formData.append("excelFile", fileExcel);

    var layerIndex = layer.load();
    $.ajax({
        url: "@Url.Content("~/BaseInfoManage/Student/ImportExcel2")",
        method: 'post',
        contentType: false,//让Ajax不指定数据类型
        processData: false,//让Ajax不对数据进行处理
        data: formData,
        success: function (jsonMsg) {
            layer.close(layerIndex);
            layer.alert(jsonMsg.Text);
            if (jsonMsg.State) {
                tabStudentSearch();//刷新表格

                $("#importStudentModal").modal("hide");//关闭模态框
            }
        }
    });
}

控制器代码:

1、导入模板的下载

 /// <summary>
/// 导入模板下载
/// </summary>
/// <returns></returns>
public ActionResult DownImportTemplate()
{
   string templatePath = Server.MapPath("~/Document/考生信息导入模板.xls");
   if (System.IO.File.Exists(templatePath))
   {
       return File(templatePath, "application/vnd.ms-excel", "考生信息导入模板.xls");
   }
   else
   {
       return Content("模板文件不存在");
   }
}

2、导入数据代码

public ActionResult ImportExcel2(HttpPostedFileBase excelFile)
{
    ReturnJson msg = new ReturnJson();
    try
    {
        //思路:
        //1、获取读取的文件;2、把文件转换为二进制数组;3、二进制数组转成内存流;4、利用NPOI把内存流中的数据读取成Excel
        //获取文件的后缀
        string fileExtension = Path.GetExtension(excelFile.FileName);
        //判断文件类型是否为指定的文件类型
        if (".xls".Equals(fileExtension) || ".XLS".Equals(fileExtension))
        {
            //声明二进制数组存放文件
            byte[] fileBytes = new byte[excelFile.ContentLength];
            //将传入的文件转化为二进制的数组存入fileBytes
            excelFile.InputStream.Read(fileBytes, 0, excelFile.ContentLength);
            //将二进制数组转化为内存流
            MemoryStream excelFileStream = new MemoryStream(fileBytes);
            //将内存流转化为工作簿
            NPOI.SS.UserModel.IWorkbook workbook = new HSSFWorkbook(excelFileStream);

            //判断工作簿中是否有工作表
            if (workbook.NumberOfSheets > 0)
            {
                //查询出 学院,专业,年级,班级 的信息:用来根据名称获取对应的ID
                List<SYS_Academe> dbAcademe = myModel.SYS_Academe.ToList();
                List<SYS_Specialty> dbSpecialty = myModel.SYS_Specialty.ToList();
                List<SYS_Grade> dbGrade = myModel.SYS_Grade.ToList();
                List<SYS_Class> dbClass = myModel.SYS_Class.ToList();

                //对象列表
                List<SYS_Student> listStudent = new List<SYS_Student>();

                //获取第一个工作表
                NPOI.SS.UserModel.ISheet sheet = workbook.GetSheetAt(0);
                //PhysicalNumberOfRows 获取的是物理行数,也就是不包括那些空行(隔行)的情况。
                //判断工作表中是否有数据
                if (sheet.PhysicalNumberOfRows > 0)
                {
                    //将数据先装到datatable中
                    // 定义datatable
                    DataTable dtExcel = new DataTable();

                    //获取标题行--- 第二行,索引为1;第一行是说明
                    NPOI.SS.UserModel.IRow rowHeader = sheet.GetRow(1);
                    /*
                      FirstCellNum:获取某行第一个单元格下标
                      LastCellNum:获取某行的列数
                      FirstRowNum:获取第一个实际行的下标
                      LastRowNum:获取最后一个实际行的下标
                    */
                    //获取表格列数  
                    int cellCount = rowHeader.LastCellNum;
                    //获取表格行数
                    int rowCount = sheet.LastRowNum + 1;

                    //创建dataTable中的列,循环添加标题行中各个单元格的值
                    for (int i = rowHeader.FirstCellNum; i < cellCount; i++)
                    {
                        //通过遍历行中的每一个单元格,获取标题行各个单元格的数据
                        DataColumn dtColumn = new DataColumn(rowHeader.GetCell(i).StringCellValue);
                        //将获取到的标题行的数据放到datatable中;
                        dtExcel.Columns.Add(dtColumn);
                    }

                    //读取Excel中的数据
                    //(sheet.FirstRowNum) 第一行是说明;第二行是标题;第三行开始才是数据信息
                    for (int i = (sheet.FirstRowNum) + 2; i < rowCount; i++)
                    {
                        //获取行(123...)数据
                        NPOI.SS.UserModel.IRow row = sheet.GetRow(i);//1
                        //创建DataTable行
                        DataRow dtRow = dtExcel.NewRow();
                        if (row != null)
                        {
                            //遍历excel中一行的所有单元格
                            for (int j = row.FirstCellNum; j < cellCount; j++)
                            {
                                if (row.GetCell(j) != null)
                                {
                                    dtRow[j] = row.GetCell(j).ToString();
                                }
                            }
                        }
                        //将填入数据的dtRow添入dtExcel
                        dtExcel.Rows.Add(dtRow);
                    }


                    //==在dtExcel 中添加学院ID 专业ID 年级ID 班级ID的列
                    dtExcel.Columns.Add("academeID", typeof(int));
                    dtExcel.Columns.Add("gradeID", typeof(int));
                    dtExcel.Columns.Add("specialtyID", typeof(int));
                    dtExcel.Columns.Add("classID", typeof(int));


                    //遍历 根据名称匹配 学院ID 专业ID 年级ID 班级ID
                    for (int i = 0; i < dtExcel.Rows.Count; i++)
                    {
                        DataRow row = dtExcel.Rows[i];

                        //获取学院ID
                        //通过dataTable中的AcademeName到dbAcademe中查找相应的AcademeID
                        string academeName = row["学院"].ToString().Trim();
                        int academeID = 0;
                        try
                        {
                            academeID = dbAcademe.Where(p => p.academeName == academeName)
                                .Single().academeID;
                            row["academeID"] = academeID;
                        }
                        catch (Exception e)
                        {
                            Debug.WriteLine(e);
                            msg.Text = string.Format("第{0}学生数据 学院 无法匹配", i + 1);
                            return Json(msg, JsonRequestBehavior.AllowGet);
                        }

                        //获取专业id和名称
                        //根据学院ID和专业名称获取相应的专业ID
                        string specialtyName = row["专业"].ToString().Trim();
                        int specialtyID = 0;
                        try
                        {
                            specialtyID = dbSpecialty.Where(p => p.academeID == academeID 
                                && p.specialtyName == specialtyName)
                                .Single().specialtyID;
                            row["specialtyID"] = specialtyID;
                        }
                        catch (Exception e)
                        {
                            Debug.WriteLine(e);
                            msg.Text = string.Format("第{0}学生数据 专业 无法匹配", i + 1);
                            return Json(msg, JsonRequestBehavior.AllowGet);
                        }

                        //获取年级ID 和名称
                        //根据学院ID以及年级名称获取相应的年级ID
                        string gradeName = row["年级"].ToString().Trim();
                        int gradeID = 0;
                        try
                        {
                            gradeID = dbGrade.Where(p => p.academeID == academeID 
                                && p.gradeName == gradeName)
                                .Single().gradeID;
                            row["gradeID"] = gradeID;
                        }
                        catch (Exception e)
                        {
                            Debug.WriteLine(e);
                            msg.Text = string.Format("第{0}学生数据 年级 无法匹配", i + 1);
                            return Json(msg, JsonRequestBehavior.AllowGet);
                        }

                        //获取 班级ID和名称
                        //根据学院ID&专业ID&班级名称获取班级ID
                        string className = row["班级"].ToString().Trim();
                        try
                        {
                            row["classID"] = dbClass.Where(p => p.academeID == academeID 
                                    && p.specialtyID == specialtyID &&
                                    p.gradeID == gradeID && p.className == className)
                                    .Single().classID;
                        }
                        catch (Exception e)
                        {
                            Debug.WriteLine(e);
                            msg.Text = string.Format("第{0}学生数据 班级 无法匹配", i + 1);
                            return Json(msg, JsonRequestBehavior.AllowGet);
                        }

                        if (!IdCardHelper.CheckIdCard(row["身份证号"].ToString().Trim()))
                        {
                            msg.Text = string.Format("第{0}学生数据 身份证号不正确", i + 1);
                            return Json(msg, JsonRequestBehavior.AllowGet);
                        }
                    }

                    //数据库连接字符串 data source=(local);initial catalog=SchoolManageSystem;user id=sa;password=sa123
                    string strConnect = "Data Source=(local);Initial Catalog=SchoolManageSystem;User ID=sa;Password=sa123";
                    //使用  System.Data.SqlClient.SqlBulkCopy 
                    using (SqlBulkCopy bulkCopy = new SqlBulkCopy(strConnect, SqlBulkCopyOptions.KeepIdentity | SqlBulkCopyOptions.UseInternalTransaction))
                    {
                        //1、指定数据导入的目标表;
                        bulkCopy.DestinationTableName = "dbo.[SYS_Student]";
                        //2、设置数据源(dtExcel)中的列名与目标表的字段的映射关系
                        bulkCopy.ColumnMappings.Add("academeID", "academeID");
                        bulkCopy.ColumnMappings.Add("gradeID", "gradeID");
                        bulkCopy.ColumnMappings.Add("specialtyID", "specialtyID");
                        bulkCopy.ColumnMappings.Add("classID", "classID");
                        bulkCopy.ColumnMappings.Add("姓名", "studentName");
                        bulkCopy.ColumnMappings.Add("性别", "studentSex");
                        bulkCopy.ColumnMappings.Add("身份证号", "studentIDNum");
                        bulkCopy.ColumnMappings.Add("学号", "studentNumber");
                        //3、将数据源数据写入到目标表中
                        bulkCopy.WriteToServer(dtExcel);
                    }

                    msg.State = true;
                    msg.Text = "导入成功";
                }
                else
                {
                    msg.Text = "工作表为空!";
                }
            }
            else
            {
                msg.Text = "工作簿中没有工作表!";
            }
        }
        else
        {
            msg.Text = "选中的文件类型不正确!";
        }
    }
    catch (Exception e)
    {
        msg.Text = "上传失败,类型不对应;请检查是否有工作表,是否有数据,是否按照模板填写!";
    }
    return Json(msg, JsonRequestBehavior.AllowGet);
}

注意:书写代码之前一定先引用NPOI插件,如果找不到可以直接在VS插件库中下载
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Eric-x

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值