使用Syncfusion XlsIO插入图片到Excel每行时重复显示同一图片
.NET 6控制台Syncfusion XlsIO插入图片重复问题
在.NET 6控制台应用中使用Syncfusion XlsIO向工作表每行末尾插入对应图片,生成文件后所有行显示的却是同一张图片。已调试确认循环中图片路径及对象均在变化,尝试过以下两段代码:
第一段尝试代码
int row = 1; foreach (DataRow dataRow in imgTable.Rows) { Console.WriteLine(dataRow.ToString()); string imagePath = $"./tempImages/{dataRow.ItemArray[1]}"; using (FileStream imageStream = new FileStream(imagePath, FileMode.Open, FileAccess.Read)) { IPictureShape shape = alarmWorksheet.Pictures.AddPicture(row, 4, imageStream); imgWorksheet.SetRowHeight(row, 288); } row++; }
第二段尝试代码
int row = 1; foreach (DataRow dataRow in imgTable.Rows) { alarmWorksheet.SetRowHeight(row, 216); Console.WriteLine(dataRow.ToString()); string imagePath = $"./tempImages/{dataRow.ItemArray[1]}"; using (FileStream imageStream = new FileStream(imagePath, FileMode.Open, FileAccess.Read)) { Image img = new Image(imageStream); imgWorksheet.Pictures.AddPicture(row, 4, img); } row++; }
问题排查与解决办法
首要排查点:工作表实例一致性
你的两段代码中都混用了alarmWorksheet和imgWorksheet两个变量——第一段用alarmWorksheet添加图片,却用imgWorksheet设置行高;第二段用alarmWorksheet设置行高,imgWorksheet添加图片。先确认这两个变量是否指向同一个工作表实例,如果不是,会导致你在错误的工作表操作,最终看到的重复图片可能是某一次的误操作结果。
核心问题:图片资源复用/流位置异常
Syncfusion XlsIO默认会对内容相同的图片做复用优化,如果图片内容不同却被识别为相同,大概率是流处理不当导致的。以下是几种修正方案:
方案1:直接通过文件路径添加图片(最稳妥)
绕开流处理的问题,直接传入图片路径给AddPicture方法:
int row = 1; foreach (DataRow dataRow in imgTable.Rows) { string imagePath = $"./tempImages/{dataRow.ItemArray[1]}"; // 确保操作的是正确的工作表实例 imgWorksheet.Pictures.AddPicture(row, 4, imagePath); imgWorksheet.SetRowHeight(row, 288); row++; }
方案2:重置流位置后再插入
如果必须用流加载图片,每次使用前务必将流的Position重置到起始位置,避免因流指针位置错误导致重复读取相同内容:
int row = 1; foreach (DataRow dataRow in imgTable.Rows) { string imagePath = $"./tempImages/{dataRow.ItemArray[1]}"; using (FileStream imageStream = new FileStream(imagePath, FileMode.Open, FileAccess.Read)) { // 重置流到起始位置 imageStream.Position = 0; imgWorksheet.Pictures.AddPicture(row, 4, imageStream); imgWorksheet.SetRowHeight(row, 288); } row++; }
方案3:正确创建并释放Image对象
第二段代码中直接new Image(imageStream)的方式存在资源未正确释放的问题,改用Image.FromStream并嵌套using块确保资源释放:
int row = 1; foreach (DataRow dataRow in imgTable.Rows) { imgWorksheet.SetRowHeight(row, 216); string imagePath = $"./tempImages/{dataRow.ItemArray[1]}"; using (FileStream imageStream = new FileStream(imagePath, FileMode.Open, FileAccess.Read)) using (Image img = Image.FromStream(imageStream, true, true)) { imgWorksheet.Pictures.AddPicture(row, 4, img); } row++; }
关键注意事项
- 确保所有操作针对同一个工作表实例,避免变量混用
- 优先使用文件路径插入图片,减少流处理的潜在问题
- 流操作必须重置位置,确保每次读取的是完整的图片内容
- 正确释放Image资源,避免对象被意外复用
内容的提问来源于stack exchange,提问作者psycho
相关产品推荐
相关产品推荐

