问题背景:

话说,在ExcelReport的开发过程中,有一个比较棘手的问题:怎么复制图片呢?

当然,解决这个问题的第一步是:能使用NPOI提取到图片及图片的位置信息。到这里,一切想法都很顺利。但NPOI到底怎么提取图片及图片的位置信息呢?NPOI能不能提取到图片的位置信息呢?

这是两个问题。是两个让BaiGoogleDu几近沉默的问题。但官方教程的评论中还是流露出了答案的蛛丝马迹。

哇咔咔,这是我去看源码寻答案的的动力。

此处省去(N多字)… …,这里宕掉了我三个晚上的时间。

不再累述,代码你懂的… ….

PicturesInfo.cs

public class PicturesInfo

{

    public int MinRow { get;set; }

    public int MaxRow { get;set; }

    public int MinCol { get;set; }

    public int MaxCol { get;set; }

    public Byte[] PictureData { get; private set; }

 

    public PicturesInfo(int minRow, int maxRow, int minCol, int maxCol,Byte[] pictureData)

    {

        this.MinRow = minRow;

        this.MaxRow = maxRow;

        this.MinCol = minCol;

        this.MaxCol = maxCol;

        this.PictureData = pictureData;

    }

}

NpoiExtend.cs

public static class NpoiExtend

{

    public static List<PicturesInfo> GetAllPictureInfos(this ISheet sheet)

    {

        return sheet.GetAllPictureInfos(null,null,null,null);

    }

 

    public static List<PicturesInfo> GetAllPictureInfos(this ISheet sheet,int? minRow,int? maxRow,int? minCol,int? maxCol,bool onlyInternal = true)

    {

        if (sheet is HSSFSheet)

        {

            return GetAllPictureInfos((HSSFSheet)sheet,minRow,maxRow,minCol,maxCol,onlyInternal);

        }

        else if (sheet is XSSFSheet)

        {

            return GetAllPictureInfos((XSSFSheet)sheet, minRow, maxRow, minCol, maxCol, onlyInternal);

        }

        else

        {

            throw new Exception("未处理类型,没有为该类型添加:GetAllPicturesInfos()扩展方法!");

        }

    }

 

    private static List<PicturesInfo> GetAllPictureInfos(HSSFSheet sheet,int? minRow, int? maxRow, int? minCol, int? maxCol, bool onlyInternal)

    {

        List<PicturesInfo> picturesInfoList = new List<PicturesInfo>();

 

        var shapeContainer = sheet.DrawingPatriarch as HSSFShapeContainer;

        if (null != shapeContainer)

        {

            var shapeList = shapeContainer.Children;

            foreach (var shape in shapeList)

            {

                if (shape is HSSFPicture && shape.Anchor is HSSFClientAnchor)

                {

                    var picture = (HSSFPicture)shape;

                    var anchor = (HSSFClientAnchor)shape.Anchor;

                    

                    if (IsInternalOrIntersect(minRow, maxRow, minCol, maxCol, anchor.Row1, anchor.Row2, anchor.Col1, anchor.Col2, onlyInternal))

                    {

                        picturesInfoList.Add(new PicturesInfo(anchor.Row1, anchor.Row2, anchor.Col1, anchor.Col2, picture.PictureData.Data));

                    }

                }

            }

        }

 

        return picturesInfoList;

    }

 

    private static List<PicturesInfo> GetAllPictureInfos(XSSFSheet sheet, int? minRow, int? maxRow, int? minCol, int? maxCol, bool onlyInternal)

    {

        List<PicturesInfo> picturesInfoList = new List<PicturesInfo>();

 

        var documentPartList = sheet.GetRelations();

        foreach (var documentPart in documentPartList)

        {

            if (documentPart is XSSFDrawing)

            {

                var drawing = (XSSFDrawing)documentPart;

                var shapeList = drawing.GetShapes();

                foreach (var shape in shapeList)

                {

                    if (shape is XSSFPicture)

                    {

                        var picture = (XSSFPicture)shape;

                        var anchor = picture.GetPreferredSize();

                        

                        if (IsInternalOrIntersect(minRow, maxRow, minCol, maxCol, anchor.Row1, anchor.Row2, anchor.Col1, anchor.Col2, onlyInternal))

                        {

                            picturesInfoList.Add(new PicturesInfo(anchor.Row1, anchor.Row2, anchor.Col1, anchor.Col2, picture.PictureData.Data));

                        }

                    }

                }

            }

        }

 

        return picturesInfoList;

    }

 

    private static bool IsInternalOrIntersect(int? rangeMinRow, int? rangeMaxRow, int? rangeMinCol, int? rangeMaxCol,

        int pictureMinRow, int pictureMaxRow, int pictureMinCol, int pictureMaxCol, bool onlyInternal)

    {

        int _rangeMinRow = rangeMinRow ?? pictureMinRow;

        int _rangeMaxRow = rangeMaxRow ?? pictureMaxRow;

        int _rangeMinCol = rangeMinCol ?? pictureMinCol;

        int _rangeMaxCol = rangeMaxCol ?? pictureMaxCol;

 

        if (onlyInternal)

        {

            return (_rangeMinRow <= pictureMinRow && _rangeMaxRow >= pictureMaxRow &&

                    _rangeMinCol <= pictureMinCol && _rangeMaxCol >= pictureMaxCol);

        }

        else

        {

            return ((Math.Abs(_rangeMaxRow - _rangeMinRow) + Math.Abs(pictureMaxRow - pictureMinRow) >= Math.Abs(_rangeMaxRow + _rangeMinRow - pictureMaxRow - pictureMinRow)) &&

            (Math.Abs(_rangeMaxCol - _rangeMinCol) + Math.Abs(pictureMaxCol - pictureMinCol) >= Math.Abs(_rangeMaxCol + _rangeMinCol - pictureMaxCol - pictureMinCol)));

        }

    }

}

使用NPOI从Excel中提取图片及图片位置信息的更多相关文章

  1. 如何使用免费PDF控件从PDF文档中提取文本和图片

             如何使用免费PDF控件从PDF文档中提取文本和图片 概要 现在手头的项目有一个需求是从PDF文档中提取文本和图片,我以前也使用过像iTextSharp, PDFBox 这些免费的PD ...

  2. c# 应用NPOI 获取Excel中的图片,保存至本地的算法

    要求:读取excel中的图片,保存到指定路径 思路:  利用NPOI中 GetAllPictures()方法获取图片信息 步骤: 1.新建一个Windows窗体应用程序 2.桌面新建一个excel,贴 ...

  3. 如何在Excel中提取小数点后面的数字?

    Excel中,如果某个单元格中包含一个带小数,要用公式提取该数值小数点后面的数字,例如A1单元格中包含一个数值“59178.68”,在B1单元格中输入下面的公式: =RIGHT(A1,LEN(A1)- ...

  4. 使用Npoi向Excel中插入图片

    先把数据库中的数据都导入到Excel表格中,把图片地址的路径全部转成绝对路径. 使用Npoi读取刚导出的Excle表格,把图片那个单元格的图片路径读出来,然后用文件流读取图片,然后通过Npoi把图片放 ...

  5. Excel中提取最大值的问题

    在使用excel的时候,碰到了一个如下的问题 意思是以每个字母为条件,取这个字母下面的数字中的最大值,需要注意一个问题是每个字母下面的数字个数不一定相等,例如d下面有四个数字,可以设置如下公式解决: ...

  6. python从Excel中提取邮箱

    从各个城市的律师协会去爬取的律师的招聘信息,可是邮箱在招聘简介里面,所有需要写个脚本去提取邮箱 import pandas as pd import re regex = r"([-_a-z ...

  7. 调用存储过程取到数据通过NPOI存到Excel中

        //调用  public ActionResult GenerateExcel() {             DataTable headerTable = new DataTable(); ...

  8. NPOI设置Excel中的单元格识别为日期

    只有月/日/年的格式,才能显示为Date 其他的,都是显示为Custom

  9. 2.4.5 用NPOI操作EXCEL--插入图片

    我们知道,在Excel中是可以插入图片的.操作菜单是“插入->图片”,然后选择要插入图片,可以很容易地在Excel插入图片.同样,在NPOI中,利用代码也可以实现同样的效果.在NPOI中插入图片 ...

随机推荐

  1. eclipse maven testng

    安装过程: 1.eclipse官网下载:

  2. Bookstore project using XAMPP 详细配置 Part 3

    3. Create PHP 1) “Sublime Text” is used as text editor. 2) HTML part of “hello.php” was created as s ...

  3. 条件随机场matlab程序下载

    19:44:23 1 http://www.cs.ubc.ca/~murphyk/Software/CRF/crf.html matlab程序包: 该条件随机场程序(CRF)是针对语句进行标注,mat ...

  4. STM32的DMA

    什么是DMA?其全称是:Direct Memory Access:根据ST公司提供的相关信息,DMA是STM32中一个独立与Cortex-M3内核的模块,有点类似与ADC.PWM.TIMER等模块:主 ...

  5. ABP框架详解(六)Aspects

    这种AOP式的设计非常类似于Asp.net MVC和WebApi中过滤器(Filter)机制,感觉没有太多可讲述的,只能谈谈设计思路. 框架中AspectAttribute特性用于设置到需要被拦截的T ...

  6. SELECT TOP 100 PERCENT 不按后面的order by 排序

    项目中,由于需要把3个状态的任务合并显示,并且按照任务由近及远的顺序排序,类似于下面的语句 order by taskid desc )m union all order by taskid desc ...

  7. maven安装nexus私服

    从nexus官网下载Nexus Repository Manager OSS 2.x的安装包:nexus-2.14.1-01-bundle.tar.gz,3.x版本需要jdk8及以上 解压 tar x ...

  8. 分享一个漂亮WPF界面框架创作过程及其源码

    本文会作为一个系列,分为以下部分来介绍: (1)见识一下这个界面框架: (2)界面框架如何进行开发: (3)辅助开发支持:Demo.模板.VsPackage制作. 框架源码如下所示. 本文介绍第(1) ...

  9. 计划参照mysql-proxy编写mssql-proxy

    目前使用haproxy做了mssql多个读库的负载均衡,在生产环境中运行得不错. 不过,这个方案有缺点:客户端需要选择是使用读库,还是写库.这样还是不够方便,如果能够实现自动路由就更好了,即让hapr ...

  10. Entity Framework 5.0系列之数据操作

    Entity Framework将概念模型中定义的实体和关系映射到数据源,利用实体框架可以将数据源返回的数据具体化为对象:跟踪对象所做的更改:并发处理:将对象更改传播到数据源等.今天我们就一起讨论如何 ...