.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 学习笔记(六)— 数据导入的更多相关文章

  1. ArcGIS案例学习笔记_3_2_CAD数据导入建库

    ArcGIS案例学习笔记_3_2_CAD数据导入建库 计划时间:第3天下午 内容:CAD数据导入,建库和管理 目的:生成地块多边形,连接属性,管理 问题:CAD存在拓扑错误,标注位置偏移 教程:pdf ...

  2. 1.4(Spring MVC学习笔记)JSON数据交互与RESTful支持

    一.JSON数据交互 1.1JSON简介 JSON(JavaScript Object Notation)是一种数据交换格式. 1.2JSON对象结构 {}代表一个对象,{}中写入数据信息,通常为ke ...

  3. Spring MVC 学习笔记11 —— 后端返回json格式数据

    Spring MVC 学习笔记11 -- 后端返回json格式数据 我们常常听说json数据,首先,什么是json数据,总结起来,有以下几点: 1. JSON的全称是"JavaScript ...

  4. GIS案例学习笔记-CAD数据分层导入现有模板实例教程

    GIS案例学习笔记-CAD数据分层导入现有模板实例教程 联系方式:谢老师,135-4855-4328,xiexiaokui#qq.com 1. 原始数据: CAD数据 目标模板 2. 任务:分5个图层 ...

  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 ...

  6. MVC学习笔记(三)—用EF向数据库中添加数据

    1.在EFDemo文件夹中添加Controllers文件夹(用的是上一篇MVC学习笔记(二)—用EF创建数据库中的项目) 2.在Controllers文件夹下添加一个空的控制器(StudentsCon ...

  7. Spring MVC 学习笔记12 —— SpringMVC+Hibernate开发(1)依赖包搭建

    Spring MVC 学习笔记12 -- SpringMVC+Hibernate开发(1)依赖包搭建 用Hibernate帮助建立SpringMVC与数据库之间的联系,通过配置DAO层,Service ...

  8. .NET MVC 学习笔记(三)— MVC 数据显示

    . NET MVC 学习笔记(三)—— MVC 数据显示 在目前做的项目中,用的最多的数据展示控件就是table展示(说不是的请走开,不是一路人),以下详细阐述下table的使用方法. 先看效果: 上 ...

  9. java之jvm学习笔记六-十二(实践写自己的安全管理器)(jar包的代码认证和签名) (实践对jar包的代码签名) (策略文件)(策略和保护域) (访问控制器) (访问控制器的栈校验机制) (jvm基本结构)

    java之jvm学习笔记六(实践写自己的安全管理器) 安全管理器SecurityManager里设计的内容实在是非常的庞大,它的核心方法就是checkPerssiom这个方法里又调用 AccessCo ...

随机推荐

  1. ubuntu系统ftp连接 以及ssh连接

    tfp连接 ssh连接 ubuntu下ssh使用 与 SCP 使用 1 ssh远程登录服务器 ssh username@remote_ip #将username换成自己的用户名,将remote_ip换 ...

  2. maven 介绍(zz )

    Maven 编辑     目录 1简介 2特点 3常用命令 4推荐书籍 5Win7配置 6生命周期     1   1简介 Maven是基于项目对象模型(POM),可以通过一小段描述信息来管理项目的构 ...

  3. Spark学习笔记-GraphX-1

    Spark学习笔记-GraphX-1 标签: SparkGraphGraphX图计算 2014-09-29 13:04 2339人阅读 评论(0) 收藏 举报  分类: Spark(8)  版权声明: ...

  4. linux文件系统问题:wrong fs type, bad option, bad superblock

    http://blog.itpub.net/26006637/viewspace-1059946/ 报错内容: mount: wrong fs type, bad option, bad superb ...

  5. kbmmw 5.04 发布

    增加了一大波功能,消灭了一大堆问题,也肯定引进了一大票BUG.We are happy to announce the release of our latest version of kbmMW. ...

  6. 796. Rotate String

    class Solution { public: bool rotateString(string A, string B) { if(A.length()==B.length()&& ...

  7. 删除GitHub中的项目

    1.找到要删除的项目 2.点击settings,下拉到底部 3.点击delete this repository,输入你要删除的项目名称

  8. java常用设计模式四:观察者模式

    1.定义 观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一主题对象.这个主题对象在状态发生变化时,会通知所有观察者对象,使它们能够自动更新自己.观察者模式又叫发布-订阅(Publis ...

  9. ubuntu上安装win7系统(64位的)

    http://www.linuxidc.com/Linux/2012-11/74195.htm deb文件在ubuntu上直接用dpkg -i xxx.deb 如果虚拟机上只显示32位,则可能是cpu ...

  10. python:OS模块

    r"""OS routines for NT or Posix depending on what system we're on. This exports: - al ...