首页 > 学院 > 开发设计 > 正文

ExcelReport第二篇:ExcelReport源码解析

2019-11-17 02:37:04
字体:
来源:转载
供稿:网友

ExcelReport第二篇:ExcelReport源码解析

导航

目 录:基于NPOI的报表引擎——ExcelReport

上一篇:使用ExcelReport导出Excel

下一篇:扩展元素格式化器

概述

针对上一篇随笔收到的反馈,在展开对ExcelReport源码解析之前,我认为把编写该组件时的想法分享给大家是有必要的。

编写该组件时,思考如下:

1)要实现样式、格式与数据的彻底分离。

为什么要将样式、格式与数据分离呢?恩,你不妨想一想在生成报表时,那些是变的而那些又是不变的。我的结论是:变的是数据。

有了这个想法,很自然的想到用模板去承载不变的部分(常量内容的样式、格式、数据及变量内容的样式、格式),在程序中控制变的部分(变量内容的数据)。

这里以上一篇中的例子标识:

image

变量内容已使用粉红色边框标出,其余为常量内容。好了,相信“内容的数据”大家都知道那个是那个的。下面截图,内容的样式和格式。

image

image

现在我们回到上篇中使用的模板,相信你应该知道它承载那些东西了。

image

啰嗦了这么多,总结一下样式、格式与数据分离的好处:它让我们编写程序时关注更少(只需关心“变量内容的数据”)。

2)关注“变量内容的数据”填充到模板的最小单元(我们把这些称之为元素格式化器),然后利用合成模式(Composite)搞定整个文档的数据填充。

为什么要抽象一个“元素格式化器”的概念呢?我们看数据源,我们有可能要将某个类型的数据填充到某个单元格、也可能将一个集合填充到多行、有可能将一张图片填充到某个位置、也有可能就将某个字符串合并到某个单元格的内容中......如此种种。那么它们有什么共同点呢?它们都是填充“变量内容的数据”到模板的。

3)外部调用,统一从一个处理入口处理。

源码解析

有了上面的背景,这张UML想必不难理解了。

ExcelReport

当然,如果你还是觉得复杂, 没关系。我会先介绍一下这里面几个重点关系。

1)从Export类开始吧!

这是一个静态类,非常简单。只有两个静态方法:ExportToLocal()、ExportToWeb()分别将生成的文件导出到本地和Web。这多半是废话了,下面是重点:

image

这便引出了SheetFormatterContainer类,SheetFormatterContainer类是何许也?

  • SheetFormatterContainer是一个存储“格式化一个Sheet用到的元素格式化器集合”的容器。

说到这,顺便说下:ElementFormatter类和SheetFormatterContext类。

  • ElementFormatter:元素格式化器。
  • SheetFormatterContext:Sheet格式化上下文。

回到Export:

public static byte[] ExportToBuffer(string templateFile, params SheetFormatterContainer[] containers)
{
    var workbook = LoadTemplateWorkbook(templateFile);
    foreach (var container in containers)
    {
        var sheet = workbook.GetSheet(container.SheetName);
        var context = new SheetFormatterContext(sheet, container.Formatters);
        context.Format();
    }
    return workbook.SaveToBuffer();
}

如上代码,在执行导出的过程中,将每一个SheetFormatterContainer对象转换成了SheetFormatterContext对象。然后SheetFormatterContext对象调用自身的Format()方法格式化Sheet。

public void Format()
{
    if (null == Sheet || null == Formatters)
    {
        return;
    }
    foreach (var formatter in Formatters)
    {
        formatter.Format(this);
    }
}

Formatters就是从SheetFormatterContainer传过来的“元素格式化器”集合。

image

抽象的“元素格式化器”:

image

至此,ExcelReport组件的核心部分已经介绍完成了,下面附上代码(如下代码仅供参考,了解ExcelReport组件最新动态,请到GitHub下载最新源码)。

2)附--(ExcelReport1.0源码)

image

SheetFormatterContainer.cs

/*
 类:SheetFormatterContainer
 描述:Sheet中元素的格式化器集合
 编 码 人:韩兆新 日期:2015年01月17日
 修改记录:
*/
using System.Collections.Generic;
namespace ExcelReport
{
    public class SheetFormatterContainer
    {
        #region 成员字段及属性
        PRivate string sheetName;
        public string SheetName
        {
            get { return sheetName; }
        }
        private IEnumerable<ElementFormatter> formatters;
        public IEnumerable<ElementFormatter> Formatters
        {
            get { return formatters; }
        }
        #endregion 成员字段及属性
        #region 构造函数
        public SheetFormatterContainer(string sheetName, IEnumerable<ElementFormatter> formatters)
        {
            this.sheetName = sheetName;
            this.formatters = formatters;
        }
        #endregion 构造函数
    }
}

SheetFormatterContext.cs

/*
 类:SheetFormatterContext
 描述:Sheet格式化的上下文
 编 码 人:韩兆新 日期:2015年01月17日
 修改记录:
*/
using System.Collections.Generic;
using NPOI.SS.UserModel;
namespace ExcelReport
{
    public class SheetFormatterContext
    {
        #region 成员字段及属性
        private int _increaseRowsCount = 0;
        public ISheet Sheet { get; set; }
        public IEnumerable<ElementFormatter> Formatters { get; set; }
        #endregion 成员字段及属性
        #region 构造函数
        public SheetFormatterContext()
        {
        }
        public SheetFormatterContext(ISheet sheet, IEnumerable<ElementFormatter> formatters)
        {
<
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表