NPOI 在指定单元格导入导出图片

Intro

我维护了一个 NPOI 的扩展,主要用来导入导出 Excel 数据,最近有网友提出了导入 Excel 的时候解析图片的需求,于是就有了本文的探索

导入Excel 时解析图片

xlsxlsx 的 API 稍有不同,详细可以直接参考以下代码,实现代码如下:

public static Dictionary<CellPosition, IPictureData> GetPicturesAndPosition(this ISheet sheet)
{
var dictionary = new Dictionary<CellPosition, IPictureData>();
if (sheet.Workbook is HSSFWorkbook)
{
foreach (var shape in ((HSSFPatriarch)sheet.DrawingPatriarch).Children)
{
if (shape is HSSFPicture picture)
{
var position = new CellPosition(picture.ClientAnchor.Row1, picture.ClientAnchor.Col1);
dictionary[position] = picture.PictureData;
}
}
}
else if (sheet.Workbook is XSSFWorkbook)
{
foreach (var shape in ((XSSFDrawing)sheet.DrawingPatriarch).GetShapes())
{
if (shape is XSSFPicture picture)
{
var position = new CellPosition(picture.ClientAnchor.Row1, picture.ClientAnchor.Col1);
dictionary[position] = picture.PictureData;
}
}
}
return dictionary;
}

CellPosition 是一个自定义的结构体,表示当前单元格的位置,源码如下:

public readonly struct CellPosition : IEquatable<CellPosition>
{
public CellPosition(int row, int col)
{
Row = row;
Column = col;
} public int Row { get; }
public int Column { get; } public bool Equals(CellPosition other)
{
return Row == other.Row && Column == other.Column;
} public override bool Equals(object? obj) => obj is CellPosition other && Equals(other); public override int GetHashCode() => $"{Row}_{Column}".GetHashCode();
}

根据上面的代码,我们就可以获取到获取到所有的图片以及图片的所在位置,这样根据单元格位置去找图片信息的时候就会很方便了

导出 Excel 时设置图片

实现代码如下:

public static bool TryAddPicture(this ISheet sheet, int row, int col, byte[] pictureBytes, PictureType pictureType = PictureType.PNG)
{
if (sheet is null)
{
throw new ArgumentNullException(nameof(sheet));
} try
{
var pictureIndex = sheet.Workbook.AddPicture(pictureBytes, pictureType); var clientAnchor = sheet.Workbook.GetCreationHelper().CreateClientAnchor();
clientAnchor.Row1 = row;
clientAnchor.Col1 = col; var picture = (sheet.DrawingPatriarch ?? sheet.CreateDrawingPatriarch())
.CreatePicture(clientAnchor, pictureIndex);
picture.Resize();
return true;
}
catch (Exception e)
{
Debug.WriteLine(e);
} return false;
}

通过上面的代码我们就可以在指定的单元格设置图片,目前没有支持单元格合并操作,有需要自己进行修改

WeihanLi.Npoi

WeihanLi.Npoi1.15.0 版本中增加了图片导入导出的支持,使用示例可以参考下面的单元测试:

[Theory]
[ExcelFormatData]
public async Task ImageImportExportTest(ExcelFormat excelFormat)
{
using var httpClient = new HttpClient();
var imageBytes = await httpClient.GetByteArrayAsync("https://weihanli.xyz/assets/avator.jpg");
var list = Enumerable.Range(1, 5)
.Select(x => new ImageTest() { Id = x, Image = imageBytes })
.ToList();
var excelBytes = list.ToExcelBytes(excelFormat);
var importResult = ExcelHelper.ToEntityList<ImageTest>(excelBytes, excelFormat);
Assert.NotNull(importResult);
Assert.Equal(list.Count, importResult.Count);
for (var i = 0; i < list.Count; i++)
{
Assert.NotNull(importResult[i]);
var result = importResult[i]!;
Assert.Equal(list[i].Id, result.Id);
Assert.NotNull(result.Image);
Assert.True(list[i].Image.SequenceEqual(result.Image));
}
} private class ImageTest
{
public int Id { get; set; } public byte[] Image { get; set; } = null!;
}

导入时会自动将 byte[] 类型的属性尝试获取对应的单元格位置的图片,如果在对应的位置找到了图片就能够读取到图片的字节数组信息映射到 model 里的字节数组属性

More

感谢 @ZeguangZhang94 童鞋提出的需求和帮忙测试~

如果你也有类似的读取指定单元格的图片或者在指定单元格插入图片的需求,可以试一下上面的方法,希望对你有帮助

References

最新文章

  1. WCF全面解析学习(1)
  2. Oracle 11g RAC 卸载CRS步骤
  3. iOS 趣谈设计模式——通知
  4. wndows程序设计之书籍知识与代码摘录-获取视屏显示器像素等参数GetsystemMetrics
  5. D/A转换器
  6. Linux 基础入门(新版)”实验报告一~十二
  7. DNS原理及其解析过程【精彩剖析】(转)
  8. 批量安装操作系统之cobbler
  9. &lt;转&gt;DNS服务系列之二:DNS区域传送漏洞的安全案例
  10. Java中使用ThreadPoolExecutor并行执行独立的单线程任务
  11. 不要浪费人生的每一天 ——Dropbox创始人在麻省理工的演讲 z
  12. 【转】[总结]FFMPEG视音频编解码零基础学习方法
  13. 不用不知道 apply()与call()的强大
  14. Lake Counting(poj 2386)
  15. 控制 Memory 和 CPU 资源的使用
  16. 【LeetCode】191. Number of 1 Bits
  17. MySQL优化 - 所需了解的基础知识
  18. 一步一步设置Joomla!开发环境
  19. ASP.NET 性能监控工具和优化技巧
  20. [转帖]Nginx rewrite模块深入浅出详解

热门文章

  1. 2019牛客多校 Round2
  2. 二叉树增删改查 &amp;&amp; 程序实现
  3. C#线程Thread类
  4. .Net反编译实践记录
  5. 大数据开发-Spark-初识Spark-Graph &amp;&amp; 快速入门
  6. c# 类(4)
  7. 重学c#————struct
  8. angular-2-tutorial-2017
  9. 高级数据结构之 BloomFilter
  10. kahoot