隐藏

使用NPOI向Excel单元格中插入图片

发布:2023/3/24 22:28:58作者:管理员 来源:本站 浏览次数:687

使用NPOI向Excel单元格中插入图片


   目标

   代码

   参考文章


目标


需要向Excel中的某一列插入图片,每行的图片大小一致。

此方法仅适用于使用NPOI向xlsx文件中的指定单元格插入图片。

代码


以下示例将向Excel的第二行第一列写入文本信息,第二行第二列插入一张图片,并调整图片所在单元格大小与图片匹配。


using System;

using System.IO;

using NPOI.SS.UserModel;

using NPOI.XSSF.UserModel;


namespace ExcelImg

{

   class Program

   {

       static void Main(string[] args)

       {

           // Excel和图片放在程序根目录

           string exlPath = "TestExcel.xlsx";

           string newPath = "NewExcel.xlsx";

           string imgPath = "TestImg.jpg";

           // 图片宽高

           int imgWid = 477;

           int imgHgt = 266;


           // 打开Excel

           IWorkbook excel = default;

           ISheet sheet = default;

           using (FileStream fs = new FileStream(exlPath, FileMode.Open, FileAccess.Read))

           {

               excel = WorkbookFactory.Create(fs);

               // 获取第一个表格

               sheet = excel.GetSheetAt(0);

               // 获取第二行,第一行是标题

               IRow row = sheet.CreateRow(1);

               // 为第一列设置文本

               row.CreateCell(0).SetCellValue("测试标题");

               // 设置行高和列宽

               sheet.SetColumnWidth(1, imgWid * 32);   // Excel的宽将1个像素分为32份

               row.Height = (short)(imgHgt * 16);      // Excel的高将1个像素分为16份


               // 添加图片

               // 1.以字节数组的形式读取图片

               byte[] buffer = GetImageBuffer(imgPath);

               // 2.向Excel添加图片,获取到图片索引

               int picIdx = excel.AddPicture(buffer, PictureType.JPEG);

               // 3.构建Excel图像

               var drawing = sheet.CreateDrawingPatriarch();

               // 4.确定图像的位置

               // new XSSFClientAnchor(int dx1, int dy1, int dx2, int dy2, int col1, int row1, int col2, int row2)

               // 前四个参数是单元格内的偏移量,这里需要填满整个单元格所以不设置。

               // col1,row1表示图片的左上角在哪个单元格的左上角;col2,row2表示图片的右下角在哪个单元格的左上角

               XSSFClientAnchor anchor = new XSSFClientAnchor(0, 0, 0, 0, 1, 1, 2, 2);

               // 5.将图片设置到上面的位置中

               drawing.CreatePicture(anchor, picIdx);

           }

           using (FileStream newFile = new FileStream(newPath, FileMode.Create, FileAccess.Write))

           {

               excel.Write(newFile);

           }

           excel?.Close();

       }


       private static byte[] GetImageBuffer(string path)

       {

           return File.ReadAllBytes(path);

       }

   }

}


 


运行效果如下图所示

在此记录注意点


   NPOI的行高将1个像素分为16份,即设置值应该等于图片像素高*16

   NPOI的列宽将1个像素分为32分,即设置值应该等于图片像素宽*32

   确定图像位置时


   XSSFClientAnchor(int dx1, int dy1, int dx2, int dy2, int col1, int row1, int col2, int row2)


前四个参数是单元格内的偏移量:

dx1、dy1是图片的左上角在起始单元格中的偏移。dx2、dy2是图片的右下角在结束单元格中的偏移。详情可参考以下文章

HSSFClientAnchor 参数说明

后四个参数是设置图片的起始单元格和结束单元格:

因为我需要在一个单元格中显示图片,所以图片的起始单元格和结束单元格这里只跨越了一个单元格。


   若需要写入大量图片时可以采用分批次写入,例如每次写入50张图片保存后重新打开继续写入,以保证中途关闭时仍能保留部分数据。


参考文章


HSSFClientAnchor 参数说明

XSSFClientAnchor Dx,Dy参数无效

XSSFClientAnchor文档