数据的导入导出,在很多系统里面都比较常见,这个导入导出的操作,在Winform里面比较容易实现,我曾经在之前的一篇文章《Winform开发框架之通用数据导入导出操作》介绍了在Winform里面的通用导入导出模块的设计和开发过程,但在Web上我们应该如何实现呢?本文主要介绍利用MVC4+EasyUI的特点,并结合文件上传控件Uploadify 的使用,实现文件上传后马上进行处理并显示,然后确认后把数据写入数据库的过程。

我们知道,Web上对Excel的处理和Winform的有所差异,如果是在Web上处理,我们需要把Excel文档上传到服务器上,然后读取文件进行显示,所以第一步是实现文件的上传操作,关于文件上传控件,具体可以参考我的文章《基于MVC4+EasyUI的Web开发框架形成之旅--附件上传组件uploadify的使用》。

1、导入数据的界面效果展示

在Winform里面,我们处理Excel数据导入的界面如下所示。

在Web上的主界面如下所示。

导入界面如下所示。

2、Web数据导入的处理逻辑和代码

为了实现Web上的数据导入导出操作,我们需要增加两个按钮,一个是导入按钮,一个是导出按钮。

  1. <a href="javascript:void(0)" class="easyui-linkbutton" id="btnImport" iconcls="icon-excel" onclick="ShowImport()">导入</a>
  2. <a href="javascript:void(0)" class="easyui-linkbutton" id="btnExport" iconcls="icon-excel" onclick="ShowExport()">导出</a>

导入的JS处理代码如下所示。

  1. //显示导入界面
  2. function ShowImport() {
  3. $.showWindow({
  4. title: '客户联系人-Excel数据导入',
  5. useiframe: true,
  6. width: 1024,
  7. height: 700,
  8. content: 'url:/Contact/Import',
  9. buttons: [{
  10. text: '取消',
  11. iconCls: 'icon-cancel',
  12. handler: function (win) {
  13. win.close();
  14. }
  15. }]
  16. });
  17. }

上面主要就是弹出一个窗口(上面的导入数据窗口),用来方便客户选择Excel文件并保存数据或者下载导入模板等操作的。

然后在Import.cshtml的视图代码里面,我们需要初始化Datagrid和相关的界面元素,初始化DataGrid的代码如下所示。

  1. //实现对DataGird控件的绑定操作
  2. function InitGrid() {
  3. var guid = $("#AttachGUID").val();
  4. $('#grid').datagrid({ //定位到Table标签,Table标签的ID是grid
  5. url: '/Contact/GetExcelData?guid=' + guid, //指向后台的Action来获取当前用户的信息的Json格式的数据
  6. title: '客户联系人-Excel数据导入',
  7. iconCls: 'icon-view',
  8. height: 400,
  9. width: function () { return document.body.clientWidth * 0.9 },//自动宽度
  10.  
  11. ..................

上面红色部分的内容,就是我们在文件顺利上传到服务器上的时候,根据一个guid的参数初始化DataGrid的列表数据。

下面是附件上传控件uploadify的初始化脚本代码,其中红色部分注意一下,我们需要上传的是一个文件,并且不允许多选,限定上传文件的类型为xls。

文件上传完成后,首先调用CheckExcelColumns控制器函数来检查是否匹配导入模板的字段,如果匹配通过,加载Excel并展示数据到Datagrid里面,否则提示用户按模板格式录入数据。

  1. <script type="text/javascript">
  2. $(function () {
  3. //添加界面的附件管理
  4. $('#file_upload').uploadify({
  5. 'swf': '/Content/JQueryTools/uploadify/uploadify.swf', //FLash文件路径
  6. 'buttonText': '浏 览', //按钮文本
  7. 'uploader': '/FileUpload/Upload', //处理ASHX页面
  8. 'queueID': 'fileQueue', //队列的ID
  9. 'queueSizeLimit': , //队列最多可上传文件数量,默认为999
  10. 'auto': false, //选择文件后是否自动上传,默认为true
  11. 'multi': false, //是否为多选,默认为true
  12. 'removeCompleted': true, //是否完成后移除序列,默认为true
  13. 'fileSizeLimit': '10MB', //单个文件大小,0为无限制,可接受KB,MB,GB等单位的字符串值
  14. 'fileTypeDesc': 'Excel Files', //文件描述
  15. 'fileTypeExts': '*.xls', //上传的文件后缀过滤器
  16. 'onQueueComplete': function (event, data) { //所有队列完成后事件
  17. var guid = $("#AttachGUID").val();
  18. ViewUpFiles(guid, "div_files");
  19.  
  20. //提示用户Excel格式是否正常,如果正常加载数据
  21. $.ajax({
  22. url: '/Contact/CheckExcelColumns?guid=' + guid,
  23. type: 'get',
  24. dataType:'json',
  25. success: function (data) {
  26. if (data.Success) {
  27. InitGrid(); //重新刷新表格数据
  28. $.messager.alert("提示", "文件已上传,数据加载完毕!");
  29. }
  30. else {
  31. $.messager.alert("提示", "上传的Excel文件检查不通过。请根据页面右上角的Excel模板格式进行数据录入。");
  32. }
  33. }
  34. });
  35. },
  36. 'onUploadStart': function (file) {
  37. InitUpFile();//上传文件前 ,重置GUID,每次不同
  38. $("#file_upload").uploadify("settings", 'formData', { 'folder': '数据导入文件', 'guid': $("#AttachGUID").val() }); //动态传参数
  39. },
  40. 'onUploadError': function (event, queueId, fileObj, errorObj) {
  41. //alert(errorObj.type + ":" + errorObj.info);
  42. }
  43. });
  44. });

为了有效处理数据的导入,我们需要严格保证导入的数据是和模板的字段是匹配的,否则处理容易出错,也没有任何意义。为了实现这个目的,框架里面提供方法对字段进行检查,主要是确保Excel里面包含了完整的字段即可。

  1. /// <summary>
  2. /// 检查Excel文件的字段是否包含了必须的字段
  3. /// </summary>
  4. /// <param name="guid">附件的GUID</param>
  5. /// <returns></returns>
  6. public ActionResult CheckExcelColumns(string guid)
  7. {
  8. CommonResult result = new CommonResult();
  9.  
  10. try
  11. {
  12. DataTable dt = ConvertExcelFileToTable(guid);
  13. if (dt != null)
  14. {
  15. //检查列表是否包含必须的字段
  16. result.Success = DataTableHelper.ContainAllColumns(dt, columnString);
  17. }
  18. }
  19. catch (Exception ex)
  20. {
  21. LogTextHelper.Error(ex);
  22. result.ErrorMessage = ex.Message;
  23. }
  24.  
  25. return ToJsonContent(result);
  26. }

而在InitGrid的初始化中的这个GetExcelData的控制器方法如下所示。主要的逻辑就是获取到Excel,并把Excel里面的数据转换为DataTable,最后初始化为实体类列表,并返回给调用页面就可以了。

  1. /// <summary>
  2. /// 获取服务器上的Excel文件,并把它转换为实体列表返回给客户端
  3. /// </summary>
  4. /// <param name="guid">附件的GUID</param>
  5. /// <returns></returns>
  6. public ActionResult GetExcelData(string guid)
  7. {
  8. if (string.IsNullOrEmpty(guid))
  9. {
  10. return null;
  11. }
  12.  
  13. List<ContactInfo> list = new List<ContactInfo>();
  14. DataTable table = ConvertExcelFileToTable(guid);
  15. if (table != null)
  16. {
  17. #region 数据转换
  18. int i = ;
  19. foreach (DataRow dr in table.Rows)
  20. {
  21. string customerName = dr["客户名称"].ToString();
  22. if (string.IsNullOrEmpty(customerName))
  23. {
  24. continue;//客户名称为空,记录跳过
  25. }
  26.  
  27. CustomerInfo customerInfo = BLLFactory<Customer>.Instance.FindByName(customerName);
  28. if (customerInfo == null)
  29. {
  30. continue;//客户名称不存在,记录跳过
  31. }
  32.  
  33. ContactInfo info = new ContactInfo();
  34. info.Customer_ID = customerInfo.ID;//客户ID
  35. info.HandNo = dr["编号"].ToString();
  36. info.Name = dr["姓名"].ToString();
  37. ..............................//增加一个特殊字段的转义
  38. info.Data1 = BLLFactory<Customer>.Instance.GetCustomerName(info.Customer_ID);
  39.  
  40. list.Add(info);
  41. }
  42. #endregion
  43. }
  44. var result = new { total = list.Count, rows = list };
  45. return JsonDate(result);
  46. }

3、Web上数据的导出操作

刚才介绍了数据的导入操作,数据的导出操作相对简单一些,它的JS函数操作如下所示。

  1. //导出Excel数据
  2. var exportCondition;
  3. function ShowExport() {
  4. var url = "/Contact/Export";
  5. $.ajax({
  6. type: "POST",
  7. url: url,
  8. data: exportCondition,
  9. success: function (filePath) {
  10. var downUrl = '/FileUpload/DownloadFile?file=' + filePath;
  11. window.location = downUrl;
  12. }
  13. });
  14. }

虽然数据的导出比较简单一点,但是由于我们需要使用POST方式对数据条件进行提交,因此不像普通的方式下载文件Window.Open(url)就可以实现文件下载了。如果POST方式提交了参数,那么返回的数据即使是文件流,也无法进行有效的下载。

从上面的脚本我们可以看到,里面的exportCondition就是我们需要提交到服务器的条件,服务器根据这个条件进行检索数据,并返回一个Excel文件就可以了。

由于使用ajax这种POST方式无法直接下载文件流,因此,我们需要先根据条件,在服务器上生成文件,返回一个文件路径,再次通过DownloadFile方法进行文件的下载才可以。

因此这个传递的条件也是很重要的,在查询操作的时候,我们可以把对应的条件传递给它。

  1. //绑定搜索按钮的的点击事件
  2. function BindSearchEvent() {
  3. //按条件进行查询数据,首先我们得到数据的值
  4. $("#btnSearch").click(function () {
  5. //得到用户输入的参数
  6. //取值有几种方式:$("#id").combobox('getValue'), $("#id").datebox('getValue'), $("#id").val(),combotree('getValue')
  7. //字段增加WHC_前缀字符,避免传递如URL这样的Request关键字冲突
  8. var queryData = {
  9. WHC_Name: $("#txtName").val(),
  10. WHC_OfficePhone: $("#txtOfficePhone").val(),
  11. WHC_Mobile: $("#txtMobile").val(),
  12. WHC_Address: $("#txtAddress").val(),
  13. WHC_Email: $("#txtEmail").val(),
  14. WHC_Note: $("#txtNote").val()
  15. }
  16. //将值传递给DataGrid
  17. InitGrid(queryData);
  18.  
  19. //传递给导出操作
  20. exportCondition = queryData;
  21. return false;
  22. });
  23. }

在我们选定某个树的节点的时候,我们也可以传递自定义的条件给它。

  1. //根据消息分组加载指定列表
  2. function loadByGroupTree(node) {
  3. //赋值给特殊字段,公司和部门查询的时候选择其中一个
  4. var queryParams = $('#grid').datagrid('options').queryParams;
  5. var condition = "{ id: \"" + node.id +"\", groupname:\"" + node.text +"\", userid:\"" + @Session["UserId"] + "\" }";
  6. queryParams.CustomedCondition = condition;//提供给datagrid的条件

  7. exportCondition = { CustomedCondition: condition };//提供给导出的条件
  8.  
  9. $("#grid").datagrid("reload");
  10. $('#grid').datagrid('uncheckAll');
  11. }

后台的Export控制器方法主要的逻辑如下所示。

最终是返回一个生成好的文件地址。

最后给一个方法直接下载文件就可以了。

  1. /// <summary>
  2. /// 根据路径下载文件,主要用于生成的文件的下载
  3. /// </summary>
  4. /// <param name="filePath">文件路径</param>
  5. /// <returns></returns>
  6. public ActionResult DownloadFile(string file)
  7. {
  8. string realPath = Server.MapPath(file);
  9. string saveFileName = FileUtil.GetFileName(realPath);
  10.  
  11. Response.WriteFile(realPath);
  12. Response.Charset = "GB2312";
  13. Response.ContentEncoding = Encoding.GetEncoding("GB2312");
  14. Response.ContentType = "application/ms-excel/msword";
  15. Response.AppendHeader("Content-Disposition", "attachment;filename=" + HttpUtility.UrlEncode(saveFileName));
  16. Response.Flush();
  17. Response.End();
  18.  
  19. return new FileStreamResult(Response.OutputStream, "application/ms-excel/msword");
  20. }

导出的Excel界面效果如下所示。

由于篇幅的原因,这个导入导出的操作就介绍到这里,希望有问题大家共同探讨。

基于MVC4+EasyUI的Web开发框架的系列文章:

基于MVC4+EasyUI的Web开发框架形成之旅--总体介绍

基于MVC4+EasyUI的Web开发框架形成之旅--MVC控制器的设计

基于MVC4+EasyUI的Web开发框架形成之旅--界面控件的使用

基于MVC4+EasyUI的Web开发框架形成之旅--附件上传组件uploadify的使用

基于MVC4+EasyUI的Web开发框架形成之旅--框架总体界面介绍

基于MVC4+EasyUI的Web开发框架形成之旅--基类控制器CRUD的操作

基于MVC4+EasyUI的Web开发框架形成之旅--权限控制

基于MVC4+EasyUI的Web开发框架经验总结(1)-利用jQuery Tags Input 插件显示选择记录

基于MVC4+EasyUI的Web开发框架经验总结(2)- 使用EasyUI的树控件构建Web界面

基于MVC4+EasyUI的Web开发框架经验总结(3)- 使用Json实体类构建菜单数据

基于MVC4+EasyUI的Web开发框架经验总结(4)--使用图表控件Highcharts

基于MVC4+EasyUI的Web开发框架经验总结(5)--使用HTML编辑控件CKEditor和CKFinder

基于MVC4+EasyUI的Web开发框架经验总结(6)--在页面中应用下拉列表的处理

基于MVC4+EasyUI的Web开发框架经验总结(7)--实现省份、城市、行政区三者联动

基于MVC4+EasyUI的Web开发框架经验总结(8)--实现Office文档的预览

基于MVC4+EasyUI的Web开发框架经验总结(9)--在Datagrid里面实现外键字段的转义操作

基于MVC4+EasyUI的Web开发框架经验总结(10)--在Web界面上实现数据的导入和导出

基于MVC4+EasyUI的Web开发框架经验总结(11)--使用Bundles处理简化页面代码

基于MVC4+EasyUI的Web开发框架经验总结(12)--利用Jquery处理数据交互的几种方式

基于MVC4+EasyUI的Web开发框架经验总结(13)--DataGrid控件实现自动适应宽带高度

基于MVC4+EasyUI的Web开发框架经验总结(14)--自动生成图标样式文件和图标的选择操作

基于MVC4+EasyUI的Web开发框架经验总结(10)--在Web界面上实现数据的导入和导出的更多相关文章

  1. (转)基于MVC4+EasyUI的Web开发框架经验总结(10)--在Web界面上实现数据的导入和导出

    http://www.cnblogs.com/wuhuacong/p/3873498.html 数据的导入导出,在很多系统里面都比较常见,这个导入导出的操作,在Winform里面比较容易实现,我曾经在 ...

  2. 基于MVC4+EasyUI的Web开发框架经验总结(12)--利用Jquery处理数据交互的几种方式

    在基于MVC4+EasyUI的Web开发框架里面,大量采用了Jquery的方法,对数据进行请求或者提交,方便页面和服务器后端进行数据的交互处理.本文主要介绍利用Jquery处理数据交互的几种方式,包括 ...

  3. (转)基于MVC4+EasyUI的Web开发框架经验总结(12)--利用Jquery处理数据交互的几种方式

    http://www.cnblogs.com/wuhuacong/p/4085682.html 在基于MVC4+EasyUI的Web开发框架里面,大量采用了Jquery的方法,对数据进行请求或者提交, ...

  4. 基于MVC4+EasyUI的Web开发框架经验总结

    http://www.cnblogs.com/wuhuacong/p/4093778.html 在很多Web系统中,一般都可能提供一些图标的选择,方便配置按钮,菜单等界面元素的图 标,从而是Web系统 ...

  5. 基于MVC4+EasyUI的Web开发框架经验总结(14)--自动生成图标样式文件和图标的选择操作

    在很多Web系统中,一般都可能提供一些图标的选择,方便配置按钮,菜单等界面元素的图标,从而是Web系统界面看起来更加美观和协调.但是在系统中一般内置的图标样式相对比较有限,而且硬编码写到样式表里面,这 ...

  6. 基于MVC4+EasyUI的Web开发框架经验总结(13)--DataGrid控件实现自动适应宽带高度

    在默认情况下,EasyUI的DataGrid好像都没有具备自动宽度的适应功能,一般是指定像素宽度的,但是使用的人员计算机的屏幕分辨率可能不一样,因此导致有些地方显示太大或者太小,总是不能达到好的预期效 ...

  7. 基于MVC4+EasyUI的Web开发框架经验总结(11)--使用Bundles处理简化页面代码

    在Web开发的时候,我们很多时候,需要引用很多CSS文件.JS文件,随着使用更多的插件或者独立样式文件,可能我们的Web界面代码会越来越臃肿,看起来也很累赘,在MVC里面提供了一个Bundle的对象, ...

  8. 基于MVC4+EasyUI的Web开发框架经验总结(9)--在Datagrid里面实现外键字段的转义操作

    我们在使用EasyUI的时候,很多情况下需要使用到表格控件datagrid,这个控件控件非常强大,使用起来很简洁,但是我在使用中,发现对于一个表里面的外键字段进行转义,并显示引用表的一些名称的操作,却 ...

  9. 基于MVC4+EasyUI的Web开发框架经验总结(8)--实现Office文档的预览

    在博客园很多文章里面,曾经有一些介绍Office文档预览查看操作的,有些通过转为PDF进行查看,有些通过把它转换为Flash进行查看,但是过程都是曲线救国,真正能够简洁方便的实现Office文档的预览 ...

随机推荐

  1. Unity3d热更新全书-加载(二)如何在不用AssetBundle的前提下动态加载预设

    Unity3D的主要构成大家都知道,首先是场景图,场景图上的节点构成一颗树. 每个节点对应一个GameObject对象 然后每个GameObject有若干个组件 有一些组件会与资源产生关系,比如Mes ...

  2. [Unity3D入门]分享一个自制的入门级游戏项目"坦克狙击手"

    [Unity3D入门]分享一个自制的入门级游戏项目"坦克狙击手" 我在学Unity3D,TankSniper(坦克狙击手)这个项目是用来练手的.游戏玩法来自这里(http://ww ...

  3. linux下获取线程号

    #include <sys/syscall.h> pid_t gettid() { return syscall(SYS_gettid); }

  4. 去除NSString里面的空格

    NSString *password = @"12  34"; [password stringByTrimmingCharactersInSet:[NSCharacterSet ...

  5. 谷歌大牛 Rob Pike 的 5 个编程原则

    谷歌大牛 Rob Pike 的 5 个编程原则 简介: Rob Pike,目前谷歌公司最著名的软件工程师之一,曾是贝尔实验室Unix开发团队成员,Plan9操作系统开发的主要领导人,Inferno操作 ...

  6. Atitit.java图片图像处理attilax总结  BufferedImage extends java.awt.Image获取图像像素点image.getRGB(i, lineIndex); 图片剪辑/AtiPlatf_cms/src/com/attilax/img/imgx.javacutImage图片处理titit 判断判断一张图片是否包含另一张小图片 atitit 图片去噪算法的原理与

    Atitit.java图片图像处理attilax总结 BufferedImage extends java.awt.Image 获取图像像素点 image.getRGB(i, lineIndex); ...

  7. php中的常用函数

    1.随机数和时间 echo rand(); //随机数生成器 echo rand(0,10); //某个范围之间的随机数:第一个参数最小,第二个参数最大:例子是从0-10之间的随机数 echo tim ...

  8. 开源、免费功能全面的Chart图

    简介: 每个前端都有一个Chart梦,至于真正去做的寥寥无几,无怪乎几个原因: 浏览器兼容问题 数据处理的一些算法,如自动计算坐标轴.自动排列文本等 流畅的动画 丰富的交互功能 去年一年的时间里,我一 ...

  9. Unity3D Editor模式下批量修改prefab

    最经遇到一个需要批量修改已经做好的prefab的问题,查了一些资料最终实现了但是还是不够完美,通过学习也发现unity的编辑器功能还是非常强大的.废话不多说直接上代码: [ExecuteInEditM ...

  10. SQL Server Window Function 窗体函数读书笔记二 - A Detailed Look at Window Functions

    这一章主要是介绍 窗体中的 Aggregate 函数, Rank 函数, Distribution 函数以及 Offset 函数. Window Aggregate 函数 Window Aggrega ...