ASP.NET MVC5+EF6+EasyUI 后台管理系统(87)-MVC Excel导入和导出

简介:

系列目录

前言:

 

导入导出实在多例子,很多成熟的组建都分装了导入和导出,这一节演示利用LinqToExcel组件对Excel的导入,这个是一个极其简单的例子。

我并不是说导入的简单。而是LinqToExcel让我们对Excel操作更加简单!

最后我们将利用ClosedXML输出Excel。这个比现流行NPOI与EPPlus更加优秀的组件,以Open XML SDK为基础,所以只支持xlsx,不支持xls格式(现阶段谁没有个office2007以上版本)

他导出的Excel根据官方描述,兼容性远超同行对手

如果你不是使用本架构只看2,3,4点,使用BLL层的代码,这同样适用你的MVC程序

知识点:

  • LinqToExcel组件读取Excel文件
  • ClosedXML组件输出Excel

准备:

  1. 一张演示的数据库表
  2. 安装LinqToExcel NuGet包
  3. 文件上传样例
  4. CloseXML导出Excel

开始:

1.数据表

复制代码
CREATE TABLE [dbo].[Spl_Person](
    [Id] [nvarchar](50) NOT NULL,          --ID
    [Name] [nvarchar](50) NULL,            --姓名
    [Sex] [nchar](10) NULL,                --性别    
    [Age] [int] NULL,                      --年龄
    [IDCard] [nvarchar](50) NULL,          --IDCard
    [Phone] [nvarchar](50) NULL,           --电话
    [Email] [nvarchar](200) NULL,          --邮件
    [Address] [nvarchar](300) NULL,        --地址
    [CreateTime] [datetime] NOT NULL,      --创建时间
    [Region] [nvarchar](50) NULL,          --区域
    [Category] [nvarchar](50) NULL,        --类别
 CONSTRAINT [PK_Spl_Person] PRIMARY KEY CLUSTERED 
(
    [Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]

GO
复制代码

如何使用这个框架?

按照之前的做法,更新到EF。并利用T4生成DAL,BLL,MODEL。再用代码生成器生成界面复制进解决方案,一步到位

配置好访问地址和权限,直接运行

 再手动在工具栏添加导入和导出的按钮(别忘记添加权限)

 

    @Html.ToolButton("btnImport", "fa fa-level-down", Resource.Import, perm, "Import", true)
    @Html.ToolButton("btnExport", "fa fa-level-up", Resource.Export, perm, "Export", true)

2.安装LinqToExcel包

因为我们读取Excel放在BLL层,所有在BLL层安装LinqToExcel包

3.文件上传

(这一点简单带过,可以到网上下载上传代码植入到自己系统中)

或者下载第32节的源码 或者下载本节的示例代码都可以

我这里使用普通的form上传功能

添加导入前端代码

复制代码
<div id="uploadExcel" class="easyui-window" data-options="modal:true,closed:true,minimizable:false,shadow:false">
    <form name="form1" method="post" id="form1">
        <table>
            <tr>
                <th style=" padding:20px;">Excel:</th>
                <td style=" padding:20px;">
                    <input name="ExcelPath" type="text" maxlength="255" id="txtExcelPath" readonly="readonly" style="width:200px" class="txtInput normal left">
                    <a href="javascript:$('#FileUpload').trigger('click').void(0);;" class="files">@Resource.Browse</a>
                    <input class="displaynone" type="file" id="FileUpload" name="FileUpload" onchange="Upload('ExcelFile', 'txtExcelPath', 'FileUpload');">
                    <span class="uploading">@Resource.Uploading</span>
                </td>
            </tr>
        </table>
        <div class="endbtndiv">
            <a id="btnSave" href="javascript:ImportData()" class="easyui-linkbutton btns">Save</a>
            <a id="btnReturn" href="javascript:$('#uploadExcel').window('close')" class="easyui-linkbutton btnc">Close</a>
        </div>
    </form>
</div>
复制代码

 导入按钮事件只要弹出上传框就好

  $("#btnImport").click(function () {
            $("#uploadExcel").window({ title: '@Resource.Import', width: 450, height: 160, iconCls: 'icon-details' }).window('open');
        });

 

 保证上传是成功的。

直接查看源码的C#上传代码

-------------------------------------------------------------------------------------------------------上面只是前期的准备工作--------------------------------------------------------------

在业务层添加以下代码

  BLL
  ValidationError

代码包含两个方法

public bool CheckImportData( string fileName, List<Spl_PersonModel> personList,ValidationErrors errors )

fileName为我们上传的文件。

personList为承接数据List

ValidationErrors 错误集合

 public void SaveImportData(IEnumerable<Spl_PersonModel> personList)

保存数据

别忘记添加接口

   public partial interface ISpl_PersonBLL
    {
        bool CheckImportData(string fileName, List<Spl_PersonModel> personList, ref ValidationErrors errors);
        void SaveImportData(IEnumerable<Spl_PersonModel> personList);
    }

简单明白,直接看代码,不再解析。OK这样控制器就可以直接调用了

复制代码
  public ActionResult Import(string filePath)
        {
            var personList = new List<Spl_PersonModel>();
             //校验数据is
            bool checkResult = m_BLL.CheckImportData(filePath, personList, ref errors);
             //校验通过直接保存
             if (checkResult)
             {
                 m_BLL.SaveImportData(personList);
                 LogHandler.WriteServiceLog(GetUserId(),"导入成功", "成功", "导入", "Spl_Person");
                 return Json(JsonHandler.CreateMessage(1, Resource.InsertSucceed));
             }
             else
             {
                 string ErrorCol = errors.Error;
                 LogHandler.WriteServiceLog(GetUserId(), ErrorCol, "失败", "导入", "Spl_Person");
                 return Json(JsonHandler.CreateMessage(0, Resource.InsertFail + ErrorCol));
              }
        
        }
复制代码

最后前端还需要把路径给回来。

复制代码
 function ImportData()
    {
        $.post("@Url.Action("Import")?filePath=" + $("#txtExcelPath").val(), function (data) {
            if (data.type == 1) {
                $("#List").datagrid('load');
                $('#uploadExcel').window('close');
            }
            $.messageBox5s('@Resource.Tip', data.message);
                            
        }, "json");
    }
复制代码

OK测试一下!建立一个新的excel格式

一般情况下我们是提供模版给用户下载供用户输入数据,来确保格式的正确性

 

--------------------------------------------------------------------------------------导出功能------------------------------------------------------------------------------

4.安装ClosedXML NuGet包

在控制器添加以下代码:

复制代码
   public ActionResult Export()
        {
            var exportSpource = this.GetExportData();
            var dt = JsonConvert.DeserializeObject<DataTable>(exportSpource.ToString());

            var exportFileName = string.Concat(
                "Person",
                DateTime.Now.ToString("yyyyMMddHHmmss"),
                ".xlsx");

            return new ExportExcelResult
            {
                SheetName = "人员列表",
                FileName = exportFileName,
                ExportData = dt
            };
        }

        private JArray GetExportData()
        {
            List<Spl_PersonModel> list = m_BLL.GetList(ref setNoPagerAscById, "");
            JArray jObjects = new JArray();

            foreach (var item in list)
            {
                var jo = new JObject();
                jo.Add("Id", item.Id);
                jo.Add("Name", item.Name);
                jo.Add("Sex", item.Sex);
                jo.Add("Age", item.Age);
                jo.Add("IDCard", item.IDCard);
                jo.Add("Phone", item.Phone);
                jo.Add("Email", item.Email);
                jo.Add("Address", item.Address);
                jo.Add("CreateTime", item.CreateTime);
                jo.Add("Region", item.Region);
                jo.Add("Category", item.Category);
                jObjects.Add(jo);
            }
            return jObjects;
        }
复制代码

注意:ExportExcelResult

此类是使用ClosedXML.Excel,已经封装好了。大家直接拿来用就可以。把关注点都放在业务中

 

复制代码
using ClosedXML.Excel;
using System;
using System.Data;
using System.IO;
using System.Text;
using System.Web;
using System.Web.Mvc;

namespace Apps.Web.Core
{
    public class ExportExcelResult : ActionResult
    {
        public string SheetName { get; set; }
        public string FileName { get; set; }
        public DataTable ExportData { get; set; }

        public ExportExcelResult()
        {

        }

        public override void ExecuteResult(ControllerContext context)
        {
            if (ExportData == null)
            {
                throw new InvalidDataException("ExportData");
            }
            if (string.IsNullOrWhiteSpace(this.SheetName))
            {
                this.SheetName = "Sheet1";
            }
            if (string.IsNullOrWhiteSpace(this.FileName))
            {
                this.FileName = string.Concat(
                    "ExportData_",
                    DateTime.Now.ToString("yyyyMMddHHmmss"),
                    ".xlsx");
            }

            this.ExportExcelEventHandler(context);
        }

        /// <summary>
        /// Exports the excel event handler.
        /// </summary>
        /// <param name="context">The context.</param>
        private void ExportExcelEventHandler(ControllerContext context)
        {
            try
            {
                var workbook = new XLWorkbook();

                if (this.ExportData != null)
                {
                    context.HttpContext.Response.Clear();

                    // 编码
                    context.HttpContext.Response.ContentEncoding = Encoding.UTF8;

                    // 设置网页ContentType
                    context.HttpContext.Response.ContentType =
                        "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";

                    // 导出名字
                    var browser = context.HttpContext.Request.Browser.Browser;
                    var exportFileName = browser.Equals("Firefox", StringComparison.OrdinalIgnoreCase)
                        ? this.FileName
                        : HttpUtility.UrlEncode(this.FileName, Encoding.UTF8);

                    context.HttpContext.Response.AddHeader(
                        "Content-Disposition",
                        string.Format("attachment;filename={0}", exportFileName));

                    // Add all DataTables in the DataSet as a worksheets
                    workbook.Worksheets.Add(this.ExportData, this.SheetName);

                    using (var memoryStream = new MemoryStream())
                    {
                        workbook.SaveAs(memoryStream);
                        memoryStream.WriteTo(context.HttpContext.Response.OutputStream);
                        memoryStream.Close();
                    }
                }
                workbook.Dispose();
            }
            catch (Exception ex)
            {
                throw;
            }
        }
    }
}
复制代码

 

总结:

本节知识点,全部聚集在CheckImportData方法上。

对应列头是模版xlsx的列头

1.如果模版需要是是中文的,如Name=名字,那么方法应该这么写

 excelFile.AddMapping<Spl_PersonModel>(x => x.Name, "名字");

2.导入第几个sheet工作薄可以这么写

我这里写0是指第一个sheet工作薄。可以直接指定工作薄

var excelContent = excelFile.Worksheet<Spl_PersonModel>("Sheet1");

3.检查正确性可以确保数据的来源。可以给出用户正确的修改提示。

4.借助ClosedXML,导出实际只需要几行代码。哈哈..这是如此的简单。

复制代码
 return new ExportExcelResult
            {
                SheetName = "人员列表",
                FileName = exportFileName,
                ExportData = dt
            };
复制代码

 

 本文转自ymnets博客园博客,原文链接:http://www.cnblogs.com/ymnets/p/7690863.html,如需转载请自行联系原作者

相关文章
|
SQL 前端开发 Java
JSP毕业设计选题系统统myeclipse开发sql数据库BS模式java编程mvc结构
JSP 毕业设计选题系统是一套完善的web设计系统,对理解JSP java编程开发语言有帮助,系统具有完整的源代码和数据库,系统主要采用B/S模式开发。
42 0
|
6月前
|
设计模式 前端开发 Java
javaweb实训第四天上午——员工管理系统-JavaBean&EL&JSTL&MVC思想(3)
5.2.怎么使用JSTL标签库 第一步:导入相关的jar包
114 0
|
6月前
|
前端开发 Java
javaweb实训第四天上午——员工管理系统-JavaBean&EL&JSTL&MVC思想(1)
1.课程介绍 项目需求分析; (了解) JavaBean; (掌握) El表达式; (掌握) JSTL标签; (掌握) MVC思想; (掌握)
76 0
|
6月前
|
安全 数据管理 中间件
云LIS系统源码JavaScript+B/S架构MVC+SQLSugar医院版检验科云LIS系统源码 可提供演示
检验科云LIS系统源码是医疗机构信息化发展的重要趋势。通过云计算技术实现数据的集中管理和共享可以提高数据利用效率和安全性;通过高效灵活的系统设计和可扩展性可以满足不同医疗机构的需求;通过移动性和智能化可以提高医疗服务的精准度和效率;通过集成性可以实现医疗服务的协同性和效率。因此,多医院版检验科云LIS系统源码将成为未来医疗机构信息化发展的重要方向之一。
91 2
|
6月前
|
前端开发 Java
javaweb实训第四天上午——员工管理系统-JavaBean&EL&JSTL&MVC思想(2)
4.3.EL表达式访问四大作用域的绑定值 搭建环境:分别从各大作用域里面取值
80 0
|
3月前
|
供应链 前端开发 Java
服装库存管理系统 Mybatis+Layui+MVC+JSP【完整功能介绍+实现详情+源码】
该博客文章介绍了一个使用Mybatis、Layui、MVC和JSP技术栈开发的服装库存管理系统,包括注册登录、权限管理、用户和货号管理、库存管理等功能,并提供了源码下载链接。
服装库存管理系统 Mybatis+Layui+MVC+JSP【完整功能介绍+实现详情+源码】
|
6月前
|
开发框架 前端开发 JavaScript
JavaScript云LIS系统源码ASP.NET CORE 3.1 MVC + SQLserver + Redis医院实验室信息系统源码 医院云LIS系统源码
实验室信息系统(Laboratory Information System,缩写LIS)是一类用来处理实验室过程信息的软件,云LIS系统围绕临床,云LIS系统将与云HIS系统建立起高度的业务整合,以体现“以病人为中心”的设计理念,优化就诊流程,方便患者就医。
79 0
|
6月前
|
前端开发 Java UED
解密Spring MVC异常处理:从局部到全局,打造稳固系统的关键步骤
解密Spring MVC异常处理:从局部到全局,打造稳固系统的关键步骤
199 0
|
消息中间件 前端开发 Java
GitHub标星30k!基于Spring MVC Mybatis分布式开发系统-zheng项目
zheng项目不仅仅是一个开发架构,而是努力打造一套从 前端模板 - 基础框架 - 分布式架构 - 开源项目 - 持续集成 - 自动化部署 - 系统监测 - 无缝升级 的全方位J2EE企业级开发解决方案。
|
开发框架 自然语言处理 前端开发
基于ASP.NET MVC开发的、开源的个人博客系统
基于ASP.NET MVC开发的、开源的个人博客系统
84 0

相关课程

更多

相关实验场景

更多