【问题标题】:How can I make an image used on multiple Excel spreadsheets always display at its full size (Aspose Cells)?如何使在多个 Excel 电子表格上使用的图像始终以完整尺寸显示(Aspose Cells)?
【发布时间】:2017-02-07 01:38:19
【问题描述】:

我正在使用以下代码在电子表格中放置图像:

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

因此,即使将 AutoFitter jazz 从 Aspose 代码中注释掉,图像仍然会在宽度上被挤压或在高度上被拉伸。

更新 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");

...但是得到了这个:

所以:又被压扁了。

更新 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;

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

更新 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 塞入一个微不足道的列中,如下所示:

...并在垂直方向上大量涂胶,因此看起来比暴风雨拖船上的润滑脂还要恶心。

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

// 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;
}

【问题讨论】:

    标签: excel image png aspose-cells


    【解决方案1】:

    请查看your thread in Aspose.Cells forum,它回答了您以下两个问题。

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

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

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

    【讨论】:

      【解决方案2】:

      只需注释掉花哨的自动装配代码即可:

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

      现在图像几乎以其实际大小均匀显示(但请注意下面的警告);有时会“溢出”,但如果他们抱怨这一点,我会创建第二张图片,并使用以下方法调整其大小:

      // 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 电子表格上的图像了。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-01-27
        • 2013-03-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多