最近有个功能,是在excel上导出时添加图片上去,总共有1300条数据,可能每条数据有3个图片所有,然后结果就异常了,出现Fail to save: an error occurs while saving the package : 引发类型为“System.OutOfMemoryException”的异常。
,然后对代码猜测可能是MemoryStream导致的,下载打方式是将OBS上的文件以流的形势导出的,请问这种问题该怎么处理
if (!string.IsNullOrEmpty(rowValue))
{
string[] imagPaths = rowValue.Split(',');
c.Row.Height = 800;
//sheet1.SetColumnWidth(j, 2000);
XSSFDrawing patriarch = (XSSFDrawing)sheet1.CreateDrawingPatriarch();
int num = 0;
foreach (var imgPath in imagPaths)
{
var fileStream =obs.DownloadFile(imgPath);
if (fileStream == null)
{
continue;
}
int pictureIdx = workbook.AddPicture(StreamToMemoryStream(fileStream), NPOI.SS.UserModel.PictureType.JPEG); //添加图片
// XSSFDrawing patriarch = (XSSFDrawing)sheet1.CreateDrawingPatriarch();
XSSFClientAnchor anchor = new XSSFClientAnchor(0, 0, 0, 0, j, i + 1, j + 1, i + 2);
XSSFPicture pict = (XSSFPicture)patriarch.CreatePicture(anchor, pictureIdx);
}
public byte[] StreamToMemoryStream(Stream stream)
{
byte[] streamBytes;
using (MemoryStream ms = new MemoryStream())
{
int count = 0;
do
{
byte[] buf = new byte[1024];
count = stream.Read(buf, 0, 1024);
ms.Write(buf, 0, count);
} while (stream.CanRead && count > 0);
streamBytes = ms.ToArray();
}
return streamBytes;
}
可能刚才的有误,最新调试是发现 workbook.Write(stream)这里导致的异常
/// <summary>
/// 保存workbook到字节流中,上面那个方法导出的文件打不开
/// </summary>
/// <returns></returns>
public byte[] SaveWorkbookToAarryByte()
{
NpoiMemoryStream stream = new NpoiMemoryStream();
stream.AllowClose = false;
// Set the position to the beginning of the stream.
//这句代码非常重要,如果不加,会报:打开的EXCEL格式与扩展名指定的格式不一致
//stream.Seek(0, SeekOrigin.Begin);
workbook.Write(stream);
stream.Flush();
stream.Seek(0, SeekOrigin.Begin);
stream.AllowClose = true;
byte[] byteArray = stream.ToArray();
return byteArray;
}
需求不合理,打回重新设计。
这样大的数据量(且放图片——原图?缩略图?)
excel 不是干啥都行的。
也有 能力天花板吧。
这个 工具 看看
语言是.net的,客户要求必须添加图片
资源不足,内存不够,,找用户增加预算——购买更大内存的计算机。
或者你自己 调一下 .net 的内存?
不懂 .net,请继续研究吧,,好了出个博文哦
你的fileStream
有没有释放?
虽说读取分块了,但是写入到excel里,是实打实的byte[]全在内存里, 3 * fileSize * 1300 也是可能撑爆的
可以试试SXSSFWorkbook
很抱歉,我之前误解了你的请求。以下是你提供的代码的中文翻译:
csharp
Copy code
// 省略部分代码...
// 下面是用于保存workbook到字节数组的方法
// 注意:上面的方法导出的文件打不开,可能会出现OutOfMemoryException
public byte[] SaveWorkbookToAarryByte()
{
NpoiMemoryStream stream = new NpoiMemoryStream();
stream.AllowClose = false;
// 设置流的位置到开头
// 这句代码非常重要,如果不加,可能会导致“打开的EXCEL格式与扩展名指定的格式不一致”错误
// stream.Seek(0, SeekOrigin.Begin);
workbook.Write(stream);
stream.Flush();
stream.Seek(0, SeekOrigin.Begin);
stream.AllowClose = true;
byte[] byteArray = stream.ToArray();
return byteArray;
}
以上代码是一个用于保存workbook(Excel文档)到字节数组的方法。它使用了一个自定义的NpoiMemoryStream类来处理流操作。需要注意的是,在导出的过程中可能会出现OutOfMemoryException异常,这很可能是因为之前的代码中出现了内存泄漏,导致了内存消耗过多。
为了解决这个问题,建议在使用MemoryStream时,使用using语句来确保资源能够正确释放,避免出现内存泄漏问题。同时,确保在使用完相关资源后,及时进行资源的释放和关闭。