Excel数据的导入就是相当于批量的新增,可以快速的添加多条数据。
给导入按钮一个点击事件,打开导入的模态框
下载模板文件
点击下载按钮可以下载文件的功能
操作如下:
首先要把模板放到项目中对应的目录下,获取到文件的物理路径
定义一个方法,返回模板文件路径
例:
页面调用模板下载的方法
下载好模板之后,可以在下载的模板中编写数据,再保存。选择写好数据的文件,然后上传
在页面中定义一个方法上传文件
先获取要上传的Excel文件
例:var fileExcel = $("#fileExcel").get(0).files[0];
再传参
例:var fmData = new FormData();
fmData.append("excelFile", fileExcel);
最后发送请求
批量导入数据的思路
- 获取读取的文件->判断数据类型是否正确;
- string fileExtension = Path.GetExtension(excelFile.FileName);
- if (".xls".Equals(fileExtension) || ".XLS".Equals(fileExtension))
- 把文件转换为二进制数组
- byte[] fileBytes = new byte[excelFile.ContentLength];
- excelFile.InputStream.Read(fileBytes, 0, excelFile.ContentLength);
- 二进制数组转成内存流;
- MemoryStream excelFileStream = new MemoryStream(fileBytes);
- 利用NPOI把内存流中的数据读取成Excel
- IWorkbook workbook = new HSSFWorkbook(excelFileStream);
注:需要引用NPOI。
NPOI是指一个构建POI3.x版本之上的一个程序,可以在没有安装office的情况下对Word或Excel文档进行读写操作。
NPOI是一个开源的C#读写Excel、Word等微软OLE2组件文档的项目
需要 判断工作簿中是否有工作表 NumberOfSheets获取工作簿中有多少工作表
- if (workbook.NumberOfSheets > 0)
创建对象列表——用于存放要保存的数据
List<SYS_Student> listStudent = new List<SYS_Student>();
获取第一张工作表
- NPOI.SS.UserModel.ISheet sheet = workbook.GetSheetAt(0);
判断工作表中是否有数据
PhysicalNumberOfRows 获取的时物理行数,不包括那些空行(隔行)的情况
- if (sheet.PhysicalNumberOfRows > 0)
将Excel表格数据放到DataTable中
先定义DataTable
- DataTable dtExcel = new DataTable();
获取标题行
NPOI.SS.UserModel.IRow rowHeader = sheet.GetRow();//行的接口 GetRow(索引)
FirstCellNum:获取某行第一个单元格下标
LastCellNum:获取某行的列数
FirstRowNum:获取第一个实际行的下标
LastRowNum:获取最后一个实际行的下标
获取表格的列数
int cellCount = rowHeader.LastCellNum;
获取表格的行数
int rowCount = sheet.LastRowNum + 1; 下标比实际行数小一,所以后面+1
循环添加标题行中各个单元格的值 -- 相当于定义数据库表的字段
- for(var i = rowHeader.FirstCellNum; i < cellCount; i++)
{
创建dataTable中的列,通过遍历行中的每一个单元格,获取标题行各个单元格的数据
- DataColumn dtColumn = new DataColumn(rowHeader.GetCell(i).StringCellValue);
将获取到的标题行的数据放到datatable中;
- dtExcel.Columns.Add(dtColumn);
}
获取Excel表格中的数据行
- for(var j = sheet.FirstRowNum; j < rowCount; j++){
获取数据行
- IRow row = sheet.GetRow(j);
创建DataTable行
- DataRow dtRow = dtExcel.NewRow();
再判断这一行是否为空,不为空的就去遍历这一行中所有的单元格,如果单元格不为空就把单元格中的值给到声明的变量中,再把这个值给到创建的行索引为n的单元格
去空行,声明一个变量 如果行当中存在不为空的单元格,变量isNull为false,否则为true
最后将数据行dtRow填入dtExcel中
- dtExcel.Rows.Add(dtRow);
}
处理DataTable中的数据
以上,将Excel表格中所有的数据写入了dtExcel中
接下来是在新增到数据库之前,对表格中各列数据的处理
遍历dtExcel中的每一行数据
- for(int i = 0; i < dtExcel.Rows.Count; i++){}
去除重复的数据
1、导入的数据之间进行比较,判断是否重复
2、导入的数据与数据库数据比较,判断是否重复
保存
多条数据的新增,开启事务,只有全部数据新增成功才提交事务,否则回滚
保证数据完整性
using (TransactionScope scope = new TransactionScope()){
保存数据到数据库
myModel.SYS_Student.AddRange();
if (myModel.SaveChanges() == listStudent.Count)
{
scope.Complete();//提交事务
msg.state = true;
msg.Text = "导入成功";
}
else
{
msg.Text = "导入失败";
}
}