.NET MVC 学习笔记(六)— 数据导入
.NET MVC 学习笔记(六)—— 数据导入
在程序使用过程中,有时候需要新增大量数据,这样一条条数据去Add明显不是很友好,这时候最好就是有一个导入功能,导入所需要的数据,下面我们就一起来看一下导入功能。

一. 在导入之前,首先我们需要下载模板,模板下载方法
$("#btnDownloadTemplate")
.click(function () {
window.location.href = "@Url.Content("~/Content/ImportClientDataTemplate.xlsx")";
});
MVC .NET框架中该方法可以在很容易的下载模板文件。
如果是纯前端框架,该方法则无效,运行效果为直接在浏览器中打开模板文件,显然不是我们想要的。此时可以使用以下办法:
/*
* 下载文件
*/
window.downloadFile = function(sUrl) {
//iOS devices do not support downloading. We have to inform user about this.
if(/(iP)/g.test(navigator.userAgent)) {
alert('Your device does not support files downloading. Please try again in desktop browser.');
return false;
} //If in Chrome or Safari - download via virtual link click
if(window.downloadFile.isChrome || window.downloadFile.isSafari) {
//Creating new link node.
var link = document.createElement('a');
link.href = sUrl; if(link.download !== undefined) {
//Set HTML5 download attribute. This will prevent file from opening if supported.
var fileName = sUrl.substring(sUrl.lastIndexOf('/') + 1, sUrl.length);
link.download = fileName;
} //Dispatching click event.
if(document.createEvent) {
var e = document.createEvent('MouseEvents');
e.initEvent('click', true, true);
link.dispatchEvent(e);
return true;
}
} // Force file download (whether supported by server).
if(sUrl.indexOf('?') === -1) {
sUrl += '?download';
} window.open(sUrl, '_self');
return true;
} window.downloadFile.isChrome = navigator.userAgent.toLowerCase().indexOf('chrome') > -1;
window.downloadFile.isSafari = navigator.userAgent.toLowerCase().indexOf('safari') > -1;
方法调用:
downloadFile("../assets/template/Template.xlsx");
二. 数据导入
1. 导入按钮:

<div class="btn-group" style="text-align:right;width:82px">
<label class="input-group-btn">
<input id="btnSelectData" type="file" name="file" accept="application/vnd.ms-excel,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" style="left: -9999px; position: absolute;">
<span class="btn btn-default" style="border-radius:3px">导入会员</span>
</label>
</div>
2. 导入按钮事件
// 选择文件事件
$("#btnSelectData").change(function (e) {
var file = e.target.files[0] || e.dataTransfer.files[0];
if (file) {
$.bootstrapLoading.start(
{
loadingTips: "正在处理数据,请稍候...",
opacity: 0.8,
//loading页面透明度
backgroundColor: "#000",
TipsColor: "#555",
});
// 获取文件资源
var file = document.getElementById("btnSelectData").files[0];
var formData = new FormData();
formData.append('ExcelData', file);
// 保存信息
$.ajax({
type: "POST",
async: true,
url: "@Url.Content("~/Client/ImportClientData")",
data: formData,
contentType: false,
processData: false,
mimeType: "multipart/form-data",
success: function (response) {
response = $.parseJSON(response);
var option = {
message: response.ResultMessage,
title: response.ResultTitle
};
Ewin.alert(option);
if (response.ResultTitle == "Success") {
$('.message-dialog').on('hide.bs.modal', function () {
refresh();
});
}
},
complete: function () {
$.bootstrapLoading.end();
$("#btnSelectData").val('');
}
});
}
});
其中$.bootstrapLoading 是Loading功能,导入过程中等待界面,需要导入PerfectLoad.js
3. Controller方法
/// <summary>
/// 导入文件
/// </summary>
/// <returns></returns>
public JsonResult ImportClientData()
{
string result = String.Empty;
String fileName = String.Empty;
// 员工信息
List<ClientDomain> lsClient = new List<ClientDomain>();
try
{
if (Request.Files.Count > 0)
{
HttpPostedFileBase file = Request.Files["ExcelData"];
String filePath = @"../Upload/TempData/";
if (Directory.Exists(Server.MapPath(filePath)) == false)//如果不存在就创建file文件夹
{
Directory.CreateDirectory(Server.MapPath(filePath));
}
fileName = Server.MapPath(filePath) + file.FileName + "_" + DateTime.Now.ToString("yyyyMMddHHmmss") + Path.GetExtension(file.FileName);
file.SaveAs(fileName);
// 解析XML文件
//读取xml
XmlDocument xdoc = new XmlDocument();
xdoc.Load(Server.MapPath("/App_Data/ExcelTemplate.xml"));
XmlElement root = xdoc.DocumentElement; //获取根节点
XmlNode node = xdoc.SelectSingleNode("/Functions/Function[@name='Client']");
// 字段列表
List<ExcelField> lsExcelFields = new List<ExcelField>();
foreach (XmlNode item in node.ChildNodes)
{
String columnName = item.SelectSingleNode("columnName").InnerText;
String fieldName = item.SelectSingleNode("fieldName").InnerText;
lsExcelFields.Add(new ExcelField() { ColumnName = columnName, FieldName = fieldName });
}
// 获取Excel信息
for (int iIndex = 0; iIndex < NPOIHelper.GetNumberOfSheets(fileName); iIndex++)
{
// Read the CLP head information
DataTable dtDatas = NPOIHelper.ReadExcel(fileName, iIndex, 0, 0);
if (dtDatas == null)
throw new Exception("Read excel error.");
ClientDomain client = null;
for (Int32 iRow = 0; iRow < dtDatas.Rows.Count; iRow++)
{
client = new ClientDomain();
// 遍历所有属性
lsExcelFields.ForEach(item =>
{
String sValue = dtDatas.Rows[iRow][item.ColumnName].ToString();
Type t = client.GetType();
PropertyInfo propertyInfo = t.GetProperty(item.FieldName);
if (propertyInfo.PropertyType == typeof(DateTime) || propertyInfo.PropertyType == typeof(DateTime?))
{
if (!String.IsNullOrEmpty(sValue))
{
propertyInfo.SetValue(client, DateTime.Parse(sValue), null);
}
}
else if (propertyInfo.PropertyType == typeof(Decimal) || propertyInfo.PropertyType == typeof(Decimal?))
{
propertyInfo.SetValue(client, Decimal.Parse(sValue), null);
}
else if (propertyInfo.PropertyType == typeof(Int32) || propertyInfo.PropertyType == typeof(Int32?))
{
propertyInfo.SetValue(client, Int32.Parse(sValue), null);
}
else
{
propertyInfo.SetValue(client, sValue, null);
}
});
lsClient.Add(client);
}
}
}
//保存员工
result = service.SaveImportDatas(lsClient, CurrentLoginUser);
// 删除临时文件
CommonMethod.DeleteFile(fileName);
if (String.IsNullOrEmpty(result))
{
LogHelper.LogOperate(String.Format("导入会员信息{0}条", lsClient.Count), Constant.OPEARTE_LOG_INFO, CurrentLoginUser);
return new JsonResult()
{
JsonRequestBehavior = JsonRequestBehavior.AllowGet,
Data = new { ResultTitle = Constant.Result_Title_Success, ResultMessage = String.Format(MessageConstant.MESSAGE_IMPORT_SUCCESS, lsClient.Count) }
};
}
else
{
LogHelper.LogOperate(String.Format("导入会员信息失败:{0}", result), Constant.OPEARTE_LOG_WARNING, CurrentLoginUser);
return new JsonResult()
{
JsonRequestBehavior = JsonRequestBehavior.AllowGet,
Data = new { ResultTitle = Constant.Result_Title_Warning, ResultMessage = result }
};
}
}
catch (Exception ex)
{
Log.SaveException(ex);
return new JsonResult()
{
JsonRequestBehavior = JsonRequestBehavior.AllowGet,
Data = new { ResultTitle = Constant.Result_Title_Error, ResultMessage = ex.Message }
};
}
finally
{
// 删除临时文件
CommonMethod.DeleteFile(fileName);
}
}
ExcelField.cs
/// <summary>
/// Excel Field
/// </summary>
[Serializable]
[DataContract]
public class ExcelField
{
[DataMember]
public String ColumnName { get; set; } [DataMember]
public String FieldName { get; set; }
}
ExcelTemplate.xml
<?xml version="1.0" encoding="utf-8" ?>
<Functions>
<Function name="Client">
<field>
<columnName>卡号</columnName>
<fieldName>CardNo</fieldName>
</field>
<field>
<columnName>姓名</columnName>
<fieldName>UserName</fieldName>
</field>
<field>
<columnName>性别</columnName>
<fieldName>Sex</fieldName>
</field>
<field>
<columnName>出生日期</columnName>
<fieldName>Birthdate</fieldName>
</field>
<field>
<columnName>手机号</columnName>
<fieldName>Phone</fieldName>
</field>
<field>
<columnName>地址</columnName>
<fieldName>Address</fieldName>
</field>
<field>
<columnName>积分</columnName>
<fieldName>Score</fieldName>
</field>
<field>
<columnName>等级</columnName>
<fieldName>GradeCode</fieldName>
</field>
</Function>
</Functions>
导入数据到数据库
/// <summary>
/// 导入数据
/// </summary>
/// <param name="manager"></param>
/// <param name="lsClient"></param>
/// <param name="user"></param>
/// <returns></returns>
public string SaveImportDatas(DBManager manager, List<ClientDomain> lsClient, LoginUser user)
{
Int32 iCount = 50;
Int32 iRunSize = (lsClient.Count / iCount) + 1;
List<ClientDomain> newList = null;
string result = String.Empty;
String sUserId = user.RolesName;
try
{
var waits = new List<EventWaitHandle>();
for (Int32 iIndex = 0; iIndex < iRunSize; iIndex++)
{
//计算每个线程执行的数据
Int32 startIndex = (iIndex * iCount);
Int32 iPage = iCount;
if ((lsClient.Count - startIndex) < iCount)
{
iPage = (lsClient.Count - startIndex);
}
newList = lsClient.GetRange(startIndex, iPage);
var handler = new ManualResetEvent(false);
waits.Add(handler);
ParamModel data = new ParamModel();
data.UserId = sUserId;
data.Data = newList;
data.manager = manager;
new Thread(new ParameterizedThreadStart(ImportData)).Start(new Tuple<ParamModel, EventWaitHandle>(data, handler));
WaitHandle.WaitAll(waits.ToArray());
}
}
catch (Exception ex)
{
Log.SaveException(ex);
result = ex.Message;
}
return result;
} /// <summary>
/// 导入数据
/// </summary>
/// <param name="obj"></param>
private void ImportData(Object obj)
{
var p = (Tuple<ParamModel, EventWaitHandle>)obj;
ParamModel param = p.Item1 as ParamModel;
String sUserId = param.UserId;
DBManager manager = param.manager;
List<ClientDomain> models = param.Data as List<ClientDomain>;
models.ForEach(model =>
{
List<ClientDomain> clients = ClientBiz.GetDomainByExactFilter(new ClientFilter() { CardNo = model.CardNo }) as List<ClientDomain>;
if (clients == null || clients.Count == 0)
{
// 添加
model.CreateUser = sUserId;
model.CreateDateTime = DateTime.Now;
model.UpdateUser = sUserId;
model.UpdateDateTime = DateTime.Now; String sql = DataHelper.GenerateInsertSQL(DbTableName.Client, model, new LoginUser() { Uid = sUserId }, DateTime.Now); manager.Execute(sql, model);
}
else
{
// 更新
model.Id = clients[0].Id;
model.CreateUser = clients[0].CreateUser;
model.CreateDateTime = clients[0].CreateDateTime;
model.UpdateUser = sUserId;
model.UpdateDateTime = DateTime.Now; String sql = DataHelper.GenerateUpdateAllFieldSQL(DbTableName.Client, model, new LoginUser() { Uid = sUserId }, DateTime.Now); manager.Execute(sql, model);
}
});
p.Item2.Set();
}
以上,数据导入功能完成。
以下程序运行效果



PS: 在Excel导入时,也可以在ExcelTemplate.xml中配置一些字段Check的问题
例如:
<field>
<columnName>卡号</columnName>
<fieldName>CardNo</fieldName>
<checkList>
<!--NotNull:非空 Length:字段长度 Type:字段类型-->
<NotNull>Y</NotNull>
<Length>20</Length>
<Type></Type>
</checkList>
</field>
ExcelField.cs & CheckModel.cs
/// <summary>
/// Excel 字段
/// </summary>
public class ExcelField
{
/// <summary>
/// Excel列名
/// </summary>
[DataMember]
public String ColumnName { get; set; }
/// <summary>
/// 字段名称
/// </summary>
[DataMember]
public String FieldName { get; set; }
/// <summary>
/// 检测
/// </summary>
[DataMember]
public CheckModel CheckModel { get; set; }
} /// <summary>
/// 检查项目
/// </summary>
public class CheckModel
{
/// <summary>
/// 非空
/// </summary>
[DataMember]
public String NotNull { get; set; }
/// <summary>
/// 字段长度检测
/// </summary>
[DataMember]
public Int32 Length { get; set; }
/// <summary>
/// 字段类型
/// </summary>
[DataMember]
public String Type { get; set; }
}
字段信息获取以及字段检查方法
/// <summary>
/// 获取所有Excel字段
/// </summary>
/// <param name="functionName">功能名</param>
/// <returns></returns>
public static List<ExcelField> GetExcelFields(String functionName)
{
// 解析XML文件
//读取xml
XmlDocument xdoc = new XmlDocument();
xdoc.Load("Content/ExcelTemplate.xml");
XmlElement root = xdoc.DocumentElement; //获取根节点
XmlNode node = xdoc.SelectSingleNode(String.Format("/Functions/Function[@name='{0}']", functionName));
// 字段列表
List<ExcelField> lsExcelFields = new List<ExcelField>();
foreach (XmlNode item in node.ChildNodes)
{
String columnName = item.SelectSingleNode("columnName").InnerText;
String fieldName = item.SelectSingleNode("fieldName").InnerText;
ExcelField excelField = new ExcelField();
// 列名
excelField.ColumnName = columnName;
// 字段名
excelField.FieldName = fieldName;
XmlNodeList childNode = item.SelectNodes("checkList");
if (childNode != null && childNode.Count != 0)
{
CheckModel check = new CheckModel();
// 非空判断
check.NotNull = childNode[0].SelectSingleNode(Constant.Check_NotNull) == null ? "" : (childNode[0].SelectSingleNode(Constant.Check_NotNull).FirstChild == null ? "" : childNode[0].SelectSingleNode(Constant.Check_NotNull).FirstChild.Value);
// 长度判断
check.Length = childNode[0].SelectSingleNode(Constant.Check_Length) == null ? -1 : (childNode[0].SelectSingleNode(Constant.Check_Length).FirstChild == null ? -1 : Int32.Parse(childNode[0].SelectSingleNode(Constant.Check_Length).FirstChild.Value));
// 字段类型
check.Type = childNode[0].SelectSingleNode(Constant.Check_Type) == null ? "" : (childNode[0].SelectSingleNode(Constant.Check_Type).FirstChild == null ? "" : childNode[0].SelectSingleNode(Constant.Check_Type).FirstChild.Value);
excelField.CheckModel = check;
}
lsExcelFields.Add(excelField);
} return lsExcelFields;
} /// <summary>
/// 检查字段
/// </summary>
/// <param name="excel"></param>
/// <param name="value"></param>
/// <param name="iRowIndex"></param>
/// <returns></returns>
public static String CheckFieldValue(ExcelField excel, String value, Int32 iRowIndex)
{
StringBuilder sb = new StringBuilder();
try
{
// 非空判断
if (Constant.NotNull_Y.Equals(excel.CheckModel.NotNull) && String.IsNullOrEmpty(value))
{
sb.AppendLine(String.Format("第{0}行,{1}列值不能为空。", iRowIndex, excel.ColumnName));
}
// 长度判断
if (excel.CheckModel.Length != -1 && (!String.IsNullOrWhiteSpace(value) && value.Length > excel.CheckModel.Length))
{
sb.AppendLine(String.Format("第{0}行,{1}列值长度不能超过{2}。", iRowIndex, excel.ColumnName, excel.CheckModel.Length));
}
// 类型判断
if (!String.IsNullOrWhiteSpace(excel.CheckModel.Type))
{
// 正则表达式
String pattern = String.Empty;
// 表达式结果
Boolean bResult = true;
switch (excel.CheckModel.Type)
{
// 正整数判断
case Constant.Type_PositiveInteger:
pattern = @"^[0-9]*[1-9][0-9]*$";
bResult = Regex.IsMatch(value ?? "", pattern);
if (!bResult)
{
sb.AppendLine(String.Format("第{0}行,{1}列值应该输入正整数。", iRowIndex, excel.ColumnName));
}
break;
case Constant.Type_Telephone:
pattern = @"(/(/d{3,4}/)|/d{3,4}-|/s)?/d{7,14}";
bResult = Regex.IsMatch(value ?? "", pattern);
if (!bResult)
{
sb.AppendLine(String.Format("第{0}行,{1}列值应该输入正确电话号码。", iRowIndex, excel.ColumnName));
}
break;
case Constant.Type_Email:
pattern = @"^[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+$";
bResult = Regex.IsMatch(value ?? "", pattern);
if (!bResult)
{
sb.AppendLine(String.Format("第{0}行,{1}列值应该输入正确邮箱。", iRowIndex, excel.ColumnName));
}
break;
}
}
return sb.ToString().Trim();
}
catch (Exception ex)
{
return ex.Message;
}
} /// <summary>
/// 设置属性值
/// </summary>
/// <param name="obj">对象</param>
/// <param name="fieldName">字段名</param>
/// <param name="value">字段值</param>
public static void SetPropertyInfoValue(Object obj,String fieldName, String value)
{
Type t = obj.GetType();
PropertyInfo propertyInfo = t.GetProperty(fieldName);
// 时间类型
if (propertyInfo.PropertyType == typeof(DateTime) || propertyInfo.PropertyType == typeof(DateTime?))
{
if (!String.IsNullOrEmpty(value))
{
DateTime dt;
if (DateTime.TryParse(value, out dt))
{
propertyInfo.SetValue(obj, dt, null);
}
}
}
// Decimal 类型
else if (propertyInfo.PropertyType == typeof(Decimal)|| propertyInfo.PropertyType == typeof(Decimal?))
{
if (!String.IsNullOrEmpty(value))
{
Decimal dValue;
if (Decimal.TryParse(value, out dValue))
{
propertyInfo.SetValue(obj, dValue, null);
}
}
}
// Int32 类型
else if (propertyInfo.PropertyType == typeof(Int32) || propertyInfo.PropertyType == typeof(Int32?))
{
if (!String.IsNullOrEmpty(value))
{
Int32 iValue;
if (Int32.TryParse(value, out iValue))
{
propertyInfo.SetValue(obj, iValue, null);
}
}
}
else
{
propertyInfo.SetValue(obj, value, null);
}
}
.NET MVC 学习笔记(六)— 数据导入的更多相关文章
- ArcGIS案例学习笔记_3_2_CAD数据导入建库
ArcGIS案例学习笔记_3_2_CAD数据导入建库 计划时间:第3天下午 内容:CAD数据导入,建库和管理 目的:生成地块多边形,连接属性,管理 问题:CAD存在拓扑错误,标注位置偏移 教程:pdf ...
- 1.4(Spring MVC学习笔记)JSON数据交互与RESTful支持
一.JSON数据交互 1.1JSON简介 JSON(JavaScript Object Notation)是一种数据交换格式. 1.2JSON对象结构 {}代表一个对象,{}中写入数据信息,通常为ke ...
- Spring MVC 学习笔记11 —— 后端返回json格式数据
Spring MVC 学习笔记11 -- 后端返回json格式数据 我们常常听说json数据,首先,什么是json数据,总结起来,有以下几点: 1. JSON的全称是"JavaScript ...
- GIS案例学习笔记-CAD数据分层导入现有模板实例教程
GIS案例学习笔记-CAD数据分层导入现有模板实例教程 联系方式:谢老师,135-4855-4328,xiexiaokui#qq.com 1. 原始数据: CAD数据 目标模板 2. 任务:分5个图层 ...
- ASP.NET MVC 学习笔记-7.自定义配置信息 ASP.NET MVC 学习笔记-6.异步控制器 ASP.NET MVC 学习笔记-5.Controller与View的数据传递 ASP.NET MVC 学习笔记-4.ASP.NET MVC中Ajax的应用 ASP.NET MVC 学习笔记-3.面向对象设计原则
ASP.NET MVC 学习笔记-7.自定义配置信息 ASP.NET程序中的web.config文件中,在appSettings这个配置节中能够保存一些配置,比如, 1 <appSettin ...
- MVC学习笔记(三)—用EF向数据库中添加数据
1.在EFDemo文件夹中添加Controllers文件夹(用的是上一篇MVC学习笔记(二)—用EF创建数据库中的项目) 2.在Controllers文件夹下添加一个空的控制器(StudentsCon ...
- Spring MVC 学习笔记12 —— SpringMVC+Hibernate开发(1)依赖包搭建
Spring MVC 学习笔记12 -- SpringMVC+Hibernate开发(1)依赖包搭建 用Hibernate帮助建立SpringMVC与数据库之间的联系,通过配置DAO层,Service ...
- .NET MVC 学习笔记(三)— MVC 数据显示
. NET MVC 学习笔记(三)—— MVC 数据显示 在目前做的项目中,用的最多的数据展示控件就是table展示(说不是的请走开,不是一路人),以下详细阐述下table的使用方法. 先看效果: 上 ...
- java之jvm学习笔记六-十二(实践写自己的安全管理器)(jar包的代码认证和签名) (实践对jar包的代码签名) (策略文件)(策略和保护域) (访问控制器) (访问控制器的栈校验机制) (jvm基本结构)
java之jvm学习笔记六(实践写自己的安全管理器) 安全管理器SecurityManager里设计的内容实在是非常的庞大,它的核心方法就是checkPerssiom这个方法里又调用 AccessCo ...
随机推荐
- linux文件系统问题:wrong fs type, bad option, bad superblock
http://blog.itpub.net/26006637/viewspace-1059946/ 报错内容: mount: wrong fs type, bad option, bad superb ...
- 初识python函数
一.函数 1.什么是函数 函数是对功能或者动作的封装 2.函数的语法和定义 def 函数名(): 函数体 调用: 函数名() 3.关于函数的返回值 return : 返回 1.当程序没写过retur ...
- samba服务和nginx服务
一 samba服务 1 samba的功能:samba是一个网络服务器,是连接linux和windows之间共享文件的. 2 samba服务的启动,停止和重启: (1) 要启动Samba服务,只需用户 ...
- Our Future
The world is betting on how to win the football game: But I'm betting on how to win your heart: Mayb ...
- 2019.01.20 bzoj3999: [TJOI2015]旅游(树链剖分)
传送门 树链剖分菜题. 题意不清差评. 题意简述(保证清晰):给一棵带权的树,每次从aaa走到bbb,在走过的路径上任意找两个点,求后访问的点与先访问的点点权差的最大值. 思路: 考虑暴力:维护路径的 ...
- sqlserver 修改数据库表所有者
SQLServer修改表所有者 来自:http://www.cnblogs.com/tearer/archive/2012/09/16/2687802.html 批量修改:EXEC sp_MSfor ...
- git 版本库拆分和subtree用法
git 版本库拆分 原文地址: https://segmentfault.com/a/1190000002548731 程序员最爽的事情是什么?删删删!所有项目本来都很苗条的,时间长了难免有一些越搞越 ...
- js实现百度搜索框滑动固定顶部
现在很多主流系统例如百度.有道.爱奇艺等的搜索框都有一个特点,滑动到刚好看不到搜索框时,固定搜索框到顶部,这也算是一个对用户友好型的操 作. 在看了百度的js和css后自己摸索出来实现效果,还是学艺不 ...
- AngularJS监听数组变化
我们在使用angualr的监听时候,业务的需要我们会去监听一个数组的某一个值得变化,再写逻辑代码.然而我们在使用$scope.$watch("",function(){ })时候会 ...
- AtCoder Beginner Contest-060
A - Shiritori Problem Statement You are given three strings A, B and C. Check whether they form a wo ...