先封装一个读取Excel的方法,等获取到数据后调用:
///
/// 将excel中的数据导入到DataTable中
///
/// excel工作薄sheet的名称
/// 第一行是否是DataTable的列名
/// 返回的DataTable
public static DataTable ExcelToDataTable(string fileName, string sheetName, bool isFirstRowColumn)
{
ISheet sheet = null;
DataTable data = new DataTable();
int startRow = 0;
IWorkbook workbook = null;
try
{
using (FileStream fs = new FileStream(fileName, FileMode.Open, FileAccess.Read))
{
if (fileName.IndexOf(".xlsx") > 0) // 2007版本
workbook = new XSSFWorkbook(fs);
else if (fileName.IndexOf(".xls") > 0) // 2003版本
workbook = new HSSFWorkbook(fs);
if (sheetName != null)
{
sheet = workbook.GetSheet(sheetName);
if (sheet == null) //如果没有找到指定的sheetName对应的sheet,则尝试获取第一个sheet
{
sheet = workbook.GetSheetAt(0);
}
}
else
{
sheet = workbook.GetSheetAt(0);
}
if (sheet != null)
{
IRow firstRow = sheet.GetRow(0);
int cellCount = firstRow.LastCellNum; //一行最后一个cell的编号 即总的列数
if (isFirstRowColumn)
{
for (int i = firstRow.FirstCellNum; i < cellCount; ++i)
{
ICell cell = firstRow.GetCell(i);
if (cell != null)
{
string cellValue = cell.StringCellValue;
if (!string.IsNullOrEmpty(cellValue))
{
DataColumn column = new DataColumn(cellValue);
data.Columns.Add(column);
}
}
}
startRow = sheet.FirstRowNum + 1;
}
else
{
startRow = sheet.FirstRowNum;
}
//最后一列的标号
int rowCount = sheet.LastRowNum;
for (int i = startRow; i <= rowCount; ++i)
{
IRow row = sheet.GetRow(i);
if (row == null) continue; //没有数据的行默认是null
DataRow dataRow = data.NewRow();
for (int j = row.FirstCellNum; j < cellCount; ++j)
{
if (row.GetCell(j) != null) //同理,没有数据的单元格都默认是null
dataRow[j] = row.GetCell(j).ToString();
}
data.Rows.Add(dataRow);
}
}
return data;
}
}
catch (Exception ex)
{
Console.WriteLine("Exception: " + ex.Message);
return null;
}
}
正文代码部分,首先是要定义一个模板,让用户按照模板,在模板里面新增数据,方便我们的代码来处理。
为了提高可读性,我这里的模板样式先上个效果图,方便你们理解:
由于里面有时间列,所以得让用户先设置该列为文本格式,方便我们处理。其他的不多说,上导出模板的代码:
///
/// 幼儿模板信息
///
///
public IActionResult ChildImportModel()
{
//创建导出对象
NPOI.HSSF.UserModel.HSSFWorkbook execl = new NPOI.HSSF.UserModel.HSSFWorkbook();
//添加一个sheet
NPOI.SS.UserModel.ISheet sheet = execl.CreateSheet("Sheet1");
//添加标题行
NPOI.SS.UserModel.IRow head = sheet.CreateRow(0);
//写入标题行
head.CreateCell(0).SetCellValue("姓名");
head.CreateCell(1).SetCellValue("生日");
head.CreateCell(2).SetCellValue("性别");
head.CreateCell(3).SetCellValue("民族");
head.CreateCell(4).SetCellValue("身份证号");
head.CreateCell(5).SetCellValue("户籍所在省");
head.CreateCell(6).SetCellValue("详细户籍地址");
head.CreateCell(7).SetCellValue("现居详细地址");
head.CreateCell(8).SetCellValue("监护人1");
head.CreateCell(9).SetCellValue("手机号1");
head.CreateCell(10).SetCellValue("监护人2");
head.CreateCell(11).SetCellValue("手机号2");
head.CreateCell(12).SetCellValue("所在级段");
head.CreateCell(13).SetCellValue("班级");
NPOI.SS.UserModel.IRow row = sheet.CreateRow(1);
row.CreateCell(0).SetCellValue("以下内容为填充示例(括号内容为提示内容):");
NPOI.SS.UserModel.IRow row1 = sheet.CreateRow(2);
row1.CreateCell(0).SetCellValue("小明");
row1.CreateCell(1).SetCellValue("2016-12-18(注:时间格式应该按yyyy-MM-dd格式)");
row1.CreateCell(2).SetCellValue("女");
row1.CreateCell(3).SetCellValue("汉族");
row1.CreateCell(4).SetCellValue("421122144899538526(注:18位数字)");
row1.CreateCell(5).SetCellValue("湖北省");
row1.CreateCell(6).SetCellValue("湖北省武汉市青山区xx镇xx小区4-1803");
row1.CreateCell(7).SetCellValue("浙江省杭州市西湖区xx镇xx小区1-1001");
row1.CreateCell(8).SetCellValue("小明爸爸");
row1.CreateCell(9).SetCellValue("12345678911");
row1.CreateCell(10).SetCellValue("小明妈妈");
row1.CreateCell(11).SetCellValue("12345678912");
row1.CreateCell(12).SetCellValue("大班");
row1.CreateCell(13).SetCellValue("102");
sheet.CreateRow(3).CreateCell(0).SetCellValue("说明:需要输入时间的列请先设置单元格格式为文本,设置步骤 : 选中列-鼠标右键-设置单元格格式-数字-文本,设置完成后记得保存");
// 写入到客户端
System.IO.MemoryStream stream = new System.IO.MemoryStream();
execl.Write(stream);
stream.Seek(0, SeekOrigin.Begin);
string fileName = "幼儿导入模板.xls";
return File(stream, "application/vnd.ms-excel", fileName);
}
导入数据的模板是我们定义的,所以接下来就比较好处理了,我们可以直接读取列标题,来循环取数据,前面已经封装了读取数据的方法,直接调用就好,导入文件代码如下:
///
/// 导出幼儿信息
///
///
public IActionResult ChildImportExcel()
{
var errorStr = "";
var file = Request.Form.Files["file"];
if (file?.Length == 0)
{
return Json(RongboResult.Failed((int)ResultCode.Fail, "请选择需要导入的文件!"));
}
string filename = Path.GetFileName(file.FileName);
string ext = Path.GetExtension(filename).ToString().ToLower();
if (ext != ".xlsx" && ext != ".xls")
{
return Json(RongboResult.Failed((int)ResultCode.Fail, "只可以选择Excel文件!"));
}
//临时存放文件的位置
string savePath = _webEnv.ContentRootPath + "\\wwwroot\\UploadExcel\\" + DateTime.Now.ToString("yyyyMMddHHmmss") + filename;
using (var fileStream = new FileStream(savePath, FileMode.Create))
{
file.CopyTo(fileStream);
}
try
{
//调用第一个方法,读取excel数据
var dt = UtilsHelper.ExcelToDataTable(savePath, null, true);
if (dt?.Rows.Count == 0)
{
return Json(RongboResult.Failed((int)ResultCode.Fail, "没有数据!"));
}
for (int i = 0; i < dt.Rows.Count; i++)
{
var Name = dt.Rows[i]["姓名"].ToString();
var Birthday = dt.Rows[i]["生日"].ToString();
var Sex = dt.Rows[i]["性别"].ToString().Trim() == "男" ? "1" : "2";
var Nation = dt.Rows[i]["民族"].ToString().Trim();
var IdCard = dt.Rows[i]["身份证号"].ToString().Trim();
var RegisteredResidence = dt.Rows[i]["户籍所在省"].ToString().Trim();
var PermanentAddress = dt.Rows[i]["详细户籍地址"].ToString().Trim();
var CurrentAddress = dt.Rows[i]["现居详细地址"].ToString();
var Guardian1 = dt.Rows[i]["监护人1"].ToString().Trim();
var Phone1 = dt.Rows[i]["手机号1"].ToString().Trim();
var Guardian2 = dt.Rows[i]["监护人2"].ToString();
var Phone2 = dt.Rows[i]["手机号2"].ToString().Trim();
var Part = dt.Rows[i]["所在级段"].ToString();
var Class = dt.Rows[i]["班级"].ToString().Trim();
//根据身份证号查询数据唯一性,bool类型的方法,这里你们自己去结合实际做校验就好
var CardOnly = _Child.IdCardOnly(IdCard, Name);
//结果为真,就是查到了数据,那么,就做修改,反之新增
if (CardOnly)
{
var page = _Child.ChildEdit(new ChildEntity
{
DistrictCode = UserInfo.DistrictCode,
SchoolId = UserInfo.SchoolId,
Year = SystemYear,
Name = Name,
Birthday = Convert.ToDateTime(Birthday),
Sex = int.Parse(Sex),
Nation = Nation,
IdCard = IdCard,
RegisteredResidence = RegisteredResidence,
PermanentAddress = PermanentAddress,
CurrentAddress = CurrentAddress,
Guardian1 = Guardian1,
Phone1 = Phone1,
Guardian2 = Guardian2,
Phone2 = Phone2,
Part = Part,
Class = Class,
UpdateUser = UserInfo.Guid,
UpdateTime = DateTime.Now
});
}
else
{
//插入数据
var page = _Child.ChildInsertEdit(new ChildEntity
{
DistrictCode = UserInfo.DistrictCode,
SchoolId = UserInfo.SchoolId,
Year = SystemYear,
Name = Name,
Birthday = Convert.ToDateTime(Birthday),
Sex = int.Parse(Sex),
Nation = Nation,
IdCard = IdCard,
RegisteredResidence = RegisteredResidence,
PermanentAddress = PermanentAddress,
CurrentAddress= CurrentAddress,
Guardian1 = Guardian1,
Phone1=Phone1,
Guardian2= Guardian2,
Phone2 = Phone2,
Part=Part,
Class=Class,
CreateUser = UserInfo.Guid,
CreateTime = DateTime.Now
});
}
}
}
catch (Exception ex)
{
return Json(RongboResult.Failed((int)ResultCode.Errer, $"导入失败,请检查数据!"));
}
finally
{
//删除文件
System.IO.File.Delete(savePath);
}
if (string.IsNullOrWhiteSpace(errorStr))
{
return Json(RongboResult.Successed("", 1));
}
return Json(RongboResult.Failed(-1, errorStr));
}