在 Azure 中运行的 EPPlus 会产生“GDI+ 中发生一般错误”

本文关键字:GDI+ 错误 运行 Azure EPPlus | 更新日期: 2023-09-27 18:30:16

我正在使用一个控制台应用程序/WebJob,它利用EPPlus库来处理Excel文件(.xlsx)。我的应用程序基本上打开一组工作簿并将它们合并为一个文件。

应用程序在本地运行良好,但在 Azure 中运行不正常。根据StackTrace,尝试保存图像时,错误发生在EEPlus库中(我假设这样做是为了将图像从一个工作簿移动到另一个工作簿)。

Unhandled Exception: System.ApplicationException: A generic error occurred in GDI+.
---> System.Runtime.InteropServices.ExternalException: A generic error occurred in GDI+.
at System.Drawing.Image.Save(Stream stream, ImageCodecInfo encoder, EncoderParameters encoderParams)
at System.Drawing.Image.Save(Stream stream, ImageFormat format)
at OfficeOpenXml.Drawing.ExcelPicture..ctor(ExcelDrawings drawings, XmlNode node)
at OfficeOpenXml.Drawing.ExcelDrawing.GetDrawing(ExcelDrawings drawings, XmlNode node)
at OfficeOpenXml.Drawing.ExcelDrawings.AddDrawings()
at OfficeOpenXml.Drawing.ExcelDrawings..ctor(ExcelPackage xlPackage, ExcelWorksheet sheet)
at OfficeOpenXml.ExcelWorksheets.Add(String Name, ExcelWorksheet Copy)

原始代码,它产生错误打开调用ConvertTo

Part = drawings.Part.Package.GetPart(UriPic);
FileInfo f = new FileInfo(UriPic.OriginalString);
ContentType = GetContentType(f.Extension);
_image = Image.FromStream(Part.GetStream());
ImageConverter ic=new ImageConverter();
var iby=(byte[])ic.ConvertTo(_image, typeof(byte[]));
var ii = _drawings._package.LoadImage(iby, UriPic, Part);
ImageHash = ii.Hash;

在阅读了有关此事的几个问题后,我尝试使用手动转换对其进行修改并保存到MemoryStream。但是我仍然收到错误。

Part = drawings.Part.Package.GetPart(UriPic);
FileInfo f = new FileInfo(UriPic.OriginalString);
ContentType = GetContentType(f.Extension);
_image = Image.FromStream(Part.GetStream());
byte[] iby;
using (MemoryStream ms = new MemoryStream())
{
    _image.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);
    iby = ms.ToArray();                
}
var ii = _drawings._package.LoadImage(iby, UriPic, Part);
ImageHash = ii.Hash;

我真的被困在下一步该尝试什么上。这个例外并没有产生那么多东西可以继续,我觉得我已经尝试了所有的建议:检查文件夹和文件权限(我的应用程序使用临时文件夹,我认为这是安全的),避免重复使用流等等。

如果您需要任何其他信息,请告诉我,我很乐意提出来。

在 Azure 中运行的 EPPlus 会产生“GDI+ 中发生一般错误”

使用当前版本的 EPPlus 无法做到这一点,因为内部依赖于 System.Drawing 库。

有关该主题的官方帖子,请参阅此处:https://github.com/JanKallman/EPPlus/issues/427

这里有一些其他有趣的阅读:https://photosauce.net/blog/post/5-reasons-you-should-stop-using-systemdrawing-from-aspnet

似乎唯一的方法是确定 EPP 中依赖于 System.Drawing 的功能并解决它们。或者调整 EPP 以对图形使用不同的库。

这可能是您开始确定可以避免的部分的良好开端:https://github.com/JanKallman/EPPlus/search?q=%22using+system.drawing%3B%22&unscoped_q=%22using+system.drawing%3B%22

我通常以这种方式使用 EPPlus:

  1. 获取模板.xlsx我之前已格式化
  2. 向其添加数据(使用 C# 和 EPPlus)
  3. 将新的 xlsx 返回给用户

我最近遇到了同样的错误:

GDI+ 中发生一般错误

如何解决:

我的模板.xlsx使用的是Excel的相机工具:也就是说,其中一个工作表中有一个快照,该快照正在粘贴到另一个工作表中。

这在本地(在我的计算机中)工作正常,但在 Azure 中则不行......我不知道为什么。

但是如果我删除快照,它可以工作