NPOI獲得EXCEL文件中的所有圖片

代碼如下(一個圖片數據類,一個拓展方法類).

調用方法:List<PicturesInfo> infos = sheet.GetAllPictureInfos(row, row + 1, col, col + 2, true);

注意:有些圖片讀取會出異常,原因未知.

 

/// <summary>
/// 貼入Excel的圖片數據,包括圖片數據及位置
/// </summary>
public class PicturesInfo
{
    /// <summary>
    /// 起始單元格行序號
    /// </summary>
    public int MinRow { get; set; }
    /// <summary>
    /// 終止單元格行序號
    /// </summary>
    public int MaxRow { get; set; }
    /// <summary>
    /// 起始單元格列序號
    /// </summary>
    public int MinCol { get; set; }
    /// <summary>
    /// 終止單元格列序號
    /// </summary>
    public int MaxCol { get; set; }
    /// <summary>
    /// 起始單元格的x偏移量
    /// </summary>
    public int dx1 { get; set; }
    /// <summary>
    /// 終止單元格的x偏移量
    /// </summary>
    public int dx2 { get; set; }
    /// <summary>
    /// 起始單元格的y偏移量
    /// </summary>
    public int dy1 { get; set; }
    /// <summary>
    /// 終止單元格的y偏移量
    /// </summary>
    public int dy2 { get; set; }
    /// <summary>
    /// 圖片數據(PNG文件格式)
    /// </summary>
    public Byte[] PictureData { get; private set; }

    public PicturesInfo(int minRow, int maxRow, int minCol, int maxCol,
        int dx1, int dx2, int dy1, int dy2, Byte[] pictureData)
    {
        this.MinRow = minRow;
        this.MaxRow = maxRow;
        this.MinCol = minCol;
        this.MaxCol = maxCol;
        this.dx1 = dx1;
        this.dx2 = dx2;
        this.dy1 = dy1;
        this.dy2 = dy2;

        this.PictureData = pictureData;
    }
}
public static class NpoiExtend
{
    public static List<PicturesInfo> GetAllPictureInfos(this ISheet sheet)
    {
        return sheet.GetAllPictureInfos(null, null, null, null);
    }
    /// <summary>
    /// 獲得在單元格範圍內的所有圖片
    /// </summary>
    /// <param name="sheet"></param>
    /// <param name="minRow"></param>
    /// <param name="maxRow"></param>
    /// <param name="minCol"></param>
    /// <param name="maxCol"></param>
    /// <param name="onlyInternal"></param>
    /// <returns></returns>
    public static List<PicturesInfo> GetAllPictureInfos(this ISheet sheet, int? minRow, int? maxRow, int? minCol, int? maxCol, bool onlyInternal = false)
    {
        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,
                            anchor.Dx1, anchor.Dx2, anchor.Dy1, anchor.Dy2, 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,
                                anchor.Dx1, anchor.Dx2, anchor.Dy1, anchor.Dy2, picture.PictureData.Data));
                        }
                    }
                }
            }
        }

        return picturesInfoList;
    }
    /// <summary>
    /// 範圍是否相交
    /// </summary>
    /// <param name="rangeMinRow"></param>
    /// <param name="rangeMaxRow"></param>
    /// <param name="rangeMinCol"></param>
    /// <param name="rangeMaxCol"></param>
    /// <param name="pictureMinRow"></param>
    /// <param name="pictureMaxRow"></param>
    /// <param name="pictureMinCol"></param>
    /// <param name="pictureMaxCol"></param>
    /// <param name="onlyInternal"></param>
    /// <returns></returns>
    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)));
        }
    }
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章