NPOI+ExcelReport

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了NPOI+ExcelReport相关的知识,希望对你有一定的参考价值。

自ExcelUtility类推出以来,经过项目中的实际使用与不断完善,现在又做了许多的优化并增加了许多的功能,本篇不再讲述原理,直接贴出示例代码以及相关的模板、结果图,以便大家快速掌握,另外这些示例说明我也已同步到GIT中,大家可以下载与学习,不足之处,敬请见谅,谢谢!

一、ExcelUtility类库操作说明(模板导出示例)

1.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
/// <summary>
/// 测试方法:测试依据模板+DataTable来生成EXCEL
/// </summary>
[TestMethod]
public void TestExportToExcelWithTemplateByDataTable()
{
    DataTable dt = GetDataTable();//获取数据
    string templateFilePath = AppDomain.CurrentDomain.BaseDirectory + "/excel.xlsx"//获得EXCEL模板路径
    SheetFormatterContainer formatterContainers = new SheetFormatterContainer(); //实例化一个模板数据格式化容器
 
    PartFormatterBuilder partFormatterBuilder = new PartFormatterBuilder();//实例化一个局部元素格式化器
    partFormatterBuilder.AddFormatter("Title""跨越IT学员");//将模板表格中Title的值设置为跨越IT学员
    formatterContainers.AppendFormatterBuilder(partFormatterBuilder);//添加到工作薄格式容器中,注意只有添加进去了才会生效
 
    CellFormatterBuilder cellFormatterBuilder = new CellFormatterBuilder();//实例化一个单元格格式化器
    cellFormatterBuilder.AddFormatter("rptdate", DateTime.Today.ToString("yyyy-MM-dd HH:mm"));//将模板表格中rptdate的值设置为当前日期
    formatterContainers.AppendFormatterBuilder(cellFormatterBuilder);//添加到工作薄格式容器中,注意只有添加进去了才会生效
 
    //实例化一个表格格式化器,dt.Select()是将DataTable转换成DataRow[],name表示的模板表格中第一行第一个单元格要填充的数据参数名
    TableFormatterBuilder<DataRow> tableFormatterBuilder = new TableFormatterBuilder<DataRow>(dt.Select(), "name");
    tableFormatterBuilder.AddFormatters(new Dictionary<string, Func<DataRow, object>>{
        {"name",r=>r["Col1"]},//将模板表格中name对应DataTable中的列Col1
        {"sex",r=>r["Col2"]},//将模板表格中sex对应DataTable中的列Col2
        {"km",r=>r["Col3"]},//将模板表格中km对应DataTable中的列Col3
        {"score",r=>r["Col4"]},//将模板表格中score对应DataTable中的列Col4
        {"result",r=>r["Col5"]}//将模板表格中result对应DataTable中的列Co5
    });
    formatterContainers.AppendFormatterBuilder(tableFormatterBuilder);//添加到工作薄格式容器中,注意只有添加进去了才会生效
    string excelPath = ExcelUtility.Export.ToExcelWithTemplate(templateFilePath, "table", formatterContainers);
    Assert.IsTrue(File.Exists(excelPath));
}

模板如下:

技术分享

导出结果如下:

技术分享

 

2.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
/// <summary>
/// 测试方法:测试依据模板+List来生成EXCEL
/// </summary>
[TestMethod]
public void TestExportToExcelWithTemplateByList()
{
    List<Student> studentList = GetStudentList();//获取数据
    string templateFilePath = AppDomain.CurrentDomain.BaseDirectory + "/excel.xlsx"//获得EXCEL模板路径
    SheetFormatterContainer formatterContainers = new SheetFormatterContainer(); //实例化一个模板数据格式化容器
 
    PartFormatterBuilder partFormatterBuilder = new PartFormatterBuilder();//实例化一个局部元素格式化器
    partFormatterBuilder.AddFormatter("Title""跨越IT学员");//将模板表格中Title的值设置为跨越IT学员
    formatterContainers.AppendFormatterBuilder(partFormatterBuilder);//添加到工作薄格式容器中,注意只有添加进去了才会生效
 
    CellFormatterBuilder cellFormatterBuilder = new CellFormatterBuilder();//实例化一个单元格格式化器
    cellFormatterBuilder.AddFormatter("rptdate", DateTime.Today.ToString("yyyy-MM-dd HH:mm"));//将模板表格中rptdate的值设置为当前日期
    formatterContainers.AppendFormatterBuilder(cellFormatterBuilder);//添加到工作薄格式容器中,注意只有添加进去了才会生效
 
    //实例化一个表格格式化器,studentList本身就是可枚举的无需转换,name表示的模板表格中第一行第一个单元格要填充的数据参数名
    TableFormatterBuilder<Student> tableFormatterBuilder = new TableFormatterBuilder<Student>(studentList, "name");
    tableFormatterBuilder.AddFormatters(new Dictionary<string, Func<Student, object>>{
        {"name",r=>r.Name},//将模板表格中name对应Student对象中的属性Name
        {"sex",r=>r.Sex},//将模板表格中sex对应Student对象中的属性Sex
        {"km",r=>r.KM},//将模板表格中km对应Student对象中的属性KM
        {"score",r=>r.Score},//将模板表格中score对应Student对象中的属性Score
        {"result",r=>r.Result}//将模板表格中result对应Student对象中的属性Result
    });
    formatterContainers.AppendFormatterBuilder(tableFormatterBuilder);
 
    string excelPath = ExcelUtility.Export.ToExcelWithTemplate(templateFilePath, "table", formatterContainers);
    Assert.IsTrue(File.Exists(excelPath));
 
}

模板同上一个模板

导出结果如下:

技术分享

 

3.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
/// <summary>
/// 测试方法:测试依据模板+DataTable来生成多表格EXCEL(注意:由于ExcelReport框架限制,目前仅支持模板文件格式为:xls)
/// </summary>
[TestMethod]
public void TestExportToRepeaterExcelWithTemplateByDataTable()
{
    DataTable dt = GetDataTable();//获取数据
    string templateFilePath = AppDomain.CurrentDomain.BaseDirectory + "/excel2.xls"//获得EXCEL模板路径
    SheetFormatterContainer formatterContainers = new SheetFormatterContainer(); //实例化一个模板数据格式化容器
 
    //实例化一个可重复表格格式化器,dt.Select()是将DataTable转换成DataRow[],rpt_begin表示的模板表格开始位置参数名,rpt_end表示的模板表格结束位置参数名
    RepeaterFormatterBuilder<DataRow> tableFormatterBuilder = new RepeaterFormatterBuilder<DataRow>(dt.Select(), "rpt_begin""rpt_end");
    tableFormatterBuilder.AddFormatters(new Dictionary<string, Func<DataRow, object>>{
        {"sex",r=>r["Col2"]},//将模板表格中sex对应DataTable中的列Col2
        {"km",r=>r["Col3"]},//将模板表格中km对应DataTable中的列Col3
        {"score",r=>r["Col4"]},//将模板表格中score对应DataTable中的列Col4
        {"result",r=>r["Col5"]}//将模板表格中result对应DataTable中的列Co5
    });
 
    PartFormatterBuilder<DataRow> partFormatterBuilder2 = new PartFormatterBuilder<DataRow>();//实例化一个可嵌套的局部元素格式化器
    partFormatterBuilder2.AddFormatter("name", r => r["Col1"]);//将模板表格中name对应DataTable中的列Col1
    tableFormatterBuilder.AppendFormatterBuilder(partFormatterBuilder2);//添加到可重复表格格式化器中,作为其子格式化器
 
 
    CellFormatterBuilder<DataRow> cellFormatterBuilder = new CellFormatterBuilder<DataRow>();//实例化一个可嵌套的单元格格式化器
    cellFormatterBuilder.AddFormatter("rptdate", r => DateTime.Today.ToString("yyyy-MM-dd HH:mm"));//将模板表格中rptdate的值设置为当前日期
    tableFormatterBuilder.AppendFormatterBuilder(cellFormatterBuilder);//添加到可重复表格格式化器中,作为其子格式化器
 
    formatterContainers.AppendFormatterBuilder(tableFormatterBuilder);//添加到工作薄格式容器中,注意只有添加进去了才会生效
 
    string excelPath = ExcelUtility.Export.ToExcelWithTemplate(templateFilePath, "multtable", formatterContainers);
    Assert.IsTrue(File.Exists(excelPath));
}

模板如下:

技术分享

导出结果如下:

技术分享

 

4.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
/// <summary>
/// 测试方法:测试依据复杂模板(含固定表格,可重复表格)+DataTable来生成EXCEL (注意:由于ExcelReport框架限制,目前仅支持模板文件格式为:xls)
/// </summary>
[TestMethod]
public void TestExportToExcelWithTemplateByList2()
{
    var schoolLevelList = SchoolLevel.GetList();
    var classList = ClassInfo.GetList();
    string templateFilePath = AppDomain.CurrentDomain.BaseDirectory + "/mb.xls"//获得EXCEL模板路径
    SheetFormatterContainer formatterContainers = new SheetFormatterContainer(); //实例化一个模板数据格式化容器
 
    PartFormatterBuilder partFormatterBuilder = new PartFormatterBuilder();
    partFormatterBuilder.AddFormatter("school""跨越小学");
    formatterContainers.AppendFormatterBuilder(partFormatterBuilder);
 
    TableFormatterBuilder<SchoolLevel> tableFormatterBuilder = new TableFormatterBuilder<SchoolLevel>(schoolLevelList, "lv");//实例化一个表格格式化器
    tableFormatterBuilder.AddFormatters(new Dictionary<string, Func<SchoolLevel, object>>
    {
        {"lv",r=>r.LevelName}, //模板参数与数据源SchoolLevel属性对应关系,下同
        {"clscount",r=>r.ClassCount},
        {"lvmaster",r=>r.Master}
    });
    formatterContainers.AppendFormatterBuilder(tableFormatterBuilder);//添加到工作薄格式容器中,注意只有添加进去了才会生效
 
    RepeaterFormatterBuilder<ClassInfo> repeaterFormatterBuilder = new RepeaterFormatterBuilder<ClassInfo>(classList, "lv_begin""lv_end");//实例化一个可重复表格格式化器
    repeaterFormatterBuilder.AddFormatters(new Dictionary<string, Func<ClassInfo, object>> {
        {"class",r=>r.ClassName}, //模板参数与数据源ClassInfo属性对应关系,下同
        {"stucount",r=>r.StudentCount},
        {"clsmaster",r=>r.Master},
        {"lvitem",r=>r.LevelName}
    });
    formatterContainers.AppendFormatterBuilder(repeaterFormatterBuilder);//添加到工作薄格式容器中,注意只有添加进去了才会生效
 
    string excelPath = ExcelUtility.Export.ToExcelWithTemplate(templateFilePath, "school", formatterContainers);
    Assert.IsTrue(File.Exists(excelPath));
 
}

模板如下:

技术分享

导出结果如下:

技术分享

 

5.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
/// <summary>
/// 测试方法:测试依据复杂模板(含固定表格,可重复表格中嵌套表格)+DataTable来生成EXCEL (注意:由于ExcelReport框架限制,目前仅支持模板文件格式为:xls)
/// </summary>
[TestMethod]
public void TestExportToExcelWithTemplateByList3()
{
    var schoolLevelList = SchoolLevel.GetList();
    var classList = ClassInfo.GetListWithLevels();
 
    string templateFilePath = AppDomain.CurrentDomain.BaseDirectory + "/mb1.xls"//获得EXCEL模板路径
    SheetFormatterContainer formatterContainers = new SheetFormatterContainer(); //实例化一个模板数据格式化容器
 
    PartFormatterBuilder partFormatterBuilder = new PartFormatterBuilder();
    partFormatterBuilder.AddFormatter("school""跨越小学");
    formatterContainers.AppendFormatterBuilder(partFormatterBuilder);
 
    TableFormatterBuilder<SchoolLevel> tableFormatterBuilder = new TableFormatterBuilder<SchoolLevel>(schoolLevelList, "lv");//实例化一个表格格式化器
    tableFormatterBuilder.AddFormatters(new Dictionary<string, Func<SchoolLevel, object>>
    {
        {"lv",r=>r.LevelName}, //模板参数与数据源SchoolLevel属性对应关系,下同
        {"clscount",r=>r.ClassCount},
        {"lvmaster",r=>r.Master}
    });
    formatterContainers.AppendFormatterBuilder(tableFormatterBuilder);//添加到工作薄格式容器中,注意只有添加进去了才会生效
 
    RepeaterFormatterBuilder<KeyValuePair<string, List<ClassInfo>>> repeaterFormatterBuilder = new RepeaterFormatterBuilder<KeyValuePair<string, List<ClassInfo>>>(classList, "lv_begin""lv_end");
    repeaterFormatterBuilder.AddFormatter("lvitem",r=>r.Key);
 
     TableFormatterBuilder<KeyValuePair<string, List<ClassInfo>>,ClassInfo> tableFormatterBuilder2=new TableFormatterBuilder<KeyValuePair<string, List<ClassInfo>>,ClassInfo>(r=>r.Value,"class");
    tableFormatterBuilder2.AddFormatter("class",r=>r.ClassName);
    tableFormatterBuilder2.AddFormatter("stucount",r=>r.StudentCount);
    tableFormatterBuilder2.AddFormatter("clsmaster",r=>r.Master);
 
    repeaterFormatterBuilder.AppendFormatterBuilder(tableFormatterBuilder2);
 
    formatterContainers.AppendFormatterBuilder(repeaterFormatterBuilder);//添加到工作薄格式容器中,注意只有添加进去了才会生效
 
    string excelPath = ExcelUtility.Export.ToExcelWithTemplate(templateFilePath, "school", formatterContainers);
    Assert.IsTrue(File.Exists(excelPath));
 
}

模板如下:

技术分享

导出结果如下:

技术分享

 

6.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
/// <summary>
/// 测试方法:测试依据复杂模板(多工作薄,且含固定表格,可重复表格)+DataSet来生成EXCEL,只支持XLS
/// </summary>
[TestMethod]
public void TestExportToExcelWithTemplateByDataSet()
{
    var ds = GetDataSet();
    string templateFilePath = AppDomain.CurrentDomain.BaseDirectory + "/mb2.xls"//获得EXCEL模板路径
    Dictionary<string, SheetFormatterContainer> formatterContainerDic = new Dictionary<string, SheetFormatterContainer>(); //实例化一个模板数据格式化容器数组,包含两个SheetFormatterContainer用于格式化两个工作薄
 
 
    #region 创建第一个工作薄格式化容器,并设置相关参数对应关系
 
    SheetFormatterContainer formatterContainer1 = new SheetFormatterContainer();
 
    PartFormatterBuilder partFormatterBuilder = new PartFormatterBuilder();
    partFormatterBuilder.AddFormatter("school""跨越小学");
    formatterContainer1.AppendFormatterBuilder(partFormatterBuilder);
 
    TableFormatterBuilder<DataRow> tableFormatterBuilder = new TableFormatterBuilder<DataRow>(ds.Tables[0].Select(), "lv");//实例化一个表格格式化器
    tableFormatterBuilder.AddFormatters(new Dictionary<string, Func<DataRow, object>>
    {
        {"lv",r=>r["Col1"]}, //模板参数与数据源DataTable属性对应关系,下同
        {"clscount",r=>r["Col2"]},
        {"lvmaster",r=>r["Col3"]}
    });
    formatterContainer1.AppendFormatterBuilder(tableFormatterBuilder);//添加到工作薄格式容器中,注意只有添加

以上是关于NPOI+ExcelReport的主要内容,如果未能解决你的问题,请参考以下文章

记一次NPOI的使用

NPOI 列宽自适应 代码示例

c#使用NPOI进行Excel导入导出,附源码,vs2010

NPOI操作Excel文件

NPOI通过NPOI从内存流中创建EXCEL

NPOI 导出 excel 性能测试