如何使多个Excel电子表格中使用的图像始终以其完整大小显示(Aspose Cells)?

时间:2017-02-02 17:25:56

标签: excel image png aspose-cells

我使用以下代码将图片放在电子表格中:

var ms = new MemoryStream();
Image _logo = RoboReporterConstsAndUtils.GetURLImage("http://www.proactusa.com/bla/pa_logo_notag.png");
_logo.Save(ms, ImageFormat.Png);
ms.Position = 0;
locationWorksheet.Pictures.Add(0, 4, ms);
AutoFitterOptions options = new AutoFitterOptions { OnlyAuto = true };
locationWorksheet.AutoFitRows(options);

工作正常;但是,我在两个不同的报告上使用相同的代码,图像显示不同的大小。其中一个高度为0.85英寸(63%),宽度为1.1英寸(53%),而另一个高度为1.44英寸(106%),宽度为2.07英寸(100%)。

为什么它们的大小不同?为什么它们不是原始图像尺寸的100%?

其他代码似乎完全相同(尽管在这种情况下,图像显示的列是动态的)是:

var ms = new MemoryStream();
Image _logo = RoboReporterConstsAndUtils.GetURLImage("http://www.proactusa.com/bla/pa_logo_notag.png");
_logo.Save(ms, ImageFormat.Png);
ms.Position = 0;
pivotTableSheet.Pictures.Add(0, _grandTotalsColumnPivotTable - 1, ms);
AutoFitterOptions options = new AutoFitterOptions { OnlyAuto = true };
pivotTableSheet.AutoFitRows(options);

图像本身位于参考位置,高度为1.35“,宽度为2.07”

调用的方法是:

internal static Image GetURLImage(string url)
{
    WebClient wc = new WebClient();
    byte[] bytes = wc.DownloadData(url);
    MemoryStream ms = new MemoryStream(bytes);
    return Image.FromStream(ms);
}

如何让图像始终以100%或至少以给定尺寸显示?

更新

我也(至少目前)在同一个项目中使用EPPlus生成的一些报告。在这些中,我有以下代码,它允许我设置图像的确切大小:

private void AddImage(ExcelWorksheet oSheet, int rowIndex, int colIndex)
{
    Image _logo = RoboReporterConstsAndUtils.GetURLImage("http://www.proactusa.com/bla/pa_logo_notag.png");
    var excelImage = oSheet.Drawings.AddPicture("PRO*ACT Logo", _logo);
    excelImage.From.Column = colIndex - 1;
    excelImage.From.Row = rowIndex - 1;
    excelImage.SetSize(199, 130);  // 199WX130H is the actual size of the image
    excelImage.From.ColumnOff = Pixel2MTU(2);
    excelImage.From.RowOff = Pixel2MTU(2);
}

......这样称呼:

AddImage(deliveryPerformanceWorksheet, UNIT_ROW, LOGO_FIRST_COLUMN);

...但是这不会在Aspose代码中出现,因为工作表是不同类型的 - Aspose.Cells.Worksheet而不是ExcelWorksheet,因此代码:

AddImage(locationWorksheet, 0, 4);

...不会在Aspose报告中编译。我希望我可以暂时将Aspose.Cells.Worksheet转换为ExcelWorksheet,如下所示:

ExcelWorksheet ews = locationWorksheet; // naive attempt to magically morph an Aspose.Cells.Worksheet to an ExcelWorksheet
AddImage(ews, 0, 4);

...所以我可以调用AddImage(),但是这种公然的尝试是由编译器吹口哨的推文停止,“无法将类型'Aspose.Cells.Worksheet'隐式转换为'OfficeOpenXml.ExcelWorksheet'

更新2

图像是预期的大小;这段代码:

int h = _logo.Height; //130, as expected
int w = _logo.Width; //199, " "

...显示图像是原始大小。问题可能是AutoFitterOptions设置吗? OnlyAuto是否允许拉伸/挤压图像,具体取决于图像的大小?

更新3

在EPPlus中,我可以使用以下代码以完全相同的尺寸显示图像:

private void AddImage(ExcelWorksheet oSheet, int rowIndex, int colIndex) 
{
    Image _logo = RoboReporterConstsAndUtils.GetURLImage("http://www.proactusa.com/bla/pa_logo_notag.png");
    var excelImage = oSheet.Drawings.AddPicture("PRO*ACT Logo", _logo);
    excelImage.From.Column = colIndex - 2;
    excelImage.From.Row = rowIndex - 1;
    excelImage.SetSize(199, 130);
    excelImage.From.ColumnOff = Pixel2MTU(2);
    excelImage.From.RowOff = Pixel2MTU(2);
}

...但是在Aspose我只能靠近使用:

var ms = new MemoryStream();
Image _logo = RoboReporterConstsAndUtils.GetURLImage("http://www.proactusa.com/bla/pa_logo_notag.png");
_logo.Save(ms, ImageFormat.Png);
ms.Position = 0;
pivotTableSheet.Pictures.Add(0, _grandTotalsColumnPivotTable - 1, ms);

EPPlus代码也保留了高/宽比:

原始图像宽199像素,高130像素。

EPPlus-plopped图像为1.33 X 2.05,因此保留1.5:1(近似值)的比例。

但是,Aspose-plopped图像是1.63和1.67 X 2.07,因此比率更像是1.25:1

因此,即使使用Aspose代码注释掉AutoFitter爵士乐,图像仍然会被压扁或拉伸高度。

更新4

基于线程here,我尝试了这个(将图像复制到我的bin文件夹):

int index = locationWorksheet.Pictures.Add(0, 4, 6, 5, "LogoFromSite.png");
Picture pic = locationWorksheet.Pictures[index];
pic.Placement = PlacementType.FreeFloating;

[sheet] .Pictures.Add()的前四个参数是左上行,左上列,右下行和右下列。

但是,这会将页面上的图像放在正确的位置,然后将其移到左侧的几列(!?!)

更新5

我找到了另一条希望之光here,并尝试了这段代码:

Aspose.Cells.Rendering.ImageOrPrintOptions opts = new Aspose.Cells.Rendering.ImageOrPrintOptions();
opts.OnePagePerSheet = true;
opts.ImageFormat = ImageFormat.Png;
opts.SetDesiredSize(199, 130);

Aspose.Cells.Rendering.SheetRender sr = new Aspose.Cells.Rendering.SheetRender(locationWorksheet, opts);
sr.ToImage(0, "LogoFromSite.png");

......但得到了这个:

enter image description here

所以:再次被压扁。

更新6

我尝试了Aspose Cells猫自己提供的一些代码,但他们承认它存在问题,并且正在研究它。只是为了笑容,我试了一下,看看会发生什么。这段代码:

byte[] bts1 = File.ReadAllBytes("LogoFromSite.png");
byte[] bts2 = File.ReadAllBytes("LogoFromSite.png");

MemoryStream ms1 = new MemoryStream();
ms1.Write(bts1, 0, bts1.Length);
ms1.Position = 0;

//This is for second picture in sheet2
MemoryStream ms2 = new MemoryStream();
ms2.Write(bts2, 0, bts2.Length);
ms2.Position = 0;

//Add picture in first worksheet
int idx = locationWorksheet.Pictures.Add(0, 4, ms1);

//Add picture in second worksheet with original size
idx = locationWorksheet.Pictures.Add(0, 10, ms2);
Picture pic = locationWorksheet.Pictures[idx];
pic.HeightScale = 100;
pic.WidthScale = 100;

......导致这些“无图像图像”:

enter image description here

更新7

我又做了一次冒险;当高度增加到100%以上时,我想我会将图像调整为另一个,并使用它:

var ms = new MemoryStream();
Image _logo = GetURLImage("http://www.proactusa.com/bla/pa_logo_notag.png");

double newHeightDbl = _logo.Height * 0.8;
int newHeightInt = (int)Math.Ceiling(newHeightDbl);
Image resizedImage = ResizeImage(_logo, newHeightInt, _logo.Width);

resizedImage.Save(ms, ImageFormat.Png);
ms.Position = 0;
locationWorksheet.Pictures.Add(0, 4, ms);

......但不是!它将整个shebang填充到一个可疑的列中,如下所示:

enter image description here

...并且垂直地对它进行gumbified,从而使它看起来比在暴风骤雨的拖船上看起来更加笨拙。

以下是调整图像大小的(被盗/借用)代码:

// from http://stackoverflow.com/questions/1922040/resize-an-image-c-sharp
public static Bitmap ResizeImage(Image image, int width, int height)
{
    var destRect = new Rectangle(0, 0, width, height);
    var destImage = new Bitmap(width, height);

    destImage.SetResolution(image.HorizontalResolution, image.VerticalResolution);

    using (var graphics = Graphics.FromImage(destImage))
    {
        graphics.CompositingMode = CompositingMode.SourceCopy;
        graphics.CompositingQuality = CompositingQuality.HighQuality;
        graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
        graphics.SmoothingMode = SmoothingMode.HighQuality;
        graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;

        using (var wrapMode = new ImageAttributes())
        {
            wrapMode.SetWrapMode(WrapMode.TileFlipXY);
            graphics.DrawImage(image, destRect, 0, 0, image.Width, image.Height, GraphicsUnit.Pixel, wrapMode);
        }
    }

    return destImage;
}

2 个答案:

答案 0 :(得分:1)

只需评论花式裤子自动调整代码:

//AutoFitterOptions options = new AutoFitterOptions { OnlyAuto = true };
//pivotTableSheet.AutoFitRows(options);

现在图像几乎以其实际尺寸均匀显示(但请注意下面的警告);一个scosh" spilly"有时,但如果他们抱怨,我会创建第二张图片,并使用它来调整大小:

// from http://stackoverflow.com/questions/1922040/resize-an-image-c-sharp
public static Bitmap ResizeImage(Image image, int width, int height)
{
    var destRect = new Rectangle(0, 0, width, height);
    var destImage = new Bitmap(width, height);

    destImage.SetResolution(image.HorizontalResolution, image.VerticalResolution);

    using (var graphics = Graphics.FromImage(destImage))
    {
        graphics.CompositingMode = CompositingMode.SourceCopy;
        graphics.CompositingQuality = CompositingQuality.HighQuality;
        graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
        graphics.SmoothingMode = SmoothingMode.HighQuality;
        graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;

        using (var wrapMode = new ImageAttributes())
        {
            wrapMode.SetWrapMode(WrapMode.TileFlipXY);
            graphics.DrawImage(image, destRect, 0, 0, image.Width, image.Height, GraphicsUnit.Pixel, wrapMode);
        }
    }

    return destImage;
}

警告:这很好用,我不情愿地接受它,但放在纸张上的图像不是完全相同的大小。一个是1.67" X 2.07",另一个是1.63" X 2.07" - 我想,它足够接近马蹄铁,手榴弹和Excel电子表格上的图像。

答案 1 :(得分:1)

请检查your thread in Aspose.Cells forum,它会回答您的两个问题。

1 - 我们可以在工作簿和工作表中重用包含图片的相同内存流对象吗?

2 - 如何添加原始尺寸的图片?

注意: 我在Aspose担任开发人员传播者