1.找到导入Excel的模板,返回与 Web 服务器上的指定虚拟路径相对应的物理文件路径。
string filePath = Server.MapPath("~/Document/用户导入模板.xls");
2.判断模板文件是否存在
if (System.IO.File.Exists(filePath)) {
string strfileName = Path.GetFileName(filePath);//获取文件的名称
return File (new FileStream(filePath, FileMode.Open), “application/octet-stream”,strfileName); //以流的形式返回文件
}else {
return Content(“模板文件不存在,请联系系统运维人员。”);
}
3.开始导入Excel模板
public ActionResult ImportExcel(HttpPostedFileBase xlsFile){
(注:HttpPostedFileBase:初始化该类供继承的类实例使用。此构造函数只能由继承的类调用。)
ReturnJson msg = new ReturnJson();
– 使用 try,catch 捕捉错误,提示用户导入失败,检查选择的工作表是否正确
try{} catch (Exception e){
Console.WriteLine(e);
msg.Text = “导入失败,请检查是否有工作表,是否有数据,是否按照模板填写!”;
}
(1)获取上传文件的后缀,判断它是否是 .xls文件
string strExtension = Path.GetExtension(xlsFile.FileName);
(注: Path.GetExtension:获取扩展名的路径字符串)
if (".xls".Equals(strExtension,StringComparison.CurrentCultureIgnoreCase)){
}else{
msg.Text = “导入失败,请上传.xls文件”;
}
(2)把文件转换为二进制数组
byte[] fileBytes = new byte[xlsFile.ContentLength];
(注: byte:表示一个 8 位无符号整数;ContentLength:获取上载文件的大小(以字节为单位))
xlsFile.InputStream.Read(fileBytes, 0, xlsFile.ContentLength);
(3)二进制数组转成内存流;
MemoryStream excleMemoryStream = new MemoryStream(fileBytes);
(4)利用NPOI把内存流中的数据读取成Excel,就是将内存流转化为工作簿
(5)数据判断
① 判断是否存在工作表
if (workbook.NumberOfFonts > 0){
} else {
msg.Text = “导入失败,请检查是工作表存在!”;
}
② 判断工作表中是否有数据
NPOI.SS.UserModel.ISheet sheet = workbook.GetSheetAt(0);获取第一个工作表
if(sheet.PhysicalNumberOfRows>0){
(注:PhysicalNumberOfRows:获取的是物理行数,也就是不包括那些空行(隔行)的情况。)
}else{
msg.Text = “导入失败,请检查是第一个工作表中是否存在数据!”;
}
(6)使用NPOI读取数据
DataTable dt = new DataTable();//将Excel保存到临时表格里面,DataTable:表示一个内存中数据表
① 获取标题行(第二行,第一行是说明),索引为1
NPOI.SS.UserModel.IRow rowHeader = sheet.GetRow(1);
② 获取表格列数
int cellCount = rowHeader.LastCellNum;//行里面获取列总数
注:
③ 获取表格行数
int rowCount = sheet.LastRowNum + 1;//工作表获取行总数
(7)将Excel里的数据给DataTable
①将 Excel表头作为dt的列,创建dataTable中的列,循环添加标题行中各个单元格的值
for (int i = rowHeader.FirstCellNum; i < cellCount; i++){
DataColumn dtColumn = new DataColumn(rowHeader.GetCell(i).StringCellValue);
dt.Columns.Add(dtColumn);
} (注: DataColumn:表示 System.Data.DataTable 中的列的架构;
Columns:获取属于该表的列的集合 )
② Excel数据作为dt的数据
for(int i = (sheet.FirstRowNum)+2; i < rowCount;i++){
NPOI.SS.UserModel.IRow row = sheet.GetRow(i);
DataRow dtRow = dt.NewRow();
(注:DataRow:表示 System.Data.DataTable 中的一行数据)
– 如果行不为空,循环将Excel的行给到dt
if (row != null){
for (int j = row.FirstCellNum; j < cellCount; j++){
if (row.GetCell(j) != null){
dtRow[j] = row.GetCell(j).ToString();
} } }
③ 将填入数据的dtRow添入dtExcel
dt.Rows.Add(dtRow);
}
4.去除DataTable中的空行, 存放需要移除的DataRow
List removeList = new List();
(1)遍历所有的行
for (int i = 0; i < dt.Rows.Count; i++) {
bool rowDataIsEmpty = true;//创建标识是否是空行,默认为空行
(2)遍历DataRow的所有列,判断数据是否为空
for (int j = 0; j < dt.Columns.Count; j++){
if (!string.IsNullOrEmpty(dt.Rows[i][j].ToString().Trim())){
rowDataIsEmpty = false;//不是空行
}
}
– 如果是空行,添加到removeList
if (rowDataIsEmpty==true) {
removeList.Add(dt.Rows[i]);
}
(3)遍历,移除掉空行
for (int i = 0; i < removeList.Count; i++){
dt.Rows.Remove(removeList[i]);
}
5.数据验证
(1)先查询需要的数据
– 查询出所有用户组,用户角色(用于后面判断导入的数据的准确性)
List<S_UserGroup> userGroups = (from tabUserGroup in myModel.S_UserGroup
select tabUserGroup).ToList();
List<S_UserType> userTypes = (from tabUserType in myModel.S_UserType
select tabUserType).ToList();
– 查询存放的所有用户 包括数据库和添加的(用于判断工号是否重复)
List<S_User> allUsers = (from tabUser in myModel.S_User
select tabUser).ToList();
(2)将dataTable中的数据转换为List<S_User>
List<S_User> saveUsers = new List<S_User>();//定义存放容器(用于保存新增的数据)
(3)遍历datatable中的数据
for (int i = 0; i < dt.Rows.Count; i++) {
– 使用 try,catch 捕捉错误,提示用户数据不正确
try{} catch (Exception e){
Console.WriteLine(e);
msg.Text = “第” + (i + 1) + “条数据不正确,请检查”;
return Json(msg, JsonRequestBehavior.AllowGet);
}
DataRow dr = dt.Rows[i];
S_User addUser = new S_User(); //创建一个S_User实例保存一条用户数据
(4)开始验证
– 用户组号
string userGroupNumber = dr[“用户组号”].ToString().Trim();//根据用户组号查询用户组ID
addUser.userGroupID = userGroups.Single(o => o.userGroupNumber == userGroupNumber).userGroupID;
– 姓名
string userName = dr[“姓名”].ToString().Trim();
if (string.IsNullOrEmpty(userName))
{ //必须填写姓名
msg.Text = “第” + (i + 1) + “条数据的 姓名 未填写,请检查”;
return Json(msg, JsonRequestBehavior.AllowGet);
}
…
saveUsers.Add(addUser);//添加到要保存的列表saveUsers
allUsers.Add(addUser); //添加到用于查重的列表allUsers
6.新增保存
(1)保存之前一定要先开启事务
using (TransactionScope scope = new TransactionScope()) {
– 使用 try,catch 捕捉错误,提示用户导入保存失败
try{} catch (Exception e){
Console.WriteLine(e);
msg.Text = “数据导入保存失败”;
return Json(msg, JsonRequestBehavior.AllowGet);
}
(2)遍历新增数据
foreach (S_User saveUser in saveUsers){
– 保存用户数据
myModel.S_User.Add(saveUser);
myModel.SaveChanges();
– 获取保存后的用户ID,再保存 虚拟账户数据
int tUserId = saveUser.userID;
S_VirtualAccount virtualAccount = new S_VirtualAccount();
virtualAccount.userID = tUserId;//设置用户ID
virtualAccount.accountBalance = saveUser.amount;//设置账户余额
virtualAccount.account = string.Format(“XNZH{0:000000000}”, tUserId);//设置虚拟账号
– 保存
myModel.S_VirtualAccount.Add(virtualAccount);
myModel.SaveChanges();
}
(3)提交事务,提示用户导入保存成功
scope.Complete();
msg.State = true;
msg.Text = “数据导入成功,成功导入” + saveUsers.Count() + “条用户数据”;
}
return Json(msg, JsonRequestBehavior.AllowGet);
}
扩:Layui表格头部工具栏
(1)在执行表格渲染时,调用toolbar,绑定工具条:
(2)该参数支持四种类型值: