在做MVC的项目中,常常会有涉及对很多数据的操作,而经常做的就是导入和导出了,我们先来了解一下导入导出。

导出:就是将你页面查询的数据导出到Excel表格,当然还有导出其他文件。

导入:就是将你需要添加的数据导入到数据库。

一、导出

(1)将要导出的数据查询出来;
(2)(2)引用NPOI插件创建表格,把创建好的Excel输出到浏览器。

public ActionResult ExportLKDATA()
 {
 try
 { 
 查询出需要导出的数据
 var query = var listStudent = (//在这里写查询代码…);
 //将查询出来的数据转化为对象列表的格式
 List list = query.ToList();
 NPOI导出Excel
 //创建工作簿Excel
 NPOI.HSSF.UserModel.HSSFWorkbook workbook = new NPOI.HSSF.UserModel.HSSFWorkbook();
 //为工作簿创建工作表并命名
 NPOI.SS.UserModel.ISheet sheet1 = workbook.CreateSheet();
 workbook.SetSheetName(0, “旅客信息”);//修改工作表名称
 //编写工作表
 (1)表头 (2)数据:query
 NPOI.SS.UserModel.IRow rowTitle = sheet1.CreateRow(0);//设置第一行表标题
 rowTitle.HeightInPoints = 35;//设置行高
 //注:行高 HeightInPoints的单位是点,而Height的单位是1/20个点,所以Height的值永远是HeightInPoints的20倍
 //创建单元格
 NPOI.SS.UserModel.ICell cell0 = rowTitle.CreateCell(0);
 //单元格设置值
 string strTitle = “旅客数据”;
 if (!string.IsNullOrEmpty(startEndDate))
 {
 strTitle += " " + startEndDate;
 }
 //合并单元格
 sheet1.AddMergedRegion(new NPOI.SS.Util.CellRangeAddress(0, 0, 0, 6));
 //设置单元格样式
 NPOI.SS.UserModel.ICellStyle cellStyle_Title = workbook.CreateCellStyle();
 cellStyle_Title.Alignment = NPOI.SS.UserModel.HorizontalAlignment.Center;//水平居中
 cellStyle_Title.VerticalAlignment = NPOI.SS.UserModel.VerticalAlignment.Center;//垂直居中
 NPOI.SS.UserModel.IFont font_title = workbook.CreateFont();//声明字体
 font_title.Color = NPOI.HSSF.Util.HSSFColor.Blue.Index;//设置字体颜色
 font_title.Boldweight = (short)NPOI.SS.UserModel.FontBoldWeight.Bold;//加粗
 font_title.FontHeightInPoints = 18;//字体大小
 cellStyle_Title.SetFont(font_title);//设置单元格字体
 cell0.CellStyle = cellStyle_Title;//设置单元格样式
 //创建行( 根据具体数据写代码…)
 //创建其他列并赋值( 根据具体数据写代码…)
 //设置列宽为自动适应
 for (int i = 0; i < sheet1.GetRow(1).Cells.Count; i++)
 {
 sheet1.AutoSizeColumn(i);
 sheet1.SetColumnWidth(i, sheet1.GetColumnWidth(i) * 17 / 10);
 }
 //把创建好的Excel输出到浏览器
 string fileName = “旅客信息” + DateTime.Now.ToString(“yyyy-MM-dd-HH-mm-ss-ffff”) + “.xls”;
 //把Excel转化为流输出
 MemoryStream BookStream = new MemoryStream();//定义流
 workbook.Write(BookStream);//将工作薄写入流
 BookStream.Seek(0, SeekOrigin.Begin);//输出之前调用Seek(偏移量,游标位置)
 return File(BookStream, “application/vnd.ms-excel”, fileName); // 文件类型/文件名称/
 }
 catch (Exception e)
 {
 Console.Write(e);
 return Content(“数据导出异常”);
 }}}
使用模板的方式导出Excel
 //–读取模板
 //获取模板的文件路径
 string templateFilePath = Server.MapPath("~/Document/ARDataTemplate.xls");
 //判断文件是否存在
 if (!System.IO.File.Exists(templateFilePath))
 {
 return Content(“导出失败,无法找到导出模板,请联系网站管理人员”);
 }
 //使用NPOI打开模板Excel
 //使用文件打开模板文件
 FileStream fileSteam = new FileStream(templateFilePath, FileMode.Open);
 //把文件流转为工作簿
 NPOI.HSSF.UserModel.HSSFWorkbook excelBookTemplate = new NPOI.HSSF.UserModel.HSSFWorkbook(fileSteam);
 //打开模板所在第一个工作表
 NPOI.SS.UserModel.ISheet sheet = excelBookTemplate.GetSheetAt(0);
 NPOI.SS.UserModel.ICellStyle style = excelBookTemplate.CreateCellStyle();
 //设置标题,如果筛选时间段不为空就拼接上筛选时间段
 if (!string.IsNullOrEmpty(startEndDate))
 {
 NPOI.SS.UserModel.IRow rowTitle = sheet.GetRow(0);
 rowTitle.GetCell(0).SetCellValue("订单数据 " + startEndDate);
 }
 //然后和上面一样往模板中填充数据二、导入
1、需要导入数据,那肯定要先有一个模板,而模板一般也是准备好的
 @* layui table toolbar模板 放在script标签中的作用 避免显示在页面 *@function openImportModal() {
 (’#formImportUser [type=“reset”]’).click();//重置表单
 $("#modImportUser").modal(‘show’);//显示模态框
 }
 下载模板只需要通过一个 window.open() 的方法就可以了。
 function downImportTemplate() {
 window.open("@Url.Content("~/OthersMaintenance/UserDataMaintain/DownImportTemplate")");
 }
 然后就是导入模板下载
 //获取模板文件的路径
 string templateFilePath = Server.MapPath("~/Document/用户导入模板.xls");
 //判断模板是否存在
 if (System.IO.File.Exists(templateFilePath))
 {
 //获取文件名称
 string fileName = System.IO.Path.GetFileName(templateFilePath);
 //以流的形式返回文件
 return File(new System.IO.FileStream(templateFilePath, System.IO.FileMode.Open),
 “application/octet-stream”, fileName);
 }
 else
 {
 return Content(“导入模板不存在,请联系网站管理人员”);
 }2、(1)模板下载好之后,就是文件上传了
 //文件上传 XMLHttpRequest
 function uploadExcelFile() {
 //获取选择文件
 var files = document.getElementById(“fileExcel”).files;
 console.log(files);
 if (files.length > 0) {
 //获取文件
 var excelFile = files[0];
 //===使用XMLHttpRequest上传文件
 //创建FormData对象
 var formData = new FormData();
 //将数据添加到FormData
 formData.append(“excelFile”, excelFile);
 var layerIndex = layer.load();//打开加载层
 //创建XMLHttpRequest对象
 var xhr = new XMLHttpRequest();
 //打开指定的URL 文件上传使用POST提交
 xhr.open(“POST”, “@Url.Content(”~/OthersMaintenance/UserDataMaintain/ImportExcel")");
 //设置回调方法
 xhr.onload = function (data) {
 //data.currentTarget.responseText 具体的返回内容
 var msg = JSON.parse(data.currentTarget.responseText);//把返回的字符串反序列化为json对象
 console.log(msg);
 layer.close(layerIndex);//关闭加载层
 if (msg.State) {
 layer.alert(msg.Text, { icon: 1 });
 $("#modImportUser").modal(‘hide’);//关闭模态框
 //刷新表格
 tabUserList.reload({
 page: {
 curr: 1 //重新从第 1 页开始
 }
 });
 } else {
 layer.alert(msg.Text, { icon: 2 });
 }
 };
 //发送数据
 xhr.send(formData);
 } else {
 alert(“请选择要上传的Excel(.xls)文件”);
 }
 }(2)判断上传文件是否是Excel(.xls)文件
 //判断文件后缀
 string fileExtension = System.IO.Path.GetExtension(excelFile.FileName);
 if (".xls".Equals(fileExtension, StringComparison.CurrentCultureIgnoreCase))
 {
 }
 else
 {
 msg.Text = “请上传Excel(.xls)文件”;
 }(3)将文件转换为二进制数组
 //转换成二进制数组
 //声明一个和文件大小一致的二进制数组
 byte[] fileBytes = new byte[excelFile.ContentLength];
 //将上传的文件转成二进制数组
 excelFile.InputStream.Read(fileBytes, 0, fileBytes.Length);(4)再将二进制数组转为内存流
 //将二进制数组转为内存流
 MemoryStream excelMemoryStream = new MemoryStream(fileBytes);(5)最后利用NPOI将内存流的数据读取到Excel工作簿
 //将内存流转为工作簿
 NPOI.SS.UserModel.IWorkbook workbook = new NPOI.HSSF.UserModel.HSSFWorkbook(excelMemoryStream);
 3、判断工作簿中是否有工作表
 //判断是否存在工作表
 if (workbook.NumberOfSheets > 0)
 {
 //获取出第一个工作表 
 NPOI.SS.UserModel.ISheet sheet = workbook.GetSheetAt(0);
 }
 Else
 {
 msg.Text = “导入失败,请检查是第一个工作表中是否存在数据!”;
 }4、判断工作表中是否有数据
 //判断工作表中是否存在行
 if (sheet.PhysicalNumberOfRows > 0)
 {
 }
 Else
 {
 msg.Text = “导入失败,请检查是第一个工作表中是否存在数据!”;
 }
 5、模板中的数据上传成功了。下面就是将数据保存到数据库了,也就是执行批量新增。
 第一步:将保存在DataTable中的数据获取到,在进行判断;
 //(1)将数据保存到DataTable中
 /定义DataTable
 DataTable dtExcel = new DataTable();
 //获取Excel中的标题行,设置dataTable的列名 第二行为标题行,索引为1
 NPOI.SS.UserModel.IRow rowHeader = sheet.GetRow(1);
 //获取表格的列数
 int cellCount = rowHeader.LastCellNum;
 //获取表格的行数
 int rowCount = sheet.LastRowNum + 1;
 //(2)创建DateTable中的列,
 for (int i = rowHeader.FirstCellNum; i < cellCount; i++)
 {
 //通过遍历行中的每一个单元格,获取标题行各个单元格的数据
 DataColumn dtCol = new DataColumn(rowHeader.GetCell(i).StringCellValue.Trim());
 //把列添加到DataTable中
 dtExcel.Columns.Add(dtCol);
 }
 //读取Excel中的数据
 //(sheet.FirstRowNum+2) 第一行是说明行 第二行是标题行,第三行开始才是数据
 for (int i = (sheet.FirstRowNum+2); i < rowCount; i++)
 {
 //获取行
 NPOI.SS.UserModel.IRow row = sheet.GetRow(i);
 //DataTable中创建一行
 DataRow dtRow = dtExcel.NewRow();
 //遍历行中列获取数据
 if (row != null)
 {
 for (int j = row.FirstCellNum; j < cellCount; j++)
 {
 if (row.GetCell(j) != null)
 {
 dtRow[j] = row.GetCell(j).ToString();
 }
 }
 }
 //将一行的数据添加到Datatable
 dtExcel.Rows.Add(dtRow);
 }
 //移除掉DataTable中的空行
 removeEmptyRow(dtExcel);
 //(3)将dataTable中的数据转换为List<S_User>
 //查询出所有用户组 和用户角色
 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();
 //定义存放容器
 List<S_User> saveUsers = new List<S_User>();
 //遍历datatable中的数据
 for (int i = 0; i < dtExcel.Rows.Count; i++)
 {
 Try
 {
 DataRow dr = dtExcel.Rows[i];
 //创建一个S_User实例保存一条用户数据
 S_User addUser = new S_User();
 获取值进行判断验证…
 //添加到要保存的列表saveUsers
 saveUsers.Add(addUser);
 //添加到用于查重的列表allUsers
 allUsers.Add(addUser);
 第二步:判断数据是否为空;
 private void removeEmptyRow(DataTable dt)
 {
 //存放需要移除的DataRow
 List removeList = new List();
 //遍历所有的行
 for (int i = 0; i < dt.Rows.Count; i++)
 {
 bool rowDataIsEmpty = true;//标识是否是空行-默认为空行
 //遍历DataRow的所有列
 for (int j = 0; j < dt.Columns.Count; j++)
 {
 //判断数据是否为空
 if (!string.IsNullOrEmpty(dt.Rows[i][j].ToString().Trim()))
 {
 rowDataIsEmpty = false;
 }
 }
 //如果是空行,添加到removeList
 if (rowDataIsEmpty)
 {
 removeList.Add(dt.Rows[i]);
 }
 }
 //移除掉空行
 for (int i = 0; i < removeList.Count; i++)
 {
 dt.Rows.Remove(removeList[i]);
 }
 }
 第四步:最后将数据保存了
 //=============进行数据保存
 if (saveUsers.Count > 0)
 {
 using (TransactionScope scope = new TransactionScope())
 {
 try
 {
 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();
        }
        //提交事务
        scope.Complete();
        msg.State = true;
        msg.Text = "数据导入成功,成功导入" + saveUsers.Count() + "条用户数据";
    }
    catch (Exception e)
    {
        Console.Write(e);
        msg.Text = "数据导入保存失败";
        return Json(msg, JsonRequestBehavior.AllowGet);
    }
}

}