导入Excel表格(一)
开发工具与关键技术:VS ASP.NET MVC
作者:张华明
撰写时间:2019/05/23
1、Excel表格的导入
弹出导入Excel表格的模态框下载Excel表格的模板上传Excel表格,保存到临时表保存Excel表格的数据到数据库
在这里有一个导入信息的窗体,里面主要是导入Excel表格的按钮和存放Excel表格数据临时表格,所以在点击导入Excel表格的按钮后,会弹出下面的模态框
在选择导入excel表格前,我们要下载模板,里面是已经设计好的模板,点击下载导入模板,
显示下载模板,打开一个新的窗口,并在窗口中装载指定URL地址的网页。而导入到数据库的按钮在这个时候是禁用状态的(图一),为了防止用户直接把空的数据导入到数据库中从而形成了垃圾数据
function downImportTemplate() {
window.open("DownImportTemplate");
}
下面是设计好的模板
下载模板控制器代码:
首先,获取模板的物理路径,判断文件是否存在,获取到文件名称,返回文件
string filePath = Server.MapPath("~/Document/Template/考生信息导入模板.xls");
if (System.IO.File.Exists(filePath))
{
//获取文件名称
string fileName = Path.GetFileName(filePath);//考生信息导入模板.xls
//返回文件
return File(new FileStream(filePath, FileMode.Open), "application/octet-stream", fileName);
}
else
{
return Content("模板文件不存在,请联系系统运维人员。");
}
2、第二步是将导入到excel表格的数据保存到session中
2.1思路:(1)获取读取的文件(2)把文件转为二进制数据(3)把二进制数据转为内存流(4)利用NPOI把内存流的数据读取成excel表格
因为把内存流转为excel表格用到了NPOI这个引用,所以要添加NPOI 这个引用
2.2声明一个二进制的数组存放文件
byte[] fileBytes = new byte[file.ContentLength];
·将传入的文件转化为二进制数组存入fileBytes
file.InputStream.Read(fileBytes, 0, file.ContentLength);
Read()方法 从TextStream文件中读取指定数量的字符串,并以字符串返回结果
语法:TextStreamObject.read(numchar); 其中numchar 是必须的。需从文件中读取的数目,当然,你也可以用长度来替代 设置的数目,在你不知道文件数目的情况下的话。
将内存流转化为工作簿
NPOI.SS.UserModel.IWorkbookworkbook=newNPOI.HSSF.UserModel.HSSFWorkbook(excelFileStream);
有了工作簿,就是excel表格,还得看工作簿中是否有工作表,如果没有则提示一下用户,该工作簿中没有工作表,如果有工作表,在这里我用我的项目列举:声明四个列表对象,主要用来查询数据,因为查询的是一个集合,像上面的“学院”一样,每个学院ID都是唯一的,所以下面要根据工作表的“学院”名称到数据库中查询获取到对应的ID值,和一个对象列表,主要是用来存放导入学生的信息
四个列表对象:
List<SYS_Academe> dbAcademe = (from tbAcademe in myModels.SYS_Academe
select tbAcademe).ToList();
List<SYS_Specialty> dbSpecialty = (from tbSpecialty in myModels.SYS_Specialty
select tbSpecialty).ToList();
List<SYS_Grade> dbGrade = (from tbGrade in myModels.SYS_Grade
select tbGrade).ToList();
List<SYS_Class> dbClass = (from tbClass in myModels.SYS_Class
select tbClass).ToList();
对象列表,存放学生信息
List<studentVo> listStudentVo = new List<studentVo>();
List listStudentVo = new List();
接下来获取第一个工作表格,判断一下工作表格是否有数据if (sheet.PhysicalNumberOfRows > 0)
PhysicalNumberOfRows 获取物理行,不包括隔行,空行。创建DataTable封装数据,然后获取到工作表的行数、列数。获取表头行后,用for 循环遍历总列数,逐个添加标题行中每个单元格的数据,将获取到的标题行数据放到用来封装数据的DataTable 中。因为只获取到了标题行数据,其他行数据还没有获取,所以要再用一个for循环,遍历除了标题行的其他行,在遍历的其他行的同时还要逐个添加各个单元格的数据,所以要在遍历其他行的for循环中再嵌套一个for循环,用来遍历每个单元格并添加数据。每行获取到数据后,把新增的新行放到已经封装了标题行的DataTable中,这样一个工作表就完成了。
2.3foreach 遍历循环DataTAble中的数据,创建实体类对象保存数据, 根据名称查找对应的ID,上面已经有了四个要根据名称查找ID 的四个列表对象,
列举一个,其他一样:
student.AcademeName = row["学院"].ToString().Trim();
student.AcademeID=dbAcademe.Where(m=>m.AcademeName==student.AcademeName).SingleOrDefault().AcademeID
lambda表达式查询,SingleOrDefault()返回第一个元素,然后把每一条数据都添加到声明的对象列表listStudentVo中。最后把保存数据的对象列表listStudentVo保存到session中。这样数据保存到session中的工作就完成了。