NPOI(2.1.3)向excel中插入图片,xls文档图片插入成功,xlsx文档图片插入失败

众所周知,NPOI对xls和xlsx两个版本的excel文档的操作并没有一个统一的支持,

程序若想兼容这两个版本的操作,必须根据excel版本分别去调用HSSF和XSSF这两套操作库,

之前一直不明白NPOI为什么不能提供一个统一的操作接口,现在我还是不明白,

也正是因为存在这个区别才导致了现在的问题!

插入图片,代码非常简单,

 1 IDrawing patriarch = sheet.CreateDrawingPatriarch();
 2 
 3 //将图片文件读入一个字符串
 4             byte[] bytes = System.IO.File.ReadAllBytes(setVal);
 5 
 6             int pictureIdx = sheet.Workbook.AddPicture(bytes, PictureType.JPEG);
 7 
 8             IClientAnchor anchor = null;
 9             IPicture pict = null;
10 
11             int dx1 = 0, dy1 = 0, dx2 = 1023, dy2 = 255;
12             int col1 = colIndex, row1 = rowIndex, col2 = colIndex, row2 = rowIndex;
13             //图片可能会合并多个单元格,需要计算合并的跨度
14             if (sheet.GetRow(row1).GetCell(col1)!=null&&sheet.GetRow(row1).GetCell(col1).IsMergedCell)
15             {
16                 int rowSpan = 0;
17                 int colSpan = 0;
18                 int regionsCount = sheet.NumMergedRegions;
19                 for (int i = 0; i < regionsCount; i++)
20                 {
21                     CellRangeAddress range = sheet.GetMergedRegion(i);
22                     sheet.IsMergedRegion(range);
23                     if (range.FirstRow == row1 && range.FirstColumn == col1)
24                     {
25                         rowSpan = range.LastRow - range.FirstRow + 1;
26                         colSpan = range.LastColumn - range.FirstColumn + 1;
27                         break;
28                     }
29                 }
30 
31                 col2 = col1 + colSpan - 1;
32                 row2 = row1 + rowSpan - 1;
33             }
34 
35             //anchor = patriarch.CreateAnchor(dx1, dy1, dx2, dy2, col1, row1, col2, row2);
36             ////把图片插到相应的位置
37             //pict = patriarch.CreatePicture(anchor, pictureIdx);
38             if (fileExt == ".xls")
39             {
40                 // 插图片的位置  HSSFClientAnchor(dx1,dy1,dx2,dy2,col1,row1,col2,row2) 
41                 anchor = new HSSFClientAnchor(dx1, dy1, dx2, dy2, col1, row1, col2, row2);
42                 //把图片插到相应的位置
43                 pict = (HSSFPicture)patriarch.CreatePicture(anchor, pictureIdx);
44             }
45             else if (fileExt == ".xlsx")
46             {               
47                 anchor = new XSSFClientAnchor(dx1, dy1, dx2, dy2, col1, row1, col2, row2);
48                 //把图片插到相应的位置
49                 pict = (XSSFPicture)patriarch.CreatePicture(anchor, pictureIdx);                
50             }

最开始的测试模板文件是一个.xls文档,图片插入的目的完美实现,

直到几天之后,来了另外一个.xlsx文档,我代码里面如此明显的支持了它的做法,想当然的以为妥妥的了吧

一测试,瞬间傻眼了懵逼了,导出的文档中怎么都找不到图片!!!

各种修改代码写法(主要是关注类型的转换),调试,没有任何错误和异常,网上搜索了大半天问题,更新最新的NPOI库,甚至到处发帖求教

最后,在网上找了一个简单的XSSF的示例,看上去代码逻辑和我的没什么区别,翻来覆去不就是那么几行代码吗

唯一的不同,示例中的行列参数(col1, row1, col2, row2)是几个明明白白的整数值

单手机械的点了运行,打开文档,嘿~图片居然出现了!只不过由于给的几个参数值很随便,所以图片的位置也很随便

这是个从无到有实现0突破的伟大时刻啊!

瞬间来劲儿了,关注点转向了行列参数值,

经过几轮不同参数值的调试之后,终于在参数和导出的图片位置之间看出了端倪,

代码的修改如下:

1 // 插图片的位置  HSSFClientAnchor(dx1,dy1,dx2,dy2,col1,row1,col2,row2) 
2                 //后面四个参数定位行列的时候,参数(,,,,0,14,11,14)在xls文档中可以正确定位插入图片,
3                 //但是在xlsx文档中图片找不到了,参数改成(,,,,0,14,12,15)才能正确定位画图
4                 //MMP,定位标准都不统一,严重怀疑NPOI的1.x和2.x版本是两拨人完成,并且没有很好的工作交接......
5                 anchor = new XSSFClientAnchor(dx1, dy1, dx2, dy2, col1, row1, col2+1, row2+1);

一行代码我给了四行注释,多余的话也不想再说了,心累。。。。

-------------------------------------

现在慢慢缓过来了,

作为一个给予了广大程序员相当的方便的一个开源库,还是得感谢NPOI作者,

只能怪自己对它的理解不够啊。。。

原文地址:https://www.cnblogs.com/lyd2016/p/7989248.html