专业信息维护(三)
作者:互联网
专业信息维护(三)
前言:
在上一篇学校信息维护已经全部的详细讲解了一遍,这剩下的四篇中将不再详细的讲解每一步的内容,如果又新的知识点会详细的说明!
下面几篇的基础都在《学校信息维护》中,基本没有改变,将会大量的设置上一篇的内容进行一个修改
一、专业信息的新增
1.1、html布局
包含【新增模态框】【导入模态框】【顶部搜索】
<!--顶部的搜索-->
<div class="container mt-5">
<!--模糊搜索、新增、导入-->
<div class="row justify-content-between mt-3">
<!--强制隔离两边的距离-->
<div class="col-auto mr-auto">
<form class="form-inline" autocomplete="off">
<div class="input-group mr-4">
<div class="input-group-prepend">
<span class="input-group-text" id="inputGroup-sizing-lg">学校:</span>
</div>
<select class="form-control" id="selectMajor" style="width:150px">
<option value="0">---请选择---</option>
</select>
</div>
<!--模糊搜索-->
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text" id="inputGroup-sizing-default">模糊搜索:</span>
</div>
<input type="text" class="form-control" id="fuzzySearch" placeholder="模糊搜索年级名称" oninput="studentReload()">
</div>
</form>
</div>
<!--新增按钮-->
<div class="col-auto">
<button type="button" class="btn btn-outline-primary" onclick="newSchool()">新增</button>
<button type="button" class="btn btn-outline-success" onclick="importStudent()">导入</button>
<button type="button" class="btn btn-outline-info">导出</button>
</div>
</div>
<!--渲染的表格-->
<table id="demo" lay-filter="test"></table>
</div>
<!--新增模态框-->
<div class="modal" id="myModal" tabindex="-1" role="dialog">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="title">新增学校信息</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<!--新增表单 autocomplete="off"禁用表单自动提交-->
<form id="myForm" autocomplete="off">
<!--隐藏域,存放学校ID-->
<input type="hidden" id="GradeID" />
<!--学校名称-->
<div class="form-group row">
<label for="academeNameI" class="col-3 col-form-label">所属学校:</label>
<div class="col-9">
<select class="form-control" id="selectGradeU" name="schoolID">
</select>
</div>
</div>
<!--年级名称-->
<div class="form-group row">
<label for="academeNameI" class="col-3 col-form-label">年级名称:</label>
<div class="col-9">
<input class="form-control" type="text" id="GradeName" name="gradeName" placeholder="年级名称" />
</div>
</div>
<!--年级编号-->
<div class="form-group row">
<label for="academeNameI" class="col-3 col-form-label">年级编码:</label>
<div class="col-9">
<input class="form-control" type="text" id="GradeCode" name="gradeCode" placeholder="年级编码" />
</div>
</div>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-primary" onclick="saveSchool()">保存</button>
<button type="button" class="btn btn-secondary" data-dismiss="modal">取消</button>
</div>
</div>
</div>
</div>
<!--导入学校信息-->
<div class="modal" id="importModal" tabindex="-1" role="dialog">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="title">导入学校信息</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<h6>第一步、下载年级表格上传模板:<button type="button" class="btn btn-info btn-sm" onclick="downImportTemplate()">下载模板</button></h6>
<div>
<h6>第二步、选择上传的文件夹</h6>
<input type="file" class="form-control-file" id="File1Excle">
</div>
</div>
<div class="modal-footer justify-content-start">
<button type="button" class="btn btn-primary" onclick="uploadSchool()">上传</button>
<button type="button" class="btn btn-secondary" data-dismiss="modal">取消</button>
</div>
</div>
</div>
</div>
1.2、表格渲染部分
<script>
var table; // 全局变量table
layui.use('table', function () {
table = layui.table; // 模块加载
//第一个实例
table.render({ // render渲染
elem: '#demo' // 渲染的ID
// , url: '/RegionalFile/SchoolInformation/SelectStudent' //数据接口
, data: [] // 默认渲染第一页
, page: true //开启分页
, cols: [[ //表头
// title是表头的名称 type是列的类型 align是设置字体居中 fiels是与查询数据的字段接口
{ title: '序号', type: "numbers", align: "center" }
, { field: 'schoolName', title: '学校名称', align: "center" }
, { field: 'schoolCode', title: '年级名称', align: "center" }
, { field: 'schoolCode', title: '年级编号', align: "center" }
, { field: 'city', title: '操作', align: "center", templet: operate, width: 150 }
]]
});
// 表格重载
studentReload();
});
</script>
1.3、表格重载(模糊、筛选)
// 表格重载(模糊搜索)
function studentReload() {
// 模糊搜索专业的名称
var fuzzySearch = $("#fuzzySearch").val();
// 根据学校去筛选
var selectSchool = $("#selectGradeI").val();
table.reload("demo", {
url: "@Url.Content("/RegionalFile/GradeInformation/SelectGrade")",
where: {
GradeName: fuzzySearch,
SchoolID: selectSchool
}
});
}
1.4、操作自定义列按钮
// 封装操作按钮返回
function operate(rowData) {
// rowData是获取到当前行的信息
var gradeID = rowData.gradeID;// 获取到每一行的学校ID
// console.log(gradeID);
// 点击的时候将学校ID传递过去
return '<a class="layui-btn layui-bg-green layui-btn-xs" lay-event="edit" onclick="editGrade(' + gradeID + ')">编辑</a><a class="layui-btn layui-bg-red layui-btn-xs" lay-event="edit" onclick="deletionStudent(' + gradeID + ')">删除</a>'
}
1.5、表格渲染查询数据和模糊搜索
创建了一个GradeData继承年级表的实体类,主要是添加一个所属学校,但要查到学校ID
#region 第二步、表格查询和模糊搜索
/// <summary>
/// 查询渲染数据信息
/// </summary>
/// <param name="layuiTable">分页参数</param>
/// <param name="SchoolID">学校ID</param>
/// <param name="GradeName">年级名称</param>
/// <returns></returns>
public ActionResult SelectGrade(LayuiTablePage layuiTable,int? SchoolID, string GradeName)
{
// 第一步、专业数据查询
var queryGrade = from tbGrade in myModels.Grade
// 连接学校表查询学校名称
join tbSchool in myModels.School on tbGrade.schoolID equals tbSchool.schoolID
select new GradeData
{
// 里面的字段跟field对应
gradeID = tbGrade.gradeID,
gradeName = tbGrade.gradeName,
gradeCode = tbGrade.gradeCode,
schoolID = tbSchool.schoolID,
SchoolName = tbSchool.schoolName
};
// 第二步、模糊搜索(条件筛选)
if (SchoolID != null && SchoolID > 0) {
queryGrade = queryGrade.Where(o => o.schoolID == SchoolID);
}
if (!string.IsNullOrEmpty(GradeName)) {
GradeName = GradeName.Trim();
queryGrade = queryGrade.Where(o => o.gradeName.Contains(GradeName));
}
// 第三步、查询的总数据
int GradeCount = queryGrade.Count();
// 第四步、分页查询
List<GradeData> GradePage = new List<GradeData>();
GradePage = queryGrade.OrderBy(o => o.gradeID).Skip(layuiTable.getPage()).Take(layuiTable.limit).ToList();
// 第五步、封装返回的数据
LayuiTableData<GradeData> GradeData = new LayuiTableData<GradeData>();
GradeData.count = GradeCount;
GradeData.data = GradePage;
return Json(GradeData, JsonRequestBehavior.AllowGet);
}
#endregion
1.5、表头样式效果如下
因为还没有数据渲染,先将上面的写上,新增的时候就可以了
二、思路分析
- 在顶部有一个学校的下拉框,而在后面的几个页面也都会用到这个下拉框,所以我们可以创建多一个区域【common】专门用来存放以后需要用到的所有公共样式
- 封装一个查询学校的方法到区域控制器里面,将js的请求方法也封装在一个外部js文件中,以后要用到的时候引入js文件调用方法和传入两个参数【请求控制器的名称,要将数据写到哪一个下拉框】
- 在页面已加载的时候要将学校的名称查询出来并绑定给下来框,并且新增的模态框中也要绑定
- 这里面的代码几乎全部复制过来进行一个修改
- 第一步是实现学校下拉框的绑定
- 第二步是封装一个基础Grade的实体类,为什么要封装这个实体类呢,看到表头会发现有一个学校名称,而学校名称是Grade中的一个外键School,需要获取到学校的名称,就只能通过实体类去封装一个保存查询出来的学校名称,表格field调用接口数据时就使用他
- 以后封装的实体类都存放在上一次创建的实体类文件【Entity】中
1.1、封装基础Grade的实体类
实体类名称GradeData
继承的意思就是:继承表的所有字段或者属性这一个实体类都会有,就相对于比原先的表多了一个字段
public class GradeData:Models.Grade
{
public string SchoolName { get; set; }
}
1.2、封装返回状态信息的实体类
实体类名称ReturnJson
里面有两个值,第一个是我们要返回的一个文本值,第二个是布尔值返回true和false
之前使用返回的方法是,声明一个str变量来记录状态信息并返回
要将实体类创建实例
// 返回值
ReturnJson msg = new ReturnJson();
public class ReturnJson
{
// 返回文本值
public string Text { get; set; }
// 返回的状态值
public bool State { get; set; }
}
1.3、区域创建和封装查询学校方法
区域的创建
创建一个区域文件Common存放公共要用到的控制
这里将获取到的值查询复制给了id和tite
注意要实例化Models
#region 查询学校信息绑定给下拉框
public ActionResult querySchool()
{
var SchoolCount = from tbSchool in myModels.School
select new {
// 查询学校ID
id = tbSchool.schoolID,
// 查询学校名称
tite = tbSchool.schoolName
};
return Json(SchoolCount, JsonRequestBehavior.AllowGet);
}
#endregion
1.4、封装js调用方法
这一个js文件是封装在一个外部js文件里面,需要用到的时候就调用queryData()
里面传递两个参数【请求路径,下拉框的ID】
eindex是获取到遍历对象索引号
ele是获取到对象的值
// 查询学校名称绑定下拉框
function queryData(url, id) {
// 获取到要插入的select标签
var selectData = $("#" + id);
// 清空子元素
$("#" + id).empty();
// 变量,先赋值一下请选择
var str = "<option value='0'>---请选择---</option>";
$.post(url, function (data) {
$.each(data, function (index, ele) {
str += "<option value='" + ele.id + "'>" + ele.tite+"</option>";
});
// 将元素插入到select中
selectData.append(str);
})
}
1.5、遍历查询的结果
1.6、页面加载时调用方法
$(function () {
// 页面中的学校
queryData("/Common/querySchool/querySchool", "selectGradeI");
// 模态框中的学校
queryData("/Common/querySchool/querySchool","selectGradeU");
});
三、年级信息的新增
1.1、控制器方法
在下面的代码中,你会发现修改的内容就那么一点点,多添加了一个学校判断
接收参数的实体类又学校改为了年级
#region 第一步、新增学校信息
/// <summary>
/// 通过实体类来接收新增数据
/// </summary>
/// <param name="school">专业表的实体类</param>
/// <returns></returns>
public ActionResult AddGrade(Grade AddGrade)
{
// 返回值
ReturnJson msg = new ReturnJson();
// 判断学校信息
if (AddGrade.schoolID > 0)
{
// 判断年级名称是否为空
if (!string.IsNullOrEmpty(AddGrade.gradeName))
{
// 判断年级编号是否为空与编号是否符合正则表达式,五位整数
if (!string.IsNullOrEmpty(AddGrade.gradeCode) && Regex.IsMatch(AddGrade.gradeCode, "^\\d{3}$"))
{
// 判断数据是否重复操作
int studentTow = myModels.Grade.Count(o => o.gradeName.Contains(AddGrade.gradeName) || o.gradeCode.Contains(AddGrade.gradeCode));
// 数据不重复就等于0
if (studentTow == 0)
{
// 使用try判断是否出错
try
{
// Add是新增的意思,新增值数据库
myModels.Grade.Add(AddGrade);
// SaveChanges() 保存到数据库
if (myModels.SaveChanges() > 0)
{
msg.State = true;
msg.Text = "年级信息新增成功";
}
else
{
msg.Text = "年级信息新增失败";
}
}
catch (Exception e)
{
return Content("新增出错");
}
}
else
{
msg.Text = "数据重复请检查";
}
}
else
{
msg.Text = "学校编号由三个整数组合";
}
}
else
{
msg.Text = "请输入年级名称";
}
}
else
{
msg.Text = "请选择学校";
}
// 返回值
return Json(msg, JsonRequestBehavior.AllowGet);
}
#endregion
1.2、弹出新增模态框
// 新增模态框的弹出
function newSchool() {
// 通过他来判断是新增还是编辑模态框
$("#SchoolID").val(0);
// 重置form表单
$("#myForm").get(0).reset();
// 修改标题
$("#title").text("新增年级信息");
// 弹出新增模态框
$("#myModal").modal();
}
1.3、将新增的数据传递控制器
新增跟修改的提交方式一样
// 学校信息新增跟编辑的保存
function saveSchool() {
// 隐藏域存放ID
var GradeID = $("#GradeID").val();
// 获取学校
var selectGrade = $("#selectGradeU").val();
// 获取名称
var GradeName = $("#GradeName").val();
// 获取编码
var GradeCode = $("#GradeCode").val();
// 判断数据信息
if (selectGrade == "" || selectGrade == undefined || selectGrade == 0) {
layer.alert("请选择所属学校");
return;
}
// 判断数据信息
if (GradeName == "" || GradeName == undefined) {
layer.alert("请输入年级名称");
return;
}
if (GradeCode == undefined || GradeCode == "" || !/^\d{3}/.test(GradeCode)) {
layer.alert("请输入正确的年级编号,3位整数组成");
return;
}
// 发送请求数据
var strUrl = "";
if (GradeID == undefined || GradeID == "" || GradeID < 1) {
// 新增专业信息
strUrl = '@Url.Content("/RegionalFile/GradeInformation/AddGrade")';
} else {
// 编辑专业信息
strUrl = '@Url.Content("/RegionalFile/SchoolInformation/editStudent")';
}
// 数据请求
$.post(strUrl, {
gradeID: GradeID,
gradeName: GradeName,
gradeCode: GradeCode,
schoolID: selectGrade
}, function (data) {
layer.alert(data.Tate);
// 表格重载
studentReload();
// 关闭模态框
$("#myModal").modal("hide");
});
}
1.4渲染结果
成功将新增的两条数据信息渲染出来
三、编辑模态框的弹出和数据绑定
1.1、弹出模态框和数据回填
编辑的模态框中,最主要的一点是点击的时候将当前行的一个信息绑定给模态框,一共有两个方法,这里使用第二种,通过点击获取到的年级ID,将ID的值传递给新的控制器来查询到年级的信息并返回给视图,然后绑定给模态框
注意点,关于学校的绑定,必须要将学校的值在页面加载时先绑定给了模态框才能将获取到达值绑定给学校
// 编辑模态框的弹出
function editGrade(gradeID) {
// 通过他来判断是新增还是编辑模态框
$("#GradeID").val(gradeID);
// 重置form表单
$("#myForm").get(0).reset();
// 修改标题
$("#title").text("编辑年级信息");
// 数据绑定
$.get("editGradeID?gradeID=" + gradeID, function (data) {
$("#SchoolID").val(data.schoolID);
// 学校名称
$("#schoolName").val(data.schoolName);
// 学校编号
$("#schoolCode").val(data.schoolCode);
});
// 弹出新增模态框
$("#myModal").modal();
}
1.2、控制器查询年级信息
Single()是返回一条数据,多了会报错
#region 第三步、编辑学校信息的重新
/// <summary>
/// 编辑学年级信息的重新
/// </summary>
/// <param name="gradeID">接收查询的ID</param>
/// <returns></returns>
public ActionResult editGradeID(int gradeID)
{
Grade query = myModels.Grade.Where(o => o.gradeID == gradeID).Single();
return Json(query, JsonRequestBehavior.AllowGet);
}
#endregion
1.3、出现未知错误
点击编辑,传递的数据没有回填,500找不到页面
但在控制中断点调试也确实是能将年级信息查询出来的
点击控制台【Network】会看到一个请求失败
点击红色的请求
说我们的对象在循环引用
解决方法:
打开数据库,找到当前数据库的表,展开表中的键,将所有的FK外键全部删除
注意是每一张表都要
删除方法:选中FK外键,右键删除即可
1.4、要更新Model模型
因为数据库已经发生更改,而映射过去的Models模型并不会
要删除所有模型然后在从模型中更新表
从数据库中生成模型
重新生成的模型没有了外键连接
现在点击编辑,就不会查询不到年级信息了
将输出的结果绑定给模态框即可
四、编辑年级信息的保存
新增保存跟编辑保存的方法都一样,在上面已经写上了
1.1、编辑年级信息的控制器方法
#region 第四步、编辑模态框的保存方法
public ActionResult editGrade(Grade grade)
{
ReturnJson msg = new ReturnJson();
// 判断学校是否存在
if (grade.schoolID > 0) {
// 判断年级名称是否为空
if (!string.IsNullOrEmpty(grade.gradeName))
{
// 判断学校编号是否为空与编号是否符合正则表达式,五位整数
if (!string.IsNullOrEmpty(grade.gradeCode) && Regex.IsMatch(grade.gradeCode, "^\\d{3}$"))
{
// 判断数据是否重复操作
int reduplication = myModels.Grade.Count(o => o.gradeID == grade.gradeID && (o.gradeName.Contains(grade.gradeName) && o.gradeCode.Contains(grade.gradeCode)));
// 数据不重复就等于0
if (reduplication == 0)
{
// 使用try判断是否出错
try
{
// Add是新增的意思,新增值数据库
// Modified是修改
myModels.Entry(grade).State = System.Data.Entity.EntityState.Modified;
// SaveChanges() 保存到数据库
if (myModels.SaveChanges() > 0)
{
msg.State = true;
msg.Text = "年级信息修改成功";
}
else
{
msg.Text = "年级信息修改失败";
}
}
catch (Exception e)
{
return Content("出现未知错误");
}
}
else
{
msg.Text = "数据重复请检查";
}
}
else
{
msg.Text = "年级编号由3个整数组合";
}
}
else
{
msg.Text = "请输入年级名称";
}
}
else
{
msg.Text = "请选择学校";
}
// 返回值
return Json(msg, JsonRequestBehavior.AllowGet);
}
#endregion
五、输出年级信息
1.1、js传递年级ID
// 删除学校信息
function deletionGrade(gradeID) {
layer.confirm('您确定要执行删除操作吗', { icon: 0, title: '删除年级信息' }, function (index) {
// 将学校ID传递给控制器删除
$.post("deletionGrade?gradeID=" + gradeID, function (data) {
// 信息回填
layer.alert(data.Text);
// 表格重载
studentReload();
});
// 确定关闭询问框
layer.close(index);
}, function (index) {
layer.alert("您已取消删除操作");
// 确定关闭询问框
layer.close(index);
});
}
1.2、删除的控制器方法
使用到了判断其他的表格是否用到年级信息,如果用到就不能这些删除操作
#region 第五步、删除学校信息操作
public ActionResult deletionGrade(int gradeID)
{
ReturnJson msg = new ReturnJson();
// 判断学校信息是否被使用到
int MajorsUseGrade = myModels.Majors.Count(o => o.gradeID == gradeID); // 专业使用情况
int ClassUseGrade = myModels.Class.Count(o => o.gradeID == gradeID); // 班级使用情况
int StudentUseGrade = myModels.Student.Count(o => o.gradeID == gradeID); // 学生使用情况
// 判断使用条数,使用就不能删除
if ((MajorsUseGrade + ClassUseGrade + StudentUseGrade) == 0)
{
// 根据学校ID出现数据
Grade delectGrade = myModels.Grade.Where(o => o.gradeID == gradeID).Single();
try
{
// 删除信息
myModels.Grade.Remove(delectGrade);
// 判断是否成功
if (myModels.SaveChanges() > 0)
{
msg.State = true;
msg.Text = "年级信息删除成功";
}
else
{
msg.Text = "年级信息删除成功";
}
}
catch (Exception e)
{
return Content("删除信息出错");
}
}
else
{
msg.Text = "年级数据正在被使用中,无法删除信息";
}
return Json(msg, JsonRequestBehavior.AllowGet);
}
#endregion
六、下载上传模板
1.1、模板的放置
选择Common存放上传的文件夹,在资源管理库中打开
1.2、将给到的年级模板复制到文件夹
1.3、显示文件包含在项目中
包含在项目中之后就可以查看到文件
1.4、导入模态框的弹出
注意修改点击导入的事件
// 打开导入模态框
function importGrade() {
// 将file清空
$("#exampleFormControlFile1").val("");
// 打开模态框
$("#importModal").modal();
}
1.5、下载模板的控制器方法
- 查找文件路径
- 判断文件是否存在
- 文件存在返回FIle下载
- File()方法有三个参数,输入逗号的时候会提示这个参数是上面值,如下图:
#region 第六步、导入年级信息模板下载
public ActionResult downloadGrade()
{
// 第一步、找到文件的路径
var exist = Server.MapPath("/Document/年级信息导入模板.xls");
// 第二步、判断文件是否存在,返回true或者false
if (System.IO.File.Exists(exist))
{
// 第三步、返回下载文件
return File(exist,"application/vnd.ms-excel","年级信息导入模板.xls");
}
else {
return Content("下载模板文件不存在");
}
}
#endregion
1.6、js调用下载的方法
模板下载成功,里面有三条示例
// 点击下载年级模板
function downloadGrade() {
window.open("/RegionalFile/GradeInformation/downloadGrade");
}
通过三条示例上传文件
七、导入年级信息上传
1.1、点击上传按钮上传数据
contentType\processData这两个方法是必须要有的
将数据插入到formData对象里面的excelFile是与控制器接收上传的数据有关,不能乱填必须想对应
// 点击上传文件
function uploadGrade() {
// 获取到要上传的文件
var file = $("#File1Excle").get(0).files[0];
// 创建对象存放上传文件
var formData = new FormData();
// 将文件插入到对象里面 excelFile是控制接收
formData.append("excelFile", file);
// 文件上传到控制器
$.ajax({
url: "/RegionalFile/GradeInformation/uploadGradeFormwork",
method:"post",
data: formData,
contentType: false, // 让ajax不指定数据类型
processData: false, // 让ajax不对数据进行处理
username: function (data) {
// 弹出回调信息
layer.alert(data.Text);
// 表格刷新
studentReload();
// 关闭导入模态框
$("#importModal").modal("hide");
}
});
1.2、上传文件的控制器
- 文件上传都使用HttpPostedFileBase来接收上传的文件
- 思路:
- 获取上传文件
- 把文件转换成二进制数组
- 将二进制数组转换为内存流表
- 利用NPOI把内存流表中的数据读取到Excel
这一篇相比如上一篇的信息导入,多了一部分内容
先查询出学校的一个信息
代码已包含在下面的完整代码中
// 学校外键 查询学校信息
List<School> listSchool = myModels.School.ToList();
根据导入的一个学校信息到到上面查询到的学校信息里面查询相应的ID
// 获取到要添加进去行的数据
string SchoolName = row["学校名称"].ToString().Trim();
try {
// listSchool前面创建的一个学校列表 只查询到他的ID
grade.schoolID = listSchool.Where(o => o.schoolName == SchoolName).Single().schoolID;
}
catch (Exception e) {
Debug.WriteLine(e);
msg.Text = string.Format("第{0}学校数据无法匹配", i +1);
return Json(msg,JsonRequestBehavior.AllowGet);
}
完整的上传文件代码如下:
#region 第七步、上传年级导入模板
public ActionResult uploadGradeFormwork(HttpPostedFileBase excelFile)
{
ReturnJson msg = new ReturnJson();
// 第一步、使用try判断
try {
//思路
//1、获取读取文件
//2、把文件转换为二进制数组
//3、二进制数组转换成内存流
//4、利用NPOI把内存流中的数据读取层Excel
// 第二步、获取文件扩展名
string fileExtension = Path.GetExtension(excelFile.FileName);
// 第三步、判断文件的格式是否符合
if (".xls".Equals(fileExtension) || ".XLS".Equals(fileExtension))
{
// 第四步、将文件转换为二进制数组
byte[] fileByte = new byte[excelFile.ContentLength]; // 二进制的长度就是上传文件的字节长度
excelFile.InputStream.Read(fileByte, 0, excelFile.ContentLength); // 上传的文件插入到二进制数组 参数(二进制数组,开始位置,结束位置)
// 第五步、将二进制数组转换为内存流
MemoryStream excelFileStream = new MemoryStream(fileByte);
// 第六步、使用NPOI读取数据
NPOI.SS.UserModel.IWorkbook workbook = new HSSFWorkbook(excelFileStream); // 将内存流转换成工作簿(Excel文件)
// 判断工作博里面是否有数据
if (workbook.NumberOfSheets > 0)
{
// 学校外键 查询学校信息
List<School> listSchool = myModels.School.ToList();
// 创建一个年级列表,最用取出来的数据就添加给他
List<Grade> listGrade = new List<Grade>();
// 获取到第一个工作表
NPOI.SS.UserModel.ISheet sheet = workbook.GetSheetAt(0); // sheet sheet2 sheet3
// 判断工作表中是否有数据
if (sheet.PhysicalNumberOfRows > 0)
{
// 创建内存中的表,将数据存放起来
DataTable dtExcel = new DataTable(); // 引入命名空间System.Data
// 获取工作表的表头(第一行),索引号找到
NPOI.SS.UserModel.IRow rowHeader = sheet.GetRow(0); // sheet获取的第一个工作表
//LastCellNum:获取某行的列数
//LastRowNum:获取最后一个实际行的下标
//FirstCellNum:获取某行第一个单元格下标
//FirstRowNum:获取第一个实际行的下标
// 获取表的列数
int cellCount = rowHeader.LastCellNum;
// 获取工作表的行数
int rowCount = sheet.LastRowNum + 1; // 加一是为了跳过表头
#region 循环给内存中的表添加表头单元格
// 循环添加dtExcel列的标题单元格
for (int i = rowHeader.FirstCellNum; i < cellCount; i++) { // i等于第一行表头的列数 2 同时小于表头列数 2 自加
// 创建列单元格
DataColumn dtColum = new DataColumn(rowHeader.GetCell(i).StringCellValue);
// 将列单元格添加给内存中的表dtExcel
dtExcel.Columns.Add(dtColum); // Columns 列的集合
}
#endregion
#region 循环读取上传数据,添加到内存中的表
// FirstRowNum获取到第一个实际下标(需要添加的数据,除表头) rowCount表格的行数
for (int i = sheet.FirstRowNum + 1; i < rowCount; i++) {
// 获取到表格的行数据(下标)
NPOI.SS.UserModel.IRow row = sheet.GetRow(i);
// 创建内存中的表dtExcel的行
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();
}
}
// 将行的数据添加到内存中创建的表
dtExcel.Rows.Add(dtRow);
}
}
#endregion
#region 循环获取表格的值添加给年级列表
for (int i = 0; i < dtExcel.Rows.Count; i++) {
// 创建行 将循环的数据添加到行里面
DataRow row = dtExcel.Rows[i];
// 创建Grade对象保存每一条数据
Grade grade = new Grade();
// 获取到要添加进去行的数据
string SchoolName = row["学校名称"].ToString().Trim();
try {
// listSchool前面创建的一个学校列表 只查询到他的ID
grade.schoolID = listSchool.Where(o => o.schoolName == SchoolName).Single().schoolID;
}
catch (Exception e) {
Debug.WriteLine(e);
msg.Text = string.Format("第{0}学校数据无法匹配", i +1);
return Json(msg,JsonRequestBehavior.AllowGet);
}
grade.gradeName = row["年级名称"].ToString().Trim();
grade.gradeCode = row["年级编号"].ToString().Trim();
// 先年级列表添加grade对象
listGrade.Add(grade);
}
#endregion
#region 保存到数据库,开启事务
using (TransactionScope scope = new TransactionScope()) {
// 保存到数据库
myModels.Grade.AddRange(listGrade);
if (myModels.SaveChanges() == dtExcel.Rows.Count) {
scope.Complete();// 提交事务
msg.Text = "年级信息导入成功";
}
else
{
msg.Text = "年级信息导入失败";
}
}
#endregion
}
else {
msg.Text = "工作表中没有数据,请检查";
}
}
else {
msg.Text = "上传文件无数据,请检查";
}
}
else {
msg.Text = "上传的文件格式不符合.xls,请检查";
}
}
catch (Exception e) {
msg.Text = "文件上传失败,请检查";
}
return Json(msg,JsonRequestBehavior.AllowGet);
}
#endregion
1.3、新增模板信息成功
标签:专业,gradeID,信息,学校,Text,msg,年级,维护 来源: https://blog.csdn.net/baidu_39378193/article/details/117822676