实例化要返回页面的类;
类名 返回页面类名(自定义) = new 类名();
整个导入操作将写在 “try” 方法里;
在 “ActionResult” 引用 “HttpPostedFileBase ”接收上传的文件;
导入数据文件,先对文件的格式进行判断,即通过判断后缀是否为“.xls”;所以先获取文件的后缀名;
string 文件后缀名(自定义)= Path.GetExtension(接收到的文件.FileName);
if(".xls".Equals( 文件后缀名 ) || ".XLS".Equals( 文件后缀名 ){
将上传文件转化为二进制数组
将文件写入二进制数组中
二进制数组转成内存流 MemoryStream
将内存流转化为工作簿;
“IWorkbook 工作簿名(自定义) = new HSSFWorkbook(内存流)”;这一步需要在引用添加“NPOI“,然后给项目引用”NPOI.SS.UserModel“和”NPOI.HSSF.UserModel“;
然后判断工作簿中是否有工作表,即通过判断工作簿的“NumberOfSheets”是否大于0;
if(工作簿名 . NumberOfSheets > 0){
然后获取数据库中各表格的数据,目标数据库表格不需要获取;(为接下来判断数据重复使用)
List<数据库表名> 数据库表名(自定义) = 数据库名 . 数据库表名 . ToList();
创建创建一个存放数据的表对象,以上传至的目标数据库表格为列表创建对象;
List<目标数据库表名> 目标数据库表名(自定义) = new List<目标数据库表名>();
(以上两步类似于查询数据的获取数据,然后赋值给拥有页面表格接收数据的形式的对象;)
获取第一张工作簿中第一张工作表;“GetSheetAt(索引值)”可以获取工作簿中的工作表进行输出;
ISheet 工作表名(自定义) = 工作簿.GetSheetAt(索引值);
接下来判断工作表中是否含有数据;
“工作表.PhysicalNumberOfRows”获取工作表的物理行数,不包括那些空行(隔行)的情况,判断工作表行数不为 0 即拥有数据;
if(工作表名 . PhysicalNumberOfRows > 0){
【【【【【【【【【【【【【【【【 将数据放到DataTable的临时表里面
创建临时表;这里需要用到来自“system.Data”里的DataTable,所以要给项目引用“system.Data”
DataTable 临时表名(自定义) = new DataTable();
获取数据工作表里面的表头;
IRow 表头所在行名(自定义) = 工作表.GetRow(索引):获取表的行数;
FirstCellNum: 获取某行第一个单元格下标
LastCellNum:获取某行的列数
FirstRowNum:获取第一个实际行的下标
LastRowNum:获取最后一个实际行的下标
获取工作表总列数;
int 工作表列名(自定义) = 工作表.LastCellNum;
获取工作表总行数; 因为下标是索引值,所以这里得 + 1;
int 工作表行名(自定义) = 工作表.LastRowNum + 1;
用for循环遍历表头数据;i 的取值是工作表的列数;
for(int i = 表头所在行名 . FirstCellNum; i < 工作表列名;i++;){
创建临时表的列,设置字段;
DataColumn 临时表列名(自定义)= new DataColumn(表头所在行名.GetCell( i ). StringCellValue );
将创建的临时表的列放到临时表中;
临时表名.Columns.Add(临时表列名)
}
该for循环结束
获取工作表的数据行;
同样采用for循环遍历数据;j 的取值为工作表的行数;
(若第一行是说明,第二行是标题;第三行开始才是数据)则:
for(int j = 工作表名.FirstRowNum + 2;j < 工作表行名;j++){
逐一获取工作表中的数据行;GetRow 获取工作表中的行
IRow 数据表行名(自定义)= 工作表名.GetRow( j );
创建临时表的行;NewRow() 该方法会创建与该表具有相同架构的行
DataRow 临时表行名(自定义) = 临时表名.NewRow();
接下来要判断该 数据行 不为空,然后把该 数据行 的数据赋值给 临时表行
if(数据表行名 != null){
创建布尔值;用于判断当前数据行是否为空,为空则不进行对临时表行的赋值
bool 布尔值名(自定义)= true;
通过for循环遍历数据行的数据;数据行的列数相对于工作表的列数,所以i 的取值为工作表的列数;
for(int i = 数据表行名 . FirstCellNum; i < 工作表列名;i++){
对数据行中的单元格进行判断,不为空就赋值给临时表行
if(数据表行名 . GetCell(i)> 0){
创建一个新的字符串,用于存放数据行中的数据;
string 数据行的数据名(自定义) = 数据表行名 . GetCell( i ) . ToString();
将数据行的数据赋值给临时表行
临时表行名[ i ] = 数据行的数据名
判断数据行中的数据是否为空,为空时改变布尔值;
if(!string.IsNullOrEmpty( 数据行的数据名 )){
布尔值名 = false;
}
}
}
判断布尔值是否为 false,若为false说明当前的数据行不是空行;
if(布尔值名 == false){
不为空则代表含有数据,将临时表行填入临时表中
临时表名 .Rows . Add (临时表行名);
}
}
}该for循环结束
】】】】】】】】】】】】】】】】】】】】】】】】】】】】】】】】】】】
【【【【【【【【【【【【【处理临时表中的数据
以上,将工作表中所有的数据写入了临时表中;
接下来是在新增之前,对表格中各列数据的处理;
遍历临时表中的每一行数据,根据填入的数据名称匹配对应的数据库ID;
i 的取值为临时表的行数;. Rows 会获取对象的行数,但返回的也是一个对象,所以还要用 . Count() 来转换数据类型
for(int i = 0; i < 临时表名 . Rows . Count();i++){
逐一获取临时表的数据行;
DataRow 临时表数据行名(自定义) = 临时表名 . Rows[ i ];
创建用于接收处理完数据的表对象
表对象 表对象名(自定义) = new 表对象();
获取当前行中的目标列的值
string 目标列值名(自定义)= 临时表行名["目标列名"] . ToString() . Trim();
*这里获取的都是非上传目标数据库的数据,因为这些数据上传目标数据库没有;
try
{
表对象名 . 表对象名中的每个数据名 =根据条件,从数据库中找到该表对象对应的数据名;
}
catch (Exception)
{
返回页面类名.Text = string.Format("表格中第{0}行中信息匹配错误,请检查!", i + 1);
i 是行的索引值,所以这里得 + 1;
return Json(返回页面类名, JsonRequestBehavior.AllowGet);
}
对某个特定的数据进行格式验证;
把需要处理的临时表数据放到表对象
表对象名 . 目标数据名 = 临时表行名[“目标列名”] . ToString() . Trim();
将数据放到目标对象列表;
目标数据库表名 . Add(表对象名);
}
】】】】】】】】】】】】】】】】】】】】】】】】】】】】】】】】】】】
【【【【【【【【【【【【【【【【【【去重复
去重复要进行两次,第一次与自己进行对比,判断本身表格内是否有重复的数据,第二次与数据库内的数据做对比,判断本身与数据库内的数据是否重复;
判断目标数据库表名中是否有重复的数据
创建 新的目标数据库表名
List<目标数据库表名> 新目标数据库表名(自定义) = new List<目标数据库表名>();
以for循环遍历判断数据是否与自身重复;m 的取值为旧目标数据库表名的数据条数;
这个for循环的原理是:利用 新目标数据库表名 来与旧目标数据库表名对比;
for (int m = 0; m < 旧目标数据库表名 . Count; m++){
判断方式为本身数据行 与 本身数据行接下来的所有数据行 做对比
判断数据是否与本身列表是否重复,无须判断第一行数据,因此直接添加到 新目标数据库表名中;
m为索引值;当m等于 0 时则代表第一行数据;
if(m != 0){
嵌套一个for循环;这个for循环会遍历 新目标数据库表名 的数据;m 的取值是 新目标数据库表名;
for(int n = 0; n < 新目标数据库表名.Count; n++){
判断数据是否重复,重复即返回;
if(旧目标数据库表名[ m ] . 目标数据库数据名 == 新目标数据库表名[ n ] . 目标数据库数据名){
返回页面类名 . Text = string . Format ("Excel表格中第{0}条数据与其他数据重复,请检查!", m + 1);
return Json( 返回页面类名 , JsonRequestBehavior . AllowGet);
}
}
判断完后,将没有重复的数据放到 新目标数据库表名 中;
新目标数据库表名 . Add ( 旧目标数据库表名[ m ] );
}
else{
新目标数据库表名 . Add(旧目标数据库表名[ m ])
}
}
for循环结束
当 旧目标数据库名 中没有与自身重复的数据时;接下来要判断 旧目标数据库表名 中的数据是否与数据库中的数据重复
查询目标数据库表中所有的数据
List<目标数据库表> 目标数据名 = 数据库名 . 目标数据库表 . ToList();
利用for嵌套循环遍历每一条数据进行对比;
for (int i = 0; i < 旧目标数据库表名 . Count; i++)
{
for (int j = 0; j < 目标数据名 . Count; j++)
{
if(旧目标数据库表名[ i ] . 目标数据库数据名 == 目标数据名[ j ] . 目标数据库数据名)
{
返回页面类名 . Text = string . Format ("Excel表格中第{0}条数据已存在,请检查!", i + 1);
return Json( 返回页面类名 , JsonRequestBehavior . AllowGet);
}
}
}
】】】】】】】】】】】】】】】】】】】】】】】】】】】】】】】】】】】
【【【【【【【【【【【【【【【【【【【保存
多条数据的新增,开启事务,只有全部数据新增成功才提交事务,否则回滚;此举可以保证数据完整性、
开启事务
using (TransactionScope scope = new TransactionScope())
{
新增数据到数据库;AddRange:复数的数据添加方式;Add:只添加一条数据
数据库名 . 目标数据库表 . AddRange( 旧目标数据库表名 );
事物在这里起的作用是:当新增到数据库的数据与我们临时表里的数据的条数相同时才会导入成功,否则就会把之前新增到数据库的数据删除;保证数据的完整性
if (数据库名 . SaveChanges() == 临时表名 . Rows . Count)
{
新增的数据条数要与上传的数据条数相等
提交事物
scope.Complete();
返回页面类名.State = true;
返回页面类名.Text = "导入成功!";
}
else
{
返回页面类名.Text = "导入失败!";
}
}
】】】】】】】】】】】】】】】】】】】】】】】】】】】】】】】】】】】
}
else
{
returnText.Text = "工作表中没有数据,请检查!";
}
}
else
{
returnText.Text = "工作簿中不含工作表,请检查!";
}
}
else
{
returnText.Text = "上传文件类型错误!";
}