您可以捐助,支持我们的公益事业。

1元 10元 50元





认证码:  验证码,看不清楚?请点击刷新验证码 必填



  求知 文章 文库 Lib 视频 iPerson 课程 认证 咨询 工具 讲座 Modeler   Code  
会员   
 
   
 
 
     
   
 订阅
  捐助
Asp.NET MVC 导入Excel数据教程 手把手教你系列!!!
 
作者:狂扁小朋友 来源:微信公众号 发布于:2016-9-5
  10472  次浏览      32
 

先上效果图

1.引言

小弟最近接了个大学生的毕业设计,收了100块钱让做一个ASP.NET MVC导入Excel到数据库的功能,由于以前没做过就到处搜索资料,但是发现网上的资料不是直接贴一大堆乱起八遭的源码,就是需要借用NPOI第三方类库太麻烦了,况且预算才100RMB简直不值得,所以小弟尝试自己动手丰衣足食,所以就有了这篇博客。

先上一张小弟的思路图:

(说明:没有安装做流程图的软件!凑合着看吧)

2 进入正题

首先跟着小弟先创建一个默认的MVC项目(相信大家都会创建,这里就不演示了)

第一步

创建一个实体类,这个类是要导入数据库的对象。为了简单起见 小弟创建了个学生对象(记录了他的名字、年龄、各科成绩分数)。

先声明这只是教学代码,完全是为了演示用的,你真正做产品的代码可没这么简单的定义实体。

 
1  public class Student
2     {
3 
4        public Student()
5        {
6            Id = Guid.NewGuid();
7        }
8 
9         //姓名
10         public string Name { get; set; }
11 
12         //年龄
13         public int Age { get; set; }
14 
15         //语文成绩
16         public int ChineseScore { get; set; }

17 //英文成绩 19 public int EnglishScore { get; set; } 20 21 //数学成绩 22 public int MathScore { get; set; } 23 24 25 }

第二步

实体创建完了,接下来我们创建一个Empty的控制器(名字取自己喜欢的),(这个也太简单了,我这里就不演示了)直接上结果:

小弟在这里创建了个名为UploadExcelController的控制器

 
1    public class UploadExcelController : Controller
2    {
3          // GET: /UploadExcel
4          public ActionResult Index()
5          {
6          return View();
7          }
8          }

第三步

控制器创建完了接下来做什么呢?估计你也猜到了,所有的不是从界面开始吗!用户访问/UploadExcel/Index 的时候总要出来个交互的东西吧。那就先创建一个交互的视图,光标移到return View();右键创建添加视图

创建视图有很多种方法,我这里只是选择了种简单的具体看个人习惯创建。

视图创建完毕后,我们先构造一个浏览文件的html标记

 
1     @{
2     ViewBag.Title = "View";
3     }
4 
5      <h1>Select the Excel file</h1>
6 
7 
8      <div class="input-group ">
9      @*文件路径的文本框*@
10     <input id="txt_Path" type="text" class="form-control"> 
11 
12      @*浏览本地文件按钮*@
13     <span id="btn_Browse" style="cursor:pointer;" onclick="
       $('input[id=fileUpload]').click();" class="input-group-addon">
14      <i class="glyphicon glyphicon-folder-open"></i>&nbsp;&nbsp;&nbsp;浏览文件
15     </span>
16      </div>

小弟这里使用的是MVC自带的bootstrap框架,相信大家也都能看懂,如果看不懂那些标记的话!建议你先花1天时间入门bootstap框架。

这个时候的效果图应该是这样的

在上传文件到服务器有个常用的html标记是 <input id="fileUpload" type="file" >,没错小弟也用的这个标记,只是它太丑了我把它给隐藏了!用我上面的html标记给替换了。接下来我们开始创建它。

1 <h1>Select the Excel file</h1>
2 
3 
4 <div class="input-group ">
5      @*文件路径的文本框*@
6     <input id="txt_Path" type="text" class="form-control"> 
7 
8      @*浏览本地文件按钮*@
9     <span id="btn_Browse" style="cursor:pointer;" 
      onclick="$('input[id=fileUpload]').click();
    " class="input-group-addon">
10         <i class="glyphicon glyphicon-folder-open"
          ></i>&nbsp;&nbsp;&nbsp;浏览文件
11     </span>
12 </div>
13 
14 <br /><br />
15 
16 
17 @using (Html.BeginForm("Browse", "UploadExcel", 
   FormMethod.Post, new { enctype = "multipart/form-data   ", id = "form_Upload" }))
18 {
19     @Html.AntiForgeryToken() 
   //防止跨站请求伪造(CSRF:Cross-site request forgery)攻击
20     <input id="fileUpload" type="file" name="file" st
       yle="display:none"> //把fileUpload隐藏,原因它太难看了
                          21 }							

红色的代码是新增的,Html.BeginForm的扩展方法如果大家不熟悉的话,你就把它看成form表单,因为它最后会生成form表单

<form id="form_Upload" action="/UploadExcel/Browse" method="post" enctype="multipart/form-data">

.......

</form>

哦!这个是基础知识,相信大家也都知道,(题外话:在能使用@HTML扩展方法的时候,我建议大家不要使用原生的HTML标记,为什么呢?因为如果你了解@HTML扩展方法的运行机制的话你就知道我的用意了, 就比如Html.BeginForm它是根据路由去生成的URL,智能的!安全的!如果自己写原生HTML标记的话,难免会产生不安全的URL!)

这个form表单就是我们把Excel文件上传到服务器用的, 看见form表单的 action="/UploadExcel/Browse",所以我们还要在UploadExcelController控制器里创建第二个名称叫Browse的Action操作

红色部分是我新增加的Action操作,前面说了竟然创建的form表单是上传文件到服务器的,那么这个操作就是处理上传文件用的Action,因为它会改变服务器状态,所以我定义成Post方法。其余2个特性是配合@Html扩展方法用的,一个是防止跨站请求伪造(CSRF:Cross-site request forgery)攻击,一个是统一处理异常页。你也可以不加,跟我们今天的例子没关系。我们先不写这个Action操作的代码,让我们再次回到我们创建的视图页 。

竟然我们要使用 <input id="fileUpload" type="file" name="file">的功能,但是又嫌弃它太难看了!怎么办呢? So easy 只需把我们构造的html标记绑定它就行了。在视图页添加如下JS代码

这段JS代码功能就是在<input id="fileUpload" type="file" name="file" style="display:none">选择文件后就把文件路径赋给我们自己构造的文本框里,然后就是提交表单,上传它的选择的文件到我们的服务器。

请注意灰色那段代码是如何用我们自己构建的按钮绑定到fileUpload的功能上

 
1     @*浏览本地文件按钮*@
2     <span id="btn_Browse" style="cursor:pointer;"
      onclick="$('input[id=fileUpload]').click();" 
	  class="input-group-addon">
3     <i class="glyphicon glyphicon-folder-open
      "></i>&nbsp;&nbsp;&nbsp;浏览文件
4     </span>

现在就来测试下我们写的代码能不能跑!F5运行!如果是以下效果就是正确的

为了浏览文件有响应的效果,我们在视图页加一小段CSS代码

第五步

到了这里我们的文件已经可以上传到我们服务了,如果不信你在Browse操作打个断点,看看file参数是不是已经接受了文件,如果接受到了说明已经成功一半了!我们还是先不写Browse操作处理Excel文件的代码,焦点还是在视图页上,在本博客第一张效果图里,大家看到浏览文件下面有张table表格吗?小弟创建这个表格只是为了更好的交互效果,让使用的人更直观而已。而且也很简单!

接下来我们来构建它,在视图页新增table表格的代码

在这里我依然用的@HTML辅助方法,如果你还不会使用它,赶紧花一天学习它,入门非常简单!非常强大! 设想如果没有@Html扩展方法 小弟得写多少硬编码啊!

然后再次按F5运行先看看效果

这里的表头是英文的,如果你想变成中文的话,可以在实体上加上数据注解特性(如下)

对了还忘了一个东西,就是上传提交按钮,我们现在来构建它!在视图页form表单下面添加如下代码

							
1 @using (Html.BeginForm("Browse", "UploadExcel",
   FormMethod.Post, new { enctype = "multipart/form-data", id = "form_Upload" }))
2 {
3     @Html.AntiForgeryToken()
4     <input id="fileUpload" type="file"
      name="file" style="display:none"> 
5 }
6 
 //红色部分是我构建的上传提交按钮
7 <div class="input-group pull-right"
  style="margin:0 0 5px 0">
8     @Html.RouteLink("开始提交", new { action = "Upload" }, 
  new { id="submit", @class = "btn  btn-primary ladda-button ", 
  data_style = "expand-right" })
9 </div>

@Html.RouteLink扩展方法会根据我定义的路由生成一个<a>锚标签,最后生成如下html标记

<a id="submit" class="btn btn-primary ladda-button" data-style="expand-right" href="/UploadExcel/Upload" >开始提交</a>

在这里我把它伪装成了一个button按钮

data-style="expand-right"这些属性是我用bootstrap加了个5毛钱的特效,你也可以不用管,也可以使用自己的特效。这个上传提交按钮的功能就是最后一个功能,把经过Browse操作转换成List<T>的数 据导入到我们的数据库。到现在为止我们的导入Excel的页面已经全部完成了,当然我的审美观和前端技术就是渣渣,所以请原谅小弟! href="/UploadExcel/Upload" 这个<a>锚标签会访问UploadExcelController控制器的Upload操作,所以我再添加最后一个操作。在控制器添加如下代码

}

现在我们来检查下我们构造好的页面,F5运行。如果是下面的样子我们就全部完成视图页面了

现在我们把重点放在Excel文件的逻辑处理上了,我们先从Browse操作下手,因为此操作负责把我们上传的Excel文件转换成List Entity对象,只要转换成这个集合对象你后面就可以想怎么插入就怎么插入了 !想插入MSSQL MYSQL 等不同数据都可以呵呵!因为我们用的ORM框架!

按照我上传的那个思维图,我想我先处理验证!先判断文件的格式是不是Excel的格式。(Excel的格式是根据版本来的 2007-2010 是xlsx,2003是xls)这里我只默认了2007-2010 。

在Browse操作添加如下代码

我在MVC项目的根目录创建了个files的文件夹,用来保存上传的Excel文件。然后读取文件转换成List Entity对象,然后把它传给我们创建的视图。这样就可以一选择Excel文件就把数据显示在页面上了,转换数据的核心是这句代码

stus = ExcelHelper.ReadExcelToEntityList<Student>(savePath);

ExcelHelper是我自己封装的一个工具库,我现在来创建它。在根目录添加一个文件夹,然后添加一个类

 
ppublic class ExcelHelper
{
//Excel数据转List
public static IList 
ReadExcelToEntityList
(string filePath) where T : class, new()
{
DataTable tbl = ReadExcelToDataTable(filePath);
//读取Excel数据到DataTable
IList 
list = DataTableToList
(tbl);
return list;
}
//Excel数据转DataTable 使用的oledb读取方式
 public static DataTable
  ReadExcelToDataTable(string filePath)
{
if (filePath == string.Empty) 
throw new ArgumentNullException
("路径参数不能为空");
string ConnectionString = 
"Provider=Microsoft.ACE.OLEDB.12.0;
Persist Security Info=False;Data Source=
" + filePath + "; 
Extended Properties='Excel 8.0;HDR=Yes;IMEX=1'";
OleDbDataAdapter adapter
 = new OleDbDataAdapter("select * From[Sheet1$]",
  ConnectionString); //默认读取的Sheet1,
  你也可以把它封装变量,动态读取你的Sheet工作表
DataTable table = new DataTable("TempTable");
adapter.Fill(table);
return table;
       }

代码很简单我就不翻译了,就是读取Excel数据转各种C#对象,但是这是教学代码不是产品代码,我很粗暴的封装了。你如果要用到生成环境,得还要加上各种逻辑验证和测试!

好了到了这步,我们就可以出现下面的效果了:

写到这里,感觉最后一个功能把List<T>集合导入数据库大家应该都会,我就不想再继续往下写了。但是还是要说下注意的地方就是导入数据一定要支持事物回滚功能,就是哪怕前面已经导入了几十条数据了,如果发生一条脏数据导致插入异常,也必须回滚判定全部导入失败。避免重复导入,导致数据库脏数据。

我贴最后导入数据库的代码就是Upload操作,我在DAL层是使用了事物处理的,支持回滚!

   
10472 次浏览       32
 
相关文章

深度解析:清理烂代码
如何编写出拥抱变化的代码
重构-使代码更简洁优美
团队项目开发"编码规范"系列文章
 
相关文档

重构-改善既有代码的设计
软件重构v2
代码整洁之道
高质量编程规范
 
相关课程

基于HTML5客户端、Web端的应用开发
HTML 5+CSS 开发
嵌入式C高质量编程
C++高级编程
最新活动计划
嵌入式软件架构设计 12-11[北京]
LLM大模型与智能体开发实战 12-18[北京]
嵌入式软件测试 12-25[北京]
AI原生应用的微服务架构 1-9[北京]
AI大模型编写高质量代码 1-14[北京]
需求分析与管理 1-22[北京]

使用decj简化Web前端开发
Web开发框架形成之旅
更有效率的使用Visual Studio
MVP+WCF+三层结构搭建框架
ASP.NET运行机制浅析【图解】
编写更好的C#代码
10个Visual Studio开发调试技巧
更多...   

.NET框架与分布式应用架构设计
.NET & WPF & WCF应用开发
UML&.Net架构设计
COM组件开发
.Net应用开发
InstallShield

日照港 .NET Framework & WCF应用开发
神华信息 .NET单元测试
北京 .Net应用软件系统架构
台达电子 .NET程序设计与开发
赛门铁克 C#与.NET架构设计
广东核电 .Net应用系统架构
更多...