NPOI随笔——图片在单元格等比缩放且居中显示

  NPOI导出的图片默认是在单元格左上方,这使得图片在单元格显示得很难看。居中,且等比缩放,才是图片在单元格上的完美展示。

        /// <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);//等比缩放
            }
        }

原文地址:https://www.cnblogs.com/xbzsz/p/8185266.html

时间: 2024-08-04 22:13:33

NPOI随笔——图片在单元格等比缩放且居中显示的相关文章

NPOI 图片在单元格等比缩放且居中显示

NPOI导出的图片默认是在单元格左上方,这使得图片在单元格显示得很难看.居中,且等比缩放,才是图片在单元格上的完美展示. /// <summary> /// 图片在单元格等比缩放居中显示 /// </summary> /// <param name="cell">单元格</param> /// <param name="value">图片二进制流</param> private void Cel

NPOI之Excel——合并单元格、设置样式、输入公式

首先建立一个空白的工作簿用作测试,并在其中建立空白工作表,在表中建立空白行,在行中建立单元格,并填入内容: //建立空白工作簿 IWorkbook workbook = new HSSFWorkbook(); //在工作簿中:建立空白工作表 ISheet sheet = workbook.CreateSheet(); //在工作表中:建立行,参数为行号,从0计 IRow row = sheet.CreateRow(0); //在行中:建立单元格,参数为列号,从0计 ICell cell = ro

NPOI之Excel——合并单元格、设置样式、输入公式、设置筛选等

首先建立一个空白的工作簿用作测试,并在其中建立空白工作表,在表中建立空白行,在行中建立单元格,并填入内容: //建立空白工作簿 IWorkbook workbook = new HSSFWorkbook(); //在工作簿中:建立空白工作表 ISheet sheet = workbook.CreateSheet(); //在工作表中:建立行,参数为行号,从0计 IRow row = sheet.CreateRow(0); //在行中:建立单元格,参数为列号,从0计 ICell cell = ro

NPOI.dll 用法。单元格,样式,字体,颜色,行高,宽度。读写excel

1.25 NPOI.dll using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using System.Data.SqlClient; using NPOI.HSSF.UserMod

NPOI.dll 用法:单元格、样式、字体、颜色、行高、宽度 读写excel

1.25 NPOI.dll using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using System.Data.SqlClient; using NPOI.HSSF.UserMod

NPOI 生成Excel (单元格合并、设置单元格样式:字段,颜色、设置单元格为下拉框并限制输入值、设置单元格只能输入数字等)

NPIO源码地址:https://github.com/tonyqus/npoi NPIO使用参考:源码中的 NPOITest项目 下面代码包括: 1.包含多个Sheet的Excel 2.单元格合并 3.设置单元格样式:字段,颜色 4.设置单元格为下拉框并限制输入值 5.设置单元格只能输入数字 // // GET: /Excel/ public ActionResult Write() { var workbook = new HSSFWorkbook();//从流内容创建Workbook对象

转载 NPOI.dll 用法。单元格,样式,字体,颜色,行高,宽度。读写excel

我用的版本是1.25的.每个版本用法有一点不同 using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using System.Data.SqlClient; using NPOI.HS

DataGridView单元格内容自动匹配下拉显示

页面显示数据使用的控件是ComponentFactory.Krypton.Toolkit中的KryptonDataGridView控件.在指定“商品”单元格中需要根据用户输入内容自动匹配数据库中商品信息,并且单元格处于编辑模式时显示一个查询图标的按钮,点击该按钮也将显示数据库中所有商品信息. KryptonDataGridView显示控件此处命名为kDGVIndentDetail; 用于下拉显示匹配内容的DataGridView命名为dgv; 1.建立一个DataGridView类型的页面变量用

通过自定义单元格渲染器在Jtable中显示超链接

转载:http://www.tuicool.com/articles/qE7FNv 在JTable中自定义单元格渲染器是非常简单和容易的.对于单元格渲染器来说,它的主要任务就是为目标单元格返回一个Component对象,以呈现其内容.说到Component,就应该豁然开朗了,因为在Swing中,所有可在屏幕上显示的图形控件都是Component的直接或间接子类,也就是说,理论上你可以在JTable单元格中显示任意图形控件! 当然,实际上有一些控件是不能在单元格中显示的,比如JFrame这样的独立