分享我基于NPOI+ExcelReport实现的导入与导出EXCEL类库:ExcelUtility (续2篇-模板导出综合示例)

简介:

自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); //添加到工作薄格式容器中,注意只有添加进去了才会生效
 
     RepeaterFormatterBuilder<DataRow> repeaterFormatterBuilder =  new  RepeaterFormatterBuilder<DataRow>(ds.Tables[1].Select(),  "lv_begin" "lv_end" ); //实例化一个可重复表格格式化器
     repeaterFormatterBuilder.AddFormatters( new  Dictionary< string , Func<DataRow,  object >> {
         { "class" ,r=>r[ "Col1" ]},  //模板参数与数据源ClassInfo属性对应关系,下同
         { "stucount" ,r=>r[ "Col2" ]},
         { "clsmaster" ,r=>r[ "Col3" ]},
         { "lvitem" ,r=>r[ "Col4" ]}
     });
     formatterContainer1.AppendFormatterBuilder(repeaterFormatterBuilder); //添加到工作薄格式容器中,注意只有添加进去了才会生效
 
     formatterContainerDic.Add( "table1" , formatterContainer1); //添加到工作薄格式容器数组中,注意此处的Key值为模板上工作薄的名称,此处即为:table1
 
     #endregion
 
 
     #region 创建第二个工作薄格式化容器,并设置相关参数对应关系
 
     SheetFormatterContainer formatterContainer2 =  new  SheetFormatterContainer();  //实例化一个模板数据格式化容器
 
     PartFormatterBuilder partFormatterBuilder2 =  new  PartFormatterBuilder(); //实例化一个局部元素格式化器
     partFormatterBuilder2.AddFormatter( "Title" "跨越IT学员" ); //将模板表格中Title的值设置为跨越IT学员
     formatterContainer2.AppendFormatterBuilder(partFormatterBuilder2); //添加到工作薄格式容器中,注意只有添加进去了才会生效
 
     CellFormatterBuilder cellFormatterBuilder2 =  new  CellFormatterBuilder(); //实例化一个单元格格式化器
     cellFormatterBuilder2.AddFormatter( "rptdate" , DateTime.Today.ToString( "yyyy-MM-dd HH:mm" )); //将模板表格中rptdate的值设置为当前日期
     formatterContainer2.AppendFormatterBuilder(cellFormatterBuilder2); //添加到工作薄格式容器中,注意只有添加进去了才会生效
 
     //实例化一个表格格式化器,dt.Select()是将DataTable转换成DataRow[],name表示的模板表格中第一行第一个单元格要填充的数据参数名
     TableFormatterBuilder<DataRow> tableFormatterBuilder2 =  new  TableFormatterBuilder<DataRow>(ds.Tables[2].Select(),  "name" );
     tableFormatterBuilder2.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
     });
     formatterContainer2.AppendFormatterBuilder(tableFormatterBuilder2); //添加到工作薄格式容器中,注意只有添加进去了才会生效
 
     formatterContainerDic.Add( "table2" , formatterContainer2); //添加到工作薄格式容器数组中,注意此处的Key值为模板上工作薄的名称,此处即为:table2
 
     #endregion
 
     string  excelPath = ExcelUtility.Export.ToExcelWithTemplate(templateFilePath, formatterContainerDic);
     Assert.IsTrue(File.Exists(excelPath));
 
}

模板如下:

    

导出结果如下:

   

 

二、ExcelUtility类库操作说明(嵌入图片示例)

一、 制作模板(含图片)
1. 制作模板的文件格式需为兼容格式,即:xls或xlt;
2. 模板变量(或称为占位符)定义与之前相同,即:$[变量名];
3. 图片变量定义如下:
a) 绘制一个图形,图形形状尽可能的与要显示的图片相同,比如:印章,则可绘制一个圆形;
b) 图形必需是透明背景,边框可要可不要,建议留着,这样后续调整比较方便,如下图中的蓝色透明背景圆形:

c) 图形大小尽可能与要显示的图片大小相同,如下图示:

 

由于EXCEL上大小默认采用厘米,而图片一般采用像素,所以需要自己换算一下像素对应的厘米数(也可将EXCEL计算单位设为像素,方法自行网上查找);也可网上下载单位转换工具
另外图形属性建议设置成如下图:

温馨提示:图形形状、属性若未设置一般不影响导出效果,但不排除其它异常情况,图形大小是一定要设置,且尽可能与要显示图形大小(高、宽)相同,否则有可能造成导出变形

代码示例:

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
/// <summary>
     /// 测试方法:测试依据模板+DataTable+图片来生成包含图片的EXCEL,只支持XLS
     /// </summary>
     [TestMethod]
     public  void  TestInsertPic()
     {
         DataTable dt = GetDataTable(); //获取数据
         string  templateFilePath = AppDomain.CurrentDomain.BaseDirectory +  "/excel.xls" //获得EXCEL模板路径
         SheetFormatterContainer formatterContainers =  new  SheetFormatterContainer();  //实例化一个模板数据格式化容器
 
 
         PartFormatterBuilder partFormatterBuilder =  new  PartFormatterBuilder(); //实例化一个局部元素格式化器
         partFormatterBuilder.AddFormatter( "Title" "跨越IT学员" ); //将模板表格中Title的值设置为跨越IT学员d
         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  picPath = AppDomain.CurrentDomain.BaseDirectory +  "\\tz.png" ; //图片路径
         PictureWithShapeFormatterBuilder pictureBuilder =  new  PictureWithShapeFormatterBuilder(); //实例化一个图片关联图形格式化器
         //pictureBuilder.AddFormatter(picPath);//当sheet中只有一个图形时,我们可以省略指定区域,那么默认就是把整个工作薄区域当成一个寻找图形区域,若sheet中包含多个,则应指定区域,替换成如下语句
         pictureBuilder.AddFormatter(picPath,5,60000, 0, 3,  false ); //第一个参数为图片路径,中间4个参数为数字型指定图形寻找的工作薄区域(行索引,列索引,索引从0开始计),最后一个为是否自适应大小,一般不建议使用,除非压缩图片
         formatterContainers.AppendFormatterBuilder(pictureBuilder);
 
         string  excelPath = ExcelUtility.Export.ToExcelWithTemplate(templateFilePath,  "table" , formatterContainers);
         Assert.IsTrue(File.Exists(excelPath));
     }

模板如下:

注意图片若需要为透明背景格式,则必需使用PNG格式,NPOI支持的图片主要格式有:PNG,JPG

导出结果如下:

温馨提示:
pictureBuilder.AddFormatter(picPath);//当sheet中只有一个图形时,我们可以省略指定区域,那么默认就是把整个工作薄区域当成一个寻找图形区域,若sheet中包含多个,则应指定区域,替换成如下语句
pictureBuilder.AddFormatter(picPath,5,60000, 0, 3, false);//第一个参数为图片路径,中间4个参数为数字型指定图形寻找的工作薄区域(行索引(起止),列索引(起止),索引从0开始计),最后一个为是否自适应大小,一般不建议使用,除非压缩图片


如果图形可能随单元格进行位置调整,那么在指定图形区域时需注意,如果图形会随单元格下移,那么结束行索引(MinRow)就需要指定一个可能的最大值或不指定,如果图形会随单元格右移,那么结束列索引(MinColumn)就需要指定一个可能的最大值或不指定,如果存在多个图形区域,则上述情况都必需给定具体值(可能的最大值),以免造成区域交叉,从而导致图片显示不正确,如下示例:

//图形可能下移,可能右移,那么将结束行设为可能最大值:60000,结束列设为可能最大值:255
pictureBuilder.AddFormatter(picPath, 5, 60000, 0, 255, false);

//此处只指定开始行与开始列,与上面差不多,但建议使用上面的用法
pictureBuilder.AddFormatter(new PictureWithShapeInfo(picPath, new SheetRange() {MinRow=5,MinColumn=0 },false));

 

特别说明:

1.本类库是基于NPOI+ExcelReport,所有功能凡我的类库能够实现的,NPOI与ExcelReport都可以实现,只是用法及复杂程度不同而矣,我封装的目的就是为了降低大家的学习难度,提高使用效率,免费且开源,源代码同步更新至开源社区的GIT目录中,具体地址请看我该系列之前的文章有列出,在此就不再说明。

2.上述图片关联图形显示功能我是在ExcelReport基础上增加了一个PictureWithShapeFormatter类及其相关的类:PictureWithShapeInfo、SheetRange,因没有关联GIT,所以是在本地更新的,这几个类的代码如下:

PictureWithShapeFormatter:

PictureWithShapeInfo、SheetRange:

分享我基于NPOI+ExcelReport实现的导入与导出EXCEL类库:ExcelUtility 其它相关文章链接:

 

 

本文转自 梦在旅途 博客园博客,原文链接: http://www.cnblogs.com/zuowj/p/5165921.html ,如需转载请自行联系原作者

相关文章
|
21天前
|
Java API Apache
|
25天前
|
存储 Java API
Java实现导出多个excel表打包到zip文件中,供客户端另存为窗口下载
Java实现导出多个excel表打包到zip文件中,供客户端另存为窗口下载
34 4
|
29天前
|
JavaScript 前端开发 数据处理
Vue导出el-table表格为Excel文件的两种方式
Vue导出el-table表格为Excel文件的两种方式
|
1月前
|
前端开发 JavaScript Java
导出excel的两个方式:前端vue+XLSX 导出excel,vue+后端POI 导出excel,并进行分析、比较
这篇文章介绍了使用前端Vue框架结合XLSX库和后端结合Apache POI库导出Excel文件的两种方法,并对比分析了它们的优缺点。
297 0
|
1月前
|
数据采集 存储 JavaScript
自动化数据处理:使用Selenium与Excel打造的数据爬取管道
本文介绍了一种使用Selenium和Excel结合代理IP技术从WIPO品牌数据库(branddb.wipo.int)自动化爬取专利信息的方法。通过Selenium模拟用户操作,处理JavaScript动态加载页面,利用代理IP避免IP封禁,确保数据爬取稳定性和隐私性。爬取的数据将存储在Excel中,便于后续分析。此外,文章还详细介绍了Selenium的基本设置、代理IP配置及使用技巧,并探讨了未来可能采用的更多防反爬策略,以提升爬虫效率和稳定性。
|
3月前
|
关系型数据库 MySQL Shell
不通过navicat工具怎么把查询数据导出到excel表中
不通过navicat工具怎么把查询数据导出到excel表中
46 0
|
1月前
|
数据处理 Python
Python实用记录(十):获取excel数据并通过列表的形式保存为txt文档、xlsx文档、csv文档
这篇文章介绍了如何使用Python读取Excel文件中的数据,处理后将其保存为txt、xlsx和csv格式的文件。
52 3
Python实用记录(十):获取excel数据并通过列表的形式保存为txt文档、xlsx文档、csv文档
|
1月前
|
easyexcel Java UED
SpringBoot中大量数据导出方案:使用EasyExcel并行导出多个excel文件并压缩zip后下载
在SpringBoot环境中,为了优化大量数据的Excel导出体验,可采用异步方式处理。具体做法是将数据拆分后利用`CompletableFuture`与`ThreadPoolTaskExecutor`并行导出,并使用EasyExcel生成多个Excel文件,最终将其压缩成ZIP文件供下载。此方案提升了导出效率,改善了用户体验。代码示例展示了如何实现这一过程,包括多线程处理、模板导出及资源清理等关键步骤。
|
2月前
|
数据采集 存储 数据挖掘
使用Python读取Excel数据
本文介绍了如何使用Python的`pandas`库读取和操作Excel文件。首先,需要安装`pandas`和`openpyxl`库。接着,通过`read_excel`函数读取Excel数据,并展示了读取特定工作表、查看数据以及计算平均值等操作。此外,还介绍了选择特定列、筛选数据和数据清洗等常用操作。`pandas`是一个强大且易用的工具,适用于日常数据处理工作。
|
3月前
|
SQL JSON 关系型数据库
n种方式教你用python读写excel等数据文件
n种方式教你用python读写excel等数据文件