我正在使用 OpenXml(版本 3.0.1)在单元格中插入图像。虽然代码运行时没有任何错误,但当我导出 Excel 文件并打开它时,我收到一条错误消息,并且图像没有出现在预期的单元格 (A2) 中。
我提到了这个 msdn-code-gallery 但该代码似乎不起作用,或者可能在最新版本的 OpenXml 中已过时。
这是我的代码
using PIC = DocumentFormat.OpenXml.Drawing.Pictures;
using A = DocumentFormat.OpenXml.Drawing;
public byte[] AddImageToExcel(SheetExport sheetExport)
{
using var memoryStream = new MemoryStream();
var spreadSheetDocument = SpreadsheetDocument.Create(memoryStream, SpreadsheetDocumentType.Workbook);
var workbookPart = spreadSheetDocument.AddWorkbookPart();
workbookPart.Workbook = new Workbook();
// Add a WorksheetPart to the WorkbookPart.
WorksheetPart worksheetPart = workbookPart.AddNewPart<WorksheetPart>();
worksheetPart.Worksheet = new Worksheet(new SheetData());
Sheets sheets = workbookPart.Workbook.AppendChild(new Sheets());
var sheetToAppend = new Sheet()
{ Name = sheetExport.SheetName, SheetId = 1, Id = workbookPart.GetIdOfPart(worksheetPart) };
sheets.Append(sheetToAppend);
// Adding image to the worksheet
InsertImageInCell(worksheetPart);
workbookPart.Workbook.Save();
spreadSheetDocument.Dispose();
return memoryStream.ToArray();
}
private (long Width, long Height) GetImageExtents(string imagePath)
{
using System.Drawing.Image image = System.Drawing.Image.FromFile(imagePath);
long width = (long)((image.Width / image.HorizontalResolution) * 914400L);
long height = (long)((image.Height / image.VerticalResolution) * 914400L);
return (width, height);
}
private void InsertImageInCell(WorksheetPart worksheetPart)
{
DrawingsPart drawingsPart;
if (worksheetPart.DrawingsPart == null)
{
drawingsPart = worksheetPart.AddNewPart<DrawingsPart>();
worksheetPart.Worksheet.Append(new Drawing { Id = worksheetPart.GetIdOfPart(drawingsPart) });
worksheetPart.Worksheet.Save();
}
else
{
drawingsPart = worksheetPart.DrawingsPart;
}
var imagePath = Path.Combine(Directory.GetCurrentDirectory(), "Resources", "Banner.png");
var imageExtents = GetImageExtents(imagePath);
// Add the image
ImagePart imagePart = drawingsPart.AddImagePart(ImagePartType.Png);
using (var imageFileStream = new FileStream(imagePath, FileMode.Open, FileAccess.Read))
{
imagePart.FeedData(imageFileStream);
}
// Create the drawing elements
var nvdp = new PIC.NonVisualDrawingProperties()
{
Id = (UInt32Value)1025U,
Name = "Picture 1"
};
var nvpd = new PIC.NonVisualPictureDrawingProperties(new A.PictureLocks() { NoChangeAspect = true });
var nvpp = new PIC.NonVisualPictureProperties()
{
NonVisualDrawingProperties = nvdp,
NonVisualPictureDrawingProperties = nvpd
};
var blip = new A.Blip()
{
Embed = drawingsPart.GetIdOfPart(imagePart),
CompressionState = A.BlipCompressionValues.Print
};
var blipFill = new PIC.BlipFill()
{
Blip = blip,
SourceRectangle = new A.SourceRectangle()
};
blipFill.Append(new A.Stretch() { FillRectangle = new A.FillRectangle() });
var sp = new PIC.ShapeProperties()
{
BlackWhiteMode = A.BlackWhiteModeValues.Auto
};
var transform2D = new A.Transform2D();
var offset = new A.Offset() { X = 0L, Y = 0L };
var extents = new A.Extents() { Cx = imageExtents.Width, Cy = imageExtents.Height };
transform2D.Append(offset);
transform2D.Append(extents);
sp.Append(transform2D);
sp.Append(new A.PresetGeometry(new A.AdjustValueList())
{
Preset = A.ShapeTypeValues.Rectangle
});
var picture = new PIC.Picture()
{
NonVisualPictureProperties = nvpp,
BlipFill = blipFill,
ShapeProperties = sp
};
var position = new Position() { X = 0L, Y = 0L };
var extent = new Extent() { Cx = imageExtents.Width, Cy = imageExtents.Height };
var absoluteAnchor = new AbsoluteAnchor()
{
Position = position,
Extent = extent
};
absoluteAnchor.Append(picture);
absoluteAnchor.Append(new ClientData());
WorksheetDrawing worksheetDrawing = drawingsPart.WorksheetDrawing;
if (worksheetDrawing == null)
{
worksheetDrawing = new WorksheetDrawing();
drawingsPart.WorksheetDrawing = worksheetDrawing;
}
worksheetDrawing.Append(absoluteAnchor);
drawingsPart.WorksheetDrawing.Save();
}
drawingPart.WorkSheetDrawing
的内部xml
<xdr:absoluteAnchor
xmlns:xdr="http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing">
<xdr:pos x="0" y="0" />
<xdr:ext cx="1781423" cy="628737" />
<pic:pic
xmlns:pic="http://schemas.openxmlformats.org/drawingml/2006/picture">
<pic:nvPicPr>
<pic:cNvPr id="1025" name="Picture 1" />
<pic:cNvPicPr>
<a:picLocks noChangeAspect="1"
xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main" />
</pic:cNvPicPr>
</pic:nvPicPr>
<pic:blipFill>
<a:blip r:embed="R3a1e7131d49045f5" cstate="print"
xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships"
xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main" />
<a:srcRect
xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main" />
<a:stretch
xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main">
<a:fillRect />
</a:stretch>
</pic:blipFill>
<pic:spPr bwMode="auto">
<a:xfrm
xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main">
<a:off x="0" y="0" />
<a:ext cx="1781423" cy="628737" />
</a:xfrm>
<a:prstGeom prst="rect"
xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main">
<a:avLst />
</a:prstGeom>
</pic:spPr>
</pic:pic>
<xdr:clientData />
</xdr:absoluteAnchor>
我无法使用任何其他第三方,如 EPPlus 或 ClosedXml,它必须通过 OpenXml 完成。
您使用
using PIC = DocumentFormat.OpenXml.Drawing.Pictures;
例如:
var nvdp = new PIC.NonVisualDrawingProperties()
一定是var nvpp = new DocumentFormat.OpenXml.Drawing.Spreadsheet.NonVisualPictureProperties()
检查您在哪里使用 PIC 并使用
DocumentFormat.OpenXml.Drawing.Spreadsheet