您好,想问一下怎么嵌入图片到单元格
需要直接使用NPOI类库。
下面是AI的回复,可以参考:
在 NPOI 中插入图片并让它根据单元格大小自动缩放,一般思路是:
把图片读入 byte[]
byte[]
将图片添加到工作簿,拿到 pictureIndex
pictureIndex
在 Sheet 上创建一个 DrawingPatriarch
用 ClientAnchor 定位到目标单元格
创建 Picture
取出目标单元格的像素宽高,算出缩放比例
调用 picture.Resize(scaleX, scaleY)
picture.Resize(scaleX, scaleY)
下面给出一个针对 XSSF(.xlsx)和 HSSF(.xls)的示例代码,你可以根据自己用的格式稍作调整。
.xlsx
.xls
using NPOI.SS.UserModel; using NPOI.XSSF.UserModel; // 如果是 .xlsx using NPOI.HSSF.UserModel; // 如果是 .xls using NPOI.SS.Util; using NPOI.SS.usermodel; using System.IO; // ... // 1. 读图片 byte[] bytes = File.ReadAllBytes("logo.png"); // 2. 新建工作簿(XSSFWorkbook 或 HSSFWorkbook) IWorkbook workbook = new XSSFWorkbook(); // or new HSSFWorkbook(); // 3. 添加图片到工作簿,得到索引 int pictureIdx = workbook.AddPicture(bytes, PictureType.PNG); // 4. 取 Sheet、Row、Cell ISheet sheet = workbook.CreateSheet("Sheet1"); int rowIndex = 2, colIndex = 1; // 比如要放在 C3 (零基:row=2, col=1) IRow row = sheet.CreateRow(rowIndex); // 可先给行高、列宽设置好 row.HeightInPoints = 80; // 行高 80 磅 sheet.SetColumnWidth(colIndex, 30*256); // 列宽 30 字符 // 5. 创建绘图容器 IDrawing drawing = sheet.CreateDrawingPatriarch(); // 6. 定位:ClientAnchor(col1, row1, col2, row2, dx1, dy1, dx2, dy2) // 这里我们起始和结束都指定在同一个单元格(所以最后四个参数都用 0) IClientAnchor anchor; if (workbook is XSSFWorkbook) { anchor = new XSSFClientAnchor(0, 0, 0, 0, colIndex, rowIndex, colIndex+1, rowIndex+1); } else { anchor = new HSSFClientAnchor(0, 0, 0, 0, colIndex, rowIndex, colIndex+1, rowIndex+1); } // 7. 创建 Picture IPicture pict = drawing.CreatePicture(anchor, pictureIdx); // 8. 计算目标单元格的像素宽高 // 列宽:GetColumnWidth 单位是 1/256 个字符宽。转换为像素大致:pixels = width * 256 / 256 * 字符宽(px) // 经验值:Excel 默认一个字符约 7px,这里直接用 NPOI 提供方法更准确 float cellWidthPx = sheet.GetColumnWidthInPixels(colIndex); float cellHeightPx = row.HeightInPoints * (96f/72f); // 磅 -> 像素(假设 96 DPI) // 9. 取得图片本身像素(需要额外解析 image) using (var ms = new MemoryStream(bytes)) using (var img = System.Drawing.Image.FromStream(ms)) { float imgW = img.Width; float imgH = img.Height; // 取最小缩放比,保证图片完整显示且不超出单元格 float scaleX = cellWidthPx / imgW; float scaleY = cellHeightPx / imgH; float scale = Math.Min(scaleX, scaleY); // 10. 缩放 // XSSF 支持两个参数;HSSF 只有无参 Resize(),会按原图比例填充到锚指定的跨单元格区域 if (pict is XSSFClientAnchor) // 或者 workbook is XSSFWorkbook { ((XSSFPicture)pict).Resize(scale, scale); } else { // HSSF 只能自动填充整个单元格区域: pict.Resize(); } } // 11. 保存 using (var fs = new FileStream("output.xlsx", FileMode.Create, FileAccess.Write)) workbook.Write(fs);
AddPicture:将图片二进制加入到 IWorkbook 中,并返回一个索引,用于后续绘图。
AddPicture
IWorkbook
CreateDrawingPatriarch:在 Sheet 上创建绘图上下文,所有图形(图片、图表)都要走它。
CreateDrawingPatriarch
ClientAnchor:定义图片的起止单元格(col1,row1 -> col2,row2),也可以用偏移量控制更精细的位置。在这里只占一个单元格区域。
ClientAnchor
获取单元格像素尺寸:
列宽可以用 sheet.GetColumnWidthInPixels(colIndex)(NPOI 对于 XSSF/HSSF 都支持)。
sheet.GetColumnWidthInPixels(colIndex)
行高从 row.HeightInPoints 得到的是“磅”,再用 (96/72) 换算成像素(通常 Windows 显示 96 DPI)。
row.HeightInPoints
(96/72)
缩放比例:取宽高的最小缩放比,保证图片既不变形(按比例缩放),又能完整显示在单元格内。
Resize(scaleX, scaleY):只有 XSSF 支持两个参数的精确缩放。HSSF 里无参数 Resize() 会把图片按原比例尽量填满你锚定的单元格区域。
Resize(scaleX, scaleY)
Resize()
这样就能让图片“贴”在某个单元格里,并自动按照单元格的实际尺寸做等比缩放了。
谢谢,按你的那个子程序改好了