分享我基于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 其它相关文章链接:

NPOI+ExcelReport的更多相关文章

  1. 分享我基于NPOI+ExcelReport实现的导入与导出EXCEL类库:ExcelUtility (续3篇-导出时动态生成多Sheet EXCEL)

    ExcelUtility 类库经过我(梦在旅途)近期不断的优化与新增功能,现已基本趋向稳定,功能上也基本可以满足绝大部份的EXCEL导出需求,该类库已在我们公司大型ERP系统全面使用,效果不错,今天应 ...

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

    自ExcelUtility类推出以来,经过项目中的实际使用与不断完善,现在又做了许多的优化并增加了许多的功能,本篇不再讲述原理,直接贴出示例代码以及相关的模板.结果图,以便大家快速掌握,另外这些示例说 ...

  3. 分享我基于NPOI+ExcelReport实现的导入与导出EXCEL类库:ExcelUtility (续篇)

    上周六我发表的文章<分享我基于NPOI+ExcelReport实现的导入与导出EXCEL类库:ExcelUtility>受到了大家的热烈支持与推荐,再此表示感谢,该ExcelUtility ...

  4. 分享我基于NPOI+ExcelReport实现的导入与导出EXCEL类库:ExcelUtility

    1. ExcelUtility功能:  1.将数据导出到EXCEL(支持XLS,XLSX,支持多种类型模板,支持列宽自适应)  类名:ExcelUtility. Export  2.将EXCEL ...

  5. 【EXCEL终极总结分享】基于NPOI扩展封装的简易操作工具类库(简单灵活易用,支持导出、导入、上传等常见操作)

    对于EXCEL的导入.导出,我之前已分享过多次,比如: 第一种方案:<我写的一个ExcelHelper通用类,可用于读取或生成数据>这个主要是利用把EXCEL当成一个DB来进行获取数据,导 ...

  6. .NET Core/.NET5/.NET6 开源项目汇总1:常用必备组件

    系列目录     [已更新最新开发文章,点击查看详细] 开源项目是众多组织与个人分享的组件或项目,作者付出的心血我们是无法体会的,所以首先大家要心存感激.尊重.请严格遵守每个项目的开源协议后再使用.尊 ...

  7. 基于NPOI的报表引擎——ExcelReport

    前言 其实现在说ExcelReport是报表引擎还为时尚早,但该组件我既然要决心维护下去,这便算是初衷吧! 1.现在,ExcelReport能为你做什么呢? 如果,你有导出数据到Excel的需求,Ex ...

  8. 开源组件ExcelReport 1.5.2 使用手册

    ExcelReport是一款基于NPOI开发的报表引擎组件.它基于关注点分离的理念,将数据与样式.格式分离.让模板承载样式.格式等NPOI不怎么擅长且实现繁琐的信息,结合NPOI对数据的处理的优点将E ...

  9. 导出数据到Excel --使用ExcelReport有感

    先看图,这是几个月前用NPOI写的导出数据到Excel,用了上百行代码,而且难控制,导出来也比较难看 excel打开的效果 下面是我用ExcelReport类库导出到Excel的操作 1.首先引用Ex ...

随机推荐

  1. [初探iOS开发]storyboard的使用

    storyboard的目的是为了方便的设计程序view之间的关系,使得程序员把精力都放到核心业务逻辑之上.

  2. Nagios监控系统的安装

    环境:centOS 6.5 X86 64位 nagios-4.08 步骤: 1.  最小化安装系统 2.  修改安全特性 关闭SELINUX     SELINUX=disabled 清除iptabl ...

  3. HBase经常使用操作之namespace

    1.介绍 在HBase中,namespace命名空间指对一组表的逻辑分组,类似RDBMS中的database,方便对表在业务上划分.Apache HBase从0.98.0, 0.95.2两个版本号開始 ...

  4. JavaScript发展史,与JScript差别,引入方式,数据类型,命名规范,命名推荐,解决命名冲突

    文件夹: 1.JavaScript发展史 2.JavaScript与JScript差别 3.JavaScript引入方式 4.JavaScript基本数据类型及布尔值 5.JavaScript命名规范 ...

  5. 断言Assert的使用

     转载地址:http://www.cnblogs.com/moondark/archive/2012/03/12/2392315.html 我一直以为assert仅仅是个报错函数,事实上,它居然是个宏 ...

  6. 关于CodeReview(java)(转)

    关于codereview,在平时的开发中,经常忽略的环节,参照目前介绍写好代码的几本书和之前掉进的坑,做了一个总结,分享出来. 为什么要做 通过review规避一些代码层面的问题 提升可读性,方便后续 ...

  7. 【cocos2d-x不要在生产白片步骤】第二项:制作Block分类

    由于游戏非常多使用阻断,因此,我们创建了一个单独的类中Block. 于Blcok.h声明了两个初始化函数: static Block* createWithArgs(Color3B color, Si ...

  8. ubuntu Linux 安装和首次使用

    1.ubuntu Linux 安装后切换到root账户,在默认情况下,系统安装过程中需要创建一个用户,切换到root账号命令如下:$ sudo -s -H输入 当前账户密码就可以切换到root.2.u ...

  9. SQLServer批量备份与还原

    原文地址:http://www.cnblogs.com/fygh/archive/2011/09/09/2172546.html 备份与还原是数据库避不开的主题,而作为DBA,经常会面临将一台机器上的 ...

  10. Cordova CLI源码分析(二)——package.json

    每个包需要在其顶层目录下包含一个package.json文件,该文件不仅是包的说明,也影响npm安装包时的配置选项 更多参数详见参考文档https://npmjs.org/doc/json.html ...