NPOI隨筆——圖片在單元格等比縮放且居中顯示

  NPOI導出的圖片默認是在單元格左上方,這使得圖片在單元格顯示得很難看。居中,且等比縮放,纔是圖片在單元格上的完美展現。spa

       

        /// <summary>
        /// 圖片在單元格等比縮放居中顯示
        /// </summary>
        /// <param name="cell">單元格</param>
        /// <param name="value">圖片二進制流</param>
        private void CellImage(ICell cell, byte[] value)
        {
            if (value.Length == 0) return;//空圖片處理
            double scalx = 0;//x軸縮放比例
            double scaly = 0;//y軸縮放比例
            int Dx1 = 0;//圖片左邊相對excel格的位置(x偏移) 範圍值爲:0~1023,超過1023就到右側相鄰的單元格里了
            int Dy1 = 0;//圖片上方相對excel格的位置(y偏移) 範圍值爲:0~256,超過256就到下方的單元格里了
            bool bOriginalSize = false;//是否顯示圖片原始大小 true表示圖片顯示原始大小  false表示顯示圖片縮放後的大小
            ///計算單元格的長度和寬度
            double CellWidth = 0;
            double CellHeight = 0;
            int RowSpanCount = cell.GetSpan().RowSpan;//合併的單元格行數
            int ColSpanCount = cell.GetSpan().ColSpan;//合併的單元格列數 
            int j = 0;
            for (j = 0; j < RowSpanCount; j++)//根據合併的行數計算出高度
            {
                CellHeight += cell.Sheet.GetRow(cell.RowIndex + j).Height;
            }
            for (j = 0; j < ColSpanCount; j++)
            {
                CellWidth += cell.Row.Sheet.GetColumnWidth(cell.ColumnIndex + j);
            }
            //單元格長度和寬度與圖片的長寬單位互換是根據實例得出
            CellWidth = CellWidth / 35;
            CellHeight = CellHeight / 15;
            ///計算圖片的長度和寬度
            MemoryStream ms = new MemoryStream(value);
            Image Img = Bitmap.FromStream(ms, true);
            double ImageOriginalWidth = Img.Width;//原始圖片的長度
            double ImageOriginalHeight = Img.Height;//原始圖片的寬度
            double ImageScalWidth = 0;//縮放後顯示在單元格上的圖片長度
            double ImageScalHeight = 0;//縮放後顯示在單元格上的圖片寬度
            if (CellWidth > ImageOriginalWidth && CellHeight > ImageOriginalHeight)//單元格的長度和寬度比圖片的大,說明單元格能放下整張圖片,不縮放
            {
                ImageScalWidth = ImageOriginalWidth;
                ImageScalHeight = ImageOriginalHeight;
                bOriginalSize = true;
            }
            else//須要縮放,根據單元格和圖片的長寬計算縮放比例
            {
                bOriginalSize = false;
                if (ImageOriginalWidth > CellWidth && ImageOriginalHeight > CellHeight)//圖片的長和寬都比單元格的大的狀況
                {
                    double WidthSub = ImageOriginalWidth - CellWidth;//圖片長與單元格長的差距
                    double HeightSub = ImageOriginalHeight - CellHeight;//圖片寬與單元格寬的差距
                    if (WidthSub > HeightSub)//長的差距比寬的差距大時,長度x軸的縮放比爲1,表示長度就用單元格的長度大小,寬度y軸的縮放比例須要根據x軸的比例來計算
                    {
                        scalx = 1;
                        scaly = (CellWidth / ImageOriginalWidth) * ImageOriginalHeight / CellHeight;//計算y軸的縮放比例,CellWidth / ImageWidth計算出圖片總體的縮放比例,而後 * ImageHeight計算出單元格應該顯示的圖片高度,而後/ CellHeight就是高度的縮放比例
                    }
                    else
                    {
                        scaly = 1;
                        scalx = (CellHeight / ImageOriginalHeight) * ImageOriginalWidth / CellWidth;
                    }
                }
                else if (ImageOriginalWidth > CellWidth && ImageOriginalHeight < CellHeight)//圖片長度大於單元格長度但圖片高度小於單元格高度,此時長度不須要縮放,直接取單元格的,所以scalx=1,但圖片高度須要等比縮放
                {
                    scalx = 1;
                    scaly = (CellWidth / ImageOriginalWidth) * ImageOriginalHeight / CellHeight;
                }
                else if (ImageOriginalWidth < CellWidth && ImageOriginalHeight > CellHeight)//圖片長度小於單元格長度但圖片高度大於單元格高度,此時單元格高度直接取單元格的,scaly = 1,長度須要等比縮放
                {
                    scaly = 1;
                    scalx = (CellHeight / ImageOriginalHeight) * ImageOriginalWidth / CellWidth;
                }
                ImageScalWidth = scalx * CellWidth;
                ImageScalHeight = scaly * CellHeight;
            }
            Dx1 = Convert.ToInt32((CellWidth - ImageScalWidth) / CellWidth * 1023 / 2);
            Dy1 = Convert.ToInt32((CellHeight - ImageScalHeight) / CellHeight * 256 / 2);
            int pictureIdx = cell.Sheet.Workbook.AddPicture((Byte[])value, PictureType.PNG);
            IClientAnchor anchor = cell.Sheet.Workbook.GetCreationHelper().CreateClientAnchor();
            anchor.AnchorType = AnchorType.MoveDontResize;
            anchor.Col1 = cell.ColumnIndex;
            anchor.Col2 = cell.ColumnIndex + cell.GetSpan().ColSpan;
            anchor.Row1 = cell.RowIndex;
            anchor.Row2 = cell.RowIndex + cell.GetSpan().RowSpan;
            anchor.Dy1 = Dy1;//圖片下移量
            anchor.Dx1 = Dx1;//圖片右移量,經過圖片下移和右移,使得圖片能居中顯示,由於圖片不一樣文字,圖片是浮在單元格上的,文字是鉗在單元格里的
            IDrawing patriarch = cell.Sheet.CreateDrawingPatriarch();
            IPicture pic = patriarch.CreatePicture(anchor, pictureIdx);
            if (bOriginalSize)
            {
                pic.Resize();//顯示圖片原始大小 
            }
            else
            {
                pic.Resize(scalx, scaly);//等比縮放   
            }
        }
相關文章
相關標籤/搜索