Excel催化剂开源第45波-按原图大小导出图片

December 17, 2023
测试
测试
测试
测试
3 分钟阅读

从Excel中导出图片,是一个很常规的需求,也有一些久旧不衰的界面操作法小技巧从OpenXml文件中批量导出,在VBA开发中,也会使用Chart对象的背景图的技巧来导出。总体来说,和真正想要的效果还是有差距,特别是这样的方式导出的图片像素会低。 在VSTO开发中,有更好的方式,此篇给大家一一分享。

使用Excel催化剂的插入图片的方式,图片已经存储在PictureBox容器内,想导出时,只需在PictureBox容器上取出其Image属性,即可拿到图片,再简单的一个保存为文件的方法即可完成。

以下为Excel催化剂的批量导出图片功能的代码。核心代码就几句完成,可见用PictureBox容器装载图片的优势非常明显。

        public static void OutputMultiPic()
        {
            foreach (Excel.ListRow row in listObjectOfImageInfo.ListRows)
            {
                Excel.Range shpNameRange = row.Range.Cells[listObjectOfImageInfo.ListColumns["图形名称"].Index];
                Excel.Range filePathRange = row.Range.Cells[listObjectOfImageInfo.ListColumns["导出文件名全路径"].Index];
                if (row.Range.Height>0 && shpNameRange.Value2!=null && filePathRange.Value2!=null)
                {
                    string filePath = filePathRange.Value2.ToString();
                    string shpName = shpNameRange.Value2.ToString();
                    Image image = listImageInfo.FirstOrDefault(s => s.ShapeName == shpName).ImageFile;
                    image.Save(filePath);
                }
            }


        }

在非PictureBox容器装载的图片,其实也可以用间接的方式实现,将普通的图片或图表等对形状对象,转换为Image类型的图片,并且可以保证到图片大小是最原始的图片。

原理是使用剪切板将图片复制到内存剪切板中,再由剪切板转换为图片,在复制过程中,我们需要考虑原始的图片在Excel上显示是已经缩放过的,需要将其放大为原始尺寸再复制。具体代码如下:

public static Image GetImageFromShape(Excel.Shape shp)
        {
            Excel.Shape shape = shp.Duplicate();
            shape.LockAspectRatio = Microsoft.Office.Core.MsoTriState.msoTrue;
            if (shp.Type.ToString() == "msoPicture")
            {
                shape.ScaleHeight(1, Microsoft.Office.Core.MsoTriState.msoTrue, Microsoft.Office.Core.MsoScaleFrom.msoScaleFromTopLeft);
            }
            else
            {
                shape.ScaleHeight(1, Microsoft.Office.Core.MsoTriState.msoFalse, Microsoft.Office.Core.MsoScaleFrom.msoScaleFromTopLeft);
            }
            shape.Copy();
            shape.Delete();

            Image returnImage = null;
            if (Clipboard.ContainsImage())
            {
                returnImage = Clipboard.GetImage();
            }
            return returnImage;

        }

核心代码中shape.ScaleHeight方法,可以将图片放大,特别是图形Shape类型时,可以按原始图来放大,其他的按实际显示的大小来放大。

同样地放大之前先锁定纵横比shape.LockAspectRatio,使用此属性。

结语

此篇再次让大家见识了VSTO开发较VBA开发的一大优势,有大量的.Net下的Winform技术可供使用,像剪切板对象,其就是System.Windows.Forms命名空间下的类。直接大量的现成方法简单调用,无需像VBA那般苦苦地挣扎着,调用各种古老方法或系统API等来扩展原生VBA对象的不足。

同时VSTO框架下,大量的特有功能,如PictureBox窗体宿主控件等可以大大地丰富了原生Excel的功能,也是VBA开发所不能享受到的好处。

继续阅读

更多来自我们博客的帖子

如何安装 BuddyPress
由 测试 December 17, 2023
经过差不多一年的开发,BuddyPress 这个基于 WordPress Mu 的 SNS 插件正式版终于发布了。BuddyPress...
阅读更多
Filter如何工作
由 测试 December 17, 2023
在 web.xml...
阅读更多
如何理解CGAffineTransform
由 测试 December 17, 2023
CGAffineTransform A structure for holding an affine transformation matrix. ...
阅读更多