• 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作者,

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

  • 相关阅读:
    Windows server 2016 解决“无法完成域加入,原因是试图加入的域的SID与本计算机的SID相同。”
    Windows Server 2016 辅助域控制器搭建
    Windows Server 2016 主域控制器搭建
    Net Framework 4.7.2 覆盖 Net Framework 4.5 解决办法
    SQL SERVER 2012更改默认的端口号为1772
    Windows下彻底卸载删除SQL Serever2012
    在Windows Server2016中安装SQL Server2016
    SQL Server 创建索引
    C#控制台或应用程序中两个多个Main()方法的设置
    Icon cache rebuilding with Delphi(Delphi 清除Windows 图标缓存源代码)
  • 原文地址:https://www.cnblogs.com/lyd2016/p/7989248.html
Copyright © 2020-2023  润新知