分享一个简单一用的 Excel 导出的类库

特性如下:

  1. 可支持复杂的多级表头的导出,表头采用树结构的数据,最终取所有的叶子节点作为数据列。

  2. 支持 DataTable、DataSet、IEnumerable、IEnumerable<>、IEnumerable<IDictianry>、IEnumerable<IDictianry<,>>、Lazy<>、Func<> 等类型作为数据源。

  3. 每个 WorkBook 可导出多个 Sheet,可自动实现分页导出到不同的 Sheet。

  4. 可对列中连续的重复值做合并单元格操作。

  5. 可对单元格的值格式化、设置行列的颜色、宽度等。

大概说一下,整个设计吧,

1、首先有一个 IExcelExporter 的接口,第一如下:

1 public interface IExcelExporter
2     {
3         Task BuildSheetsAsync(
4             Stream stream, IEnumerable<Settings> settings_list, bool useOldVersion = false,
5             object hostContext = null);
6     }

2、然后有一个抽象类, ExcelExporterBase<TWorkBook, TWorkSheet, TCellStyle> 实现 IExcelExporter 接口。

抽象类里面封装了创建表头、创建表格主题的、合并列中连续重复值 等的算法。然后定义了一些需要在子类是实现的抽象方法。如下:

 1 #region [ protected ]
 2 
 3         protected abstract TWorkBook CreateWorkBook(bool useOldVersion);
 4 
 5         protected abstract TWorkSheet CreateWorkSheet(TWorkBook workbook, string name, Settings settings);
 6 
 7         protected abstract TCellStyle CreateCellStyle(TWorkBook workbook, TCellStyle style, CellStyle cellStyle);
 8 
 9         protected abstract TCellStyle GetCellStyle(TWorkBook workbook, TWorkSheet sheet, int row, int col);
10 
11         protected abstract void SetCell(TWorkBook workbook, TWorkSheet sheet, int row, int col, Settings settings, ColNode node, object value, TCellStyle style, bool setValue = true, bool setStyle = true);
12 
13         protected abstract void MergeCells(TWorkBook workbook, TWorkSheet sheet, int startRow, int endRow, int startCol, int endCol, Settings settings);
14 
15         protected abstract void FreezePane(TWorkBook workbook, TWorkSheet sheet, int rowSplit, int colSplit);
16 
17         protected abstract void SetColumnsWidth(TWorkBook workbook, TWorkSheet sheet, Settings settings, uint[] widthArray, int startCol);
18 
19         protected abstract void AutoFillColumns(TWorkBook workbook, TWorkSheet sheet, Settings settings, int startCol);
20 
21         protected abstract void Save(TWorkBook workbook, bool useOldVersion, Stream stream);
22 
23         #endregion

几个抽象方法,都很好理解,根据方法名很容易知道要实现的功能。

3、在具体的实现中我用 Aspose.Cells 和 NPOI 分别实现了一套。

Aspose_Cells_ExcelExporter、 NPOI_ExcelExporter 这两个类。

 

4、使用示例。

DataTable dt = MAIN.Get_Users();

Settings set = new Settings()
            {
                PageSize = 100,
                Name = "",
                ColumnsAutoWidth = true,
                StartColIndex = 1,
                StartRowIndex = 1,
                DataSource = new Lazy<System.Collections.Generic.IEnumerable<SysUser>>(() =>
                {
                    string str = ConfigurationManager.ConnectionStrings["mysql_demo"].ConnectionString;
                    return MAIN.helper.ToEnumerable2<SysUser>("SELECT * FROM SysUser"); //MAIN.Get_Users();
                }),
                FreezeHeader = true,
                //RowStyleGetter = (i, row) => i % 2 == 0 ? CellStyle.Body : new CellStyle() { BgColor = Color.White, FgColor = RandColor() },
                RootNodes = new[]{
                    new ColNode(){
                        Title = "用户列表",
                        ChildColNodes = dt.Columns.Cast<
                            DataColumn>().Select(col => 
                                new ColNode {
                                    Title = col.ColumnName,
                                    Field = col.ColumnName,
                                    MergeField = col.ColumnName
                                }).ToArray()
                    }
                }
            };

IExcelExporter ep = new NPOI_ExcelExporter();

Task task = ep.BuildSheetsAsync(
                new FileStream("./test.xlsx", FileMode.Create, FileAccess.Write),
                new[] { set }, false);

            task.Wait();

这里导出时,我将表头作为了一个父列,DataTable 的所有列作为子列。

比如 SysUser 表结构如下 : ID、UserName、Sex

那么导出的 Excel 格式如下 

用户列表
ID UserName Sex
     
     

 

 

 

已在开源中国开源,有需要的朋友,可以下载,欢迎拍砖。

posted on 2016-11-29 20:47  醉仙灵芙  阅读(747)  评论(18编辑  收藏  举报