问题背景:

话说,在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. SQL分页常用的两个存储过程

    在做数据绑定时,我们常常会遇到分页事件,下面记录一下分页常用到SQL的两个存储过程 ①/****分页数据总数****//****** 对象:  StoredProcedure [dbo].[GetRe ...

  2. vim中输入tab符

    今天在写Makefile时各种出错.后来发现是all:的下一行,make前面必须是tab符,不能是空格. 但是vim中只要按tab就会自动转换成4个空格.平时编程需要,也不便把这个设置取消. 查了下, ...

  3. Python成长笔记 - 基础篇 (十一)

    回顾: 线程:资源的集合:内存共享,两个或多个线程同时修改一份数据时,造成结果可能不正确,必须加锁 进程:运行的最小单元 守护进程:在start之前设置setDemo() 队列queue:作用解耦,使 ...

  4. iOS7界面的兼容性调整之一

      if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7) {   self.edgesForExtendedLayout ...

  5. 0003--Weekly Meeting on 10th April and 17th April, 2015

    10th April, 2015 (1) Orthogonal Matching Pursuit, Least Angle Regression, Dictionary Coherence. -> ...

  6. idlcpp 功能改进

    最近没有续写 idlcpp 的教程, 因为忙着对它进行大幅度的修改. 一开始本是计划用idlcpp对付新写的代码,让这些新写的代码能够很容易提供给脚本使用.后来又希望能将大量现存的代码移植过来,毕竟有 ...

  7. Apache HTTP Server 2.2.26 发布

    Apache遗留产品线2.2.26发布.2013-11-13 之前的版本是2013-07-02的2.2.25 同样先在开发目录下放出下载,然后放到正式目录下.修正了大量的Bug.目前的稳定版2.4系列 ...

  8. HTTP解析

    前言 B/S网络架构的核心是HTTP,掌握HTTP对一个从事互联网工作的程序员来说非常重要.要理解HTTP,最重要的是要熟悉HTTP的HTTP Header,HTTP Header控制着互联网上成千上 ...

  9. 浅析Ajax跨域原理及JQuery中的实现分析

    AJAX 的出现使得网页可以通过在后台与服务器进行少量数据交换,实现网页的局部刷新.但是出于安全的考虑,ajax不允许跨域通信.如果尝试从不同的域请求数据,就会出现错误.如果能控制数据驻留的远程服务器 ...

  10. 如何用django开发一个简易个人Blog

    功能概要:(目前已实现功能) 公共展示部分: 1.网站首页展示已发布的博客记录,包括名称.摘要信息.发布日期.阅读量及评论数. 2.首页文章列表可按照分类筛选. 3.点击标题或阅读全文链接,进入博客阅 ...