前言

前面一篇详细讲解了导入导出,本节演示混合结构的导出功能!同时提供代码下载..

代码下载 vs2015+无数据库

先看效果图:这个一个混合的Excel,列表与自定义信息的混合!

  我们的步骤大概分为以下几步

  • 1.模拟数据库数据
  • 2.创建工作簿
  • 3.填充固定数据
  • 4.合并单元格
  • 5.处理动态数据

  数据及环境准备

  创建一个新的Asp.Net MVC5项目,并从Nuget包安装ClosedXML

  

  为了更好的跟真实数据结合,我们需要模拟一些静态数据,新建2个模型来保存数据

  public class SchoolClass
    {

        public string Id { get; set; }//班级标示
        public string Name { get; set; }//班级名称
        public string Manager { get; set; }//班主任姓名
        public string Manager2 { get; set; }//副班主任姓名
        public string PhoneNumber { get; set; }//班主任联系电话
        public string PhoneNumber2 { get; set; }//副主任联系电话
        public string Remark { get; set; } //班级说明
        public List<Students> stuList { get; set; }//一个班级对应多个学生
    }

    public class Students
    {
        public string Id { get; set; }//学号
        public string Name { get; set; }//姓名
        public string Sex { get; set; }//性别
        public string Age { get; set; }//年龄
        public string Point { get; set; }//年度得分
        public string PhoneNumber { get; set; }//电话
    }

注:从模型看出,这是一个班级信息表,一个班级对应多个学生的信息!

实现方式

1.新建一个控制器并填充数据

 public ActionResult Index()
 {
            //模拟数据库赋值,一个班级对应多个学生
            SchoolClass model = new SchoolClass();
            model.Id = "CLS0001";
            model.Name = "三年二班";
            model.Manager = "黄SIR";
            model.PhoneNumber = ";
            model.Manager2 = "李SIR";
            model.PhoneNumber2 = ";
            model.Remark = "这是一段有很多个字的班级说明,只有足够长的字,才能证明这段文字很长,如果100个字还不够长,那么就再来100个字!";
            model.stuList = new List<Students>();
            model.stuList.Add(" });
            model.stuList.Add(" });
            model.stuList.Add(" });
            model.stuList.Add(" });
            model.stuList.Add(" });
            model.stuList.Add(" });

}

2.创建作业本并填充表头

红框中表示表示表头位置,我们Excel大家都知道是按位置标示的,比如我点中的三年二班表示的是B3(左上角显示),所有我们填充表头也是这么做

   var wb = new XLWorkbook();
            var ws = wb.Worksheets.Add("班级");
            ws.Cell("A1").Value = model.Name+"班级信息表";
            //标题
            ws.Cell("A2").Value = "班级代号";
            ws.Cell("B2").Value = "班级名称";
            ws.Cell("C2").Value = "班主任";
            ws.Cell("D2").Value = "联系电话";
            ws.Cell("E2").Value = "副班主任";
            ws.Cell("F2").Value = "联系电话";
            //主表内容
            ws.Cell("A3").Value = model.Id;
            ws.Cell("B3").Value = model.Name;
            ws.Cell("C3").Value = model.Manager;
            ws.Cell("D3").Value = model.PhoneNumber;
            ws.Cell("E3").Value = model.Manager2;
            ws.Cell("F3").Value = model.PhoneNumber2;
            ws.Cell("A4").Value = model.Remark;//说明

            //明细表标题
            ws.Cell("A5").Value = "学号";
            ws.Cell("B5").Value = "姓名";
            ws.Cell("C5").Value = "性别";
            ws.Cell("D5").Value = "年龄";
            ws.Cell("E5").Value = "得分";
            ws.Cell("F5").Value = "电话号码";

所以位置决定内容,填充表头后。我们再填充列表

   ; i < model.stuList.Count(); i++)
            {
                ws.Cell(i + , ).Value = model.stuList[i].Id;
                ws.Cell(i + , ).Value = model.stuList[i].Name;
                ws.Cell(i + , ).Value = model.stuList[i].Sex;
                ws.Cell(i + , ).Value = model.stuList[i].Age;
                ws.Cell(i + , ).Value = model.stuList[i].PhoneNumber;
                ws.Cell(i + , ).Value = model.stuList[i].PhoneNumber;
            }

由于我们列表数据是动态并不是固定的,工作簿也是支持二维数组位置填充!看代码从第6行开始,一行一行填充!

3.合并和填充

       ));

            //合并表头
            var rngHeaders = rngTable.Range("A1:F1");
            ws.Row().Height = ;
            rngHeaders.FirstCell().Style
             .Font.SetBold()
             .Fill.SetBackgroundColor(XLColor.Buff)
             .Alignment.SetHorizontal(XLAlignmentHorizontalValues.Center);
            rngHeaders.FirstRow().Merge();

            //第二行表头样式
            rngHeaders = rngTable.Range("A2:F2"); // The address is relative to rngTable (NOT the worksheet)
            rngHeaders.Style.Alignment.Horizontal = XLAlignmentHorizontalValues.Center;
            rngHeaders.Style.Font.Bold = true;
            //rngHeaders.Style.Font.FontColor = XLColor.DarkBlue;
            rngHeaders.Style.Fill.BackgroundColor = XLColor.Aqua;

            //合并说明
            var rngRemark = rngTable.Range("A4:F4");
            ws.Row().Height = ;
            rngRemark.Style.Alignment.WrapText = true;
            rngRemark.FirstCell().Comment.Style.Size.SetAutomaticSize();
            rngRemark.FirstRow().Merge();

            rngTable = ws.Range());
            var excelTable = rngTable.CreateTable();

            ws.Columns().AdjustToContents(); 

最后我们要做:填充颜色,合并单元格就好,比如说明:说明内容我们是填充在A4,但是我们要合并A1-F4的位置

 public ActionResult Index()
        {
            //模拟数据库赋值,一个班级对应多个学生
            SchoolClass model = new SchoolClass();
            model.Id = "CLS0001";
            model.Name = "三年二班";
            model.Manager = "黄SIR";
            model.PhoneNumber = ";
            model.Manager2 = "李SIR";
            model.PhoneNumber2 = ";
            model.Remark = "这是一段有很多个字的班级说明,只有足够长的字,才能证明这段文字很长,如果100个字还不够长,那么就再来100个字!";
            model.stuList = new List<Students>();
            model.stuList.Add(" });
            model.stuList.Add(" });
            model.stuList.Add(" });
            model.stuList.Add(" });
            model.stuList.Add(" });
            model.stuList.Add(" });

            var wb = new XLWorkbook();
            var ws = wb.Worksheets.Add("班级");
            ws.Cell("A1").Value = model.Name+"班级信息表";
            //标题
            ws.Cell("A2").Value = "班级代号";
            ws.Cell("B2").Value = "班级名称";
            ws.Cell("C2").Value = "班主任";
            ws.Cell("D2").Value = "联系电话";
            ws.Cell("E2").Value = "副班主任";
            ws.Cell("F2").Value = "联系电话";
            //主表内容
            ws.Cell("A3").Value = model.Id;
            ws.Cell("B3").Value = model.Name;
            ws.Cell("C3").Value = model.Manager;
            ws.Cell("D3").Value = model.PhoneNumber;
            ws.Cell("E3").Value = model.Manager2;
            ws.Cell("F3").Value = model.PhoneNumber2;
            ws.Cell("A4").Value = model.Remark;//说明

            //明细表标题
            ws.Cell("A5").Value = "学号";
            ws.Cell("B5").Value = "姓名";
            ws.Cell("C5").Value = "性别";
            ws.Cell("D5").Value = "年龄";
            ws.Cell("E5").Value = "得分";
            ws.Cell("F5").Value = "电话号码";

            ; i < model.stuList.Count(); i++)
            {
                ws.Cell(i + , ).Value = model.stuList[i].Id;
                ws.Cell(i + , ).Value = model.stuList[i].Name;
                ws.Cell(i + , ).Value = model.stuList[i].Sex;
                ws.Cell(i + , ).Value = model.stuList[i].Age;
                ws.Cell(i + , ).Value = model.stuList[i].PhoneNumber;
                ws.Cell(i + , ).Value = model.stuList[i].PhoneNumber;
            }

            ));

            //合并表头
            var rngHeaders = rngTable.Range("A1:F1");
            ws.Row().Height = ;
            rngHeaders.FirstCell().Style
             .Font.SetBold()
             .Fill.SetBackgroundColor(XLColor.Buff)
             .Alignment.SetHorizontal(XLAlignmentHorizontalValues.Center);
            rngHeaders.FirstRow().Merge();

            //第二行表头样式
            rngHeaders = rngTable.Range("A2:F2"); // The address is relative to rngTable (NOT the worksheet)
            rngHeaders.Style.Alignment.Horizontal = XLAlignmentHorizontalValues.Center;
            rngHeaders.Style.Font.Bold = true;
            //rngHeaders.Style.Font.FontColor = XLColor.DarkBlue;
            rngHeaders.Style.Fill.BackgroundColor = XLColor.Aqua;

            //合并说明
            var rngRemark = rngTable.Range("A4:F4");
            ws.Row().Height = ;
            rngRemark.Style.Alignment.WrapText = true;
            rngRemark.FirstCell().Comment.Style.Size.SetAutomaticSize();
            rngRemark.FirstRow().Merge();

            rngTable = ws.Range());
            var excelTable = rngTable.CreateTable();

            ws.Columns().AdjustToContents(); 

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

            return new ExportExcelResult(wb)
            {
                SheetName = "人员列表",
                FileName = exportFileName,
                Workbook = wb
            };

        }

Index完整代码

总结

代码不难看懂,基本情景我都用到:比如合并、高度、自动换行、等等,是一篇值得参考的文章,同时也见证ClosedXML的强大

参考代码:https://github.com/closedxml/closedxml

ASP.NET MVC5+EF6+EasyUI 后台管理系统(88)-Excel导入和导出-主从表结构导出的更多相关文章

  1. ASP.NET MVC5+EF6+EasyUI 后台管理系统(44)-工作流设计-设计表单

    系列目录 设计表单是比较复杂的一步,完成一个表单的设计其实很漫长,主要分为四步. 开始之前先说说表的结构. 其实表Flow_Form与Flow_FormContent设计是有一个缺陷的.我总共是设置最 ...

  2. ASP.NET MVC5+EF6+EasyUI 后台管理系统(1)-前言与目录(转)

    开发工具:VS2015(2012以上)+SQL2008R2以上数据库 您可以有偿获取一份最新源码联系QQ:729994997 价格 666RMB 升级后界面效果如下: 日程管理   http://ww ...

  3. ASP.NET MVC5+EF6+EasyUI 后台管理系统(1)-前言与目录(持续更新中...)

    开发工具:VS2015(2012以上)+SQL2008R2以上数据库  您可以有偿获取一份最新源码联系QQ:729994997 价格 666RMB  升级后界面效果如下: 任务调度系统界面 http: ...

  4. ASP.NET MVC5+EF6+EasyUI 后台管理系统(63)-Excel导入和导出-自定义表模导入

    系列目录 前言 上一节使用了LinqToExcel和CloseXML对Excel表进行导入和导出的简单操作,大家可以跳转到上一节查看: ASP.NET MVC5+EF6+EasyUI 后台管理系统(6 ...

  5. ASP.NET MVC5+EF6+EasyUI 后台管理系统-WebApi的用法与调试

    1:ASP.NET MVC5+EF6+EasyUI 后台管理系统(1)-WebApi与Unity注入 使用Unity是为了使用我们后台的BLL和DAL层 2:ASP.NET MVC5+EF6+Easy ...

  6. ASP.NET MVC5+EF6+EasyUI 后台管理系统(51)-系统升级

    系统很久没有更新内容了,期待已久的更新在今天发布了,最近花了2个月的时间每天一点点,从原有系统 MVC4+EF5+UNITY2.X+Quartz 2.0+easyui 1.3.4无缝接入 MVC5+E ...

  7. ASP.NET MVC5+EF6+EasyUI 后台管理系统(58)-DAL层重构

    系列目录 前言:这是对本文系统一次重要的革新,很久就想要重构数据访问层了,数据访问层重复代码太多.主要集中增删该查每个模块都有,所以本次是为封装相同接口方法 如果你想了解怎么重构普通的接口DAL层请查 ...

  8. ASP.NET MVC5+EF6+EasyUI 后台管理系统(34)-文章发布系统①-简要分析

    系列目录 最新比较闲,为了学习下Android的开发构建ASP.NET MVC4+EF5+EasyUI+Unity2.x注入的后台管理系统(1)-前言与,虽然有点没有目的的学习,但还是了解了Andro ...

  9. ASP.NET MVC5+EF6+EasyUI 后台管理系统(54)-工作流设计-所有流程监控

    系列目录 先补充一个平面化登陆页面代码,自己更换喜欢的颜色背景 @using Apps.Common; @{ Layout = null; } <!DOCTYPE html> <ht ...

随机推荐

  1. 5分钟看懂svg path 路径的所有命令(更有API解释、有图、有图文对比解析)

    友情提示:更多详情.每个命令的例子.参数变化对比图文详解,欢迎关注九十七度的博客:SVG<Path>命令详解 M = moveto M x y 移动到指定坐标,xy分别为x轴和y轴的坐标点 ...

  2. clone对象

    在JavaScript中,当对象作为参数传给函数的时候,在函数内部对这个对象的属性进行修改时,函数外部的对象属性也会跟着被修改,而有些时候我们并不想原来的对象数据发生改变,这时候就需要切断对象之间的引 ...

  3. Linux系列教程(八)——Linux常用命令之压缩和解压缩命令

    前面一篇博客我们讲解了Linux帮助和用户管理命令,对于帮助命令,man 命令能获得命令和配置文件的帮助信息,help命令能获得shell内置命令的帮助信息.我们可以通过which来区分什么是shel ...

  4. Lua5.3 注册表 _G _ENV

    Lua5.3 注册表 _G _ENV 来源:http://blog.csdn.net/murisly/article/details/46518551 注册表的描述,借用PIL中的一段话: regis ...

  5. 初窥图像识别与k-means算法

    前段时间做了一个车型识别的小项目,思路是利用k-means算法以及词袋模型来做的. 近年来图像识别的方法非常非常多,这边只记录一下我那个项目的思路,核心思想是k-means算法和词汇树. 很遗憾没有做 ...

  6. ajax跨域之---服务器端代理实现

    介绍一种不是通过js实现跨域的方式: 通过服务器端代理实现. 具体的思路:由于浏览器有同源策略限制,(同源策略即:https://developer.mozilla.org/zh-CN/docs/We ...

  7. HTML资源定位器-URL

    URL 也被称为网址. URL 可以由单词组成,比如 "www.baidu.com",或者是因特网协议(IP)地址:192.168.1.253. URL - Uniform Res ...

  8. SQL Server分组查询某最大值的整条数据(包含linq写法)

    想实现如下效果,就是分组后时间最大的那一条数据: 1.SQL SELECT * FROM ( SELECT * , ROW_NUMBER() OVER ( PARTITION BY RIP_GUID ...

  9. JavaScript系列----面向对象的JavaScript(2)

    本文中心: 这篇文章比较难懂,所以读起来比较晦涩.所以,我简单列一下提纲: 在第一部分,从函数原型开始谈起,目的是想搞明白,这个属性是什么,为什么存在,在创建对象的的时候起到了什么作用! 在第二部分, ...

  10. app.config 配置多项 配置集合 自定义配置(3)

    再说说利用app.config配置多个自定义的方法.先看这个例子:美国家庭Simpson的家里有父亲母亲和三个儿女,而中国的老王只有独生子女.结构如下: <?xml version=" ...