我目前正在使用 OpenXML,并找到了一些有关如何将图像插入 Excel 文件的参考,但我想插入图像作为水印。我目前正在使用此代码,但这只是将图像附加到 Excel 文件。
static void AddImage(WorksheetPart worksheetPart, Stream imageStream, string imgDesc, int colNumber, int rowNumber)
{
MemoryStream imageMemStream = new MemoryStream();
imageStream.Position = 0;
imageStream.CopyTo(imageMemStream);
imageStream.Position = 0;
var drawingsPart = worksheetPart.DrawingsPart;
if (drawingsPart == null)
drawingsPart = worksheetPart.AddNewPart<DrawingsPart>();
if (!worksheetPart.Worksheet.ChildElements.OfType<Drawing>().Any())
worksheetPart.Worksheet.Append(new Drawing { Id = worksheetPart.GetIdOfPart(drawingsPart) });
if (drawingsPart.WorksheetDrawing == null)
drawingsPart.WorksheetDrawing = new Xdr.WorksheetDrawing();
var worksheetDrawing = drawingsPart.WorksheetDrawing;
Bitmap bm = new Bitmap(imageMemStream);
var imagePart = drawingsPart.AddImagePart(GetImagePartTypeByBitmap(bm));
imagePart.FeedData(imageStream);
A.Extents extents = new A.Extents();
var extentsCx = bm.Width * (long)(914400 / bm.HorizontalResolution);
var extentsCy = bm.Height * (long)(914400 / bm.VerticalResolution);
bm.Dispose();
var colOffset = 0;
var rowOffset = 0;
var nvps = worksheetDrawing.Descendants<Xdr.NonVisualDrawingProperties>();
var nvpId = nvps.Count() > 0 ? (UInt32Value)worksheetDrawing.Descendants<Xdr.NonVisualDrawingProperties>().Max(p => p.Id.Value) + 1 : 1U;
var oneCellAnchor = new Xdr.OneCellAnchor(
new Xdr.FromMarker
{
ColumnId = new Xdr.ColumnId((colNumber - 1).ToString()),
RowId = new Xdr.RowId((rowNumber - 1).ToString()),
ColumnOffset = new Xdr.ColumnOffset(colOffset.ToString()),
RowOffset = new Xdr.RowOffset(rowOffset.ToString())
},
new Xdr.Extent { Cx = extentsCx, Cy = extentsCy },
new Xdr.Picture(
new Xdr.NonVisualPictureProperties(
new Xdr.NonVisualDrawingProperties { Id = nvpId, Name = "Picture " + nvpId },
new Xdr.NonVisualPictureDrawingProperties(new A.PictureLocks { NoChangeAspect = true })
),
new Xdr.BlipFill(
new A.Blip { Embed = drawingsPart.GetIdOfPart(imagePart), CompressionState = A.BlipCompressionValues.Print },
new A.Stretch(new A.FillRectangle())
),
new Xdr.ShapeProperties(
new A.Transform2D(
new A.Offset { X = 0, Y = 0 },
new A.Extents { Cx = extentsCx, Cy = extentsCy }
),
new A.PresetGeometry { Preset = A.ShapeTypeValues.Rectangle }
)
),
new Xdr.ClientData()
);
worksheetDrawing.Append(oneCellAnchor);
}
我希望图像像 Excel 文件的水印一样。我想将图像放在文本后面。
using DocumentFormat.OpenXml;
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Spreadsheet;
using System.Drawing;
namespace ExcelHeaderGraphicsExample;
public class ExcelHeaderGraphicGenerator
{
// Creates a SpreadsheetDocument.
public void CreatePackage(string filePath)
{
using (SpreadsheetDocument package = SpreadsheetDocument.Create(filePath, SpreadsheetDocumentType.Workbook))
{
CreateParts(package);
}
}
// Adds child parts and generates content of the specified part.
private void CreateParts(SpreadsheetDocument document)
{
WorkbookPart workbookPart1 = document.AddWorkbookPart();
WorksheetPart worksheetPart1 = workbookPart1.AddNewPart<WorksheetPart>(null);
string workBookToSheetRelId = workbookPart1.GetIdOfPart(worksheetPart1);
GenerateWorkbookPart1Content(workbookPart1, workBookToSheetRelId);
VmlDrawingPart vmlDrawingPart1 = worksheetPart1.AddNewPart<VmlDrawingPart>(null);
GenerateVmlDrawingPart1Content(vmlDrawingPart1, workBookToSheetRelId);
string sheetToDrawingRelId = worksheetPart1.GetIdOfPart(vmlDrawingPart1);
ImagePart imagePart1 = vmlDrawingPart1.AddNewPart<ImagePart>("image/png", workBookToSheetRelId);
GenerateImagePart1Content(imagePart1);
GenerateWorksheetPart1Content(worksheetPart1, sheetToDrawingRelId);
}
private void GenerateWorkbookPart1Content(WorkbookPart workbookPart1, string relationshipId)
{
Workbook workbook1 = new Workbook() ;
workbook1.AddNamespaceDeclaration("r", "http://schemas.openxmlformats.org/officeDocument/2006/relationships");
workbook1.AddNamespaceDeclaration("mc", "http://schemas.openxmlformats.org/markup-compatibility/2006");
workbook1.AddNamespaceDeclaration("x15", "http://schemas.microsoft.com/office/spreadsheetml/2010/11/main");
workbook1.AddNamespaceDeclaration("xr", "http://schemas.microsoft.com/office/spreadsheetml/2014/revision");
workbook1.AddNamespaceDeclaration("xr6", "http://schemas.microsoft.com/office/spreadsheetml/2016/revision6");
workbook1.AddNamespaceDeclaration("xr10", "http://schemas.microsoft.com/office/spreadsheetml/2016/revision10");
workbook1.AddNamespaceDeclaration("xr2", "http://schemas.microsoft.com/office/spreadsheetml/2015/revision2");
Sheets sheets1 = new Sheets();
Sheet sheet1 = new Sheet() { Name = "Sheet1", SheetId = (UInt32Value)1U, Id = relationshipId };
sheets1.Append(sheet1);
workbook1.Append(sheets1);
workbookPart1.Workbook = workbook1;
}
// Generates content of worksheetPart1.
private void GenerateWorksheetPart1Content(WorksheetPart worksheetPart1, string imageDrawingRelId)
{
Worksheet worksheet = new Worksheet() ;
worksheet.AddNamespaceDeclaration("r", "http://schemas.openxmlformats.org/officeDocument/2006/relationships");
worksheet.AddNamespaceDeclaration("mc", "http://schemas.openxmlformats.org/markup-compatibility/2006");
worksheet.AddNamespaceDeclaration("x14ac", "http://schemas.microsoft.com/office/spreadsheetml/2009/9/ac");
worksheet.AddNamespaceDeclaration("xr", "http://schemas.microsoft.com/office/spreadsheetml/2014/revision");
worksheet.AddNamespaceDeclaration("xr2", "http://schemas.microsoft.com/office/spreadsheetml/2015/revision2");
worksheet.AddNamespaceDeclaration("xr3", "http://schemas.microsoft.com/office/spreadsheetml/2016/revision3");
worksheet.SetAttribute(new OpenXmlAttribute("xr", "uid", "http://schemas.microsoft.com/office/spreadsheetml/2014/revision", "{00000000-0001-0000-0000-000000000000}"));
SheetData sheetData1 = new SheetData();
HeaderFooter headerFooter1 = new HeaderFooter();
OddHeader oddHeader1 = new OddHeader();
oddHeader1.Text = "&R&G";
headerFooter1.Append(oddHeader1);
LegacyDrawingHeaderFooter legacyDrawingHeaderFooter1 = new LegacyDrawingHeaderFooter() { Id = imageDrawingRelId };
worksheet.Append(sheetData1);
worksheet.Append(headerFooter1);
worksheet.Append(legacyDrawingHeaderFooter1);
worksheetPart1.Worksheet = worksheet;
}
// Generates content of vmlDrawingPart1.
private void GenerateVmlDrawingPart1Content(VmlDrawingPart vmlDrawingPart1, string relationshipId)
{
System.Xml.XmlTextWriter writer = new System.Xml.XmlTextWriter(vmlDrawingPart1.GetStream(System.IO.FileMode.Create), System.Text.Encoding.UTF8);
string vmlText = string.Format("<xml xmlns:v=\"urn:schemas-microsoft-com:vml\"\r\n xmlns:o=\"urn:schemas-microsoft-com:office:office\"\r\n xmlns:x=\"urn:schemas-microsoft-com:office:excel\">\r\n <o:shapelayout v:ext=\"edit\">\r\n <o:idmap v:ext=\"edit\" data=\"1\"/>\r\n </o:shapelayout><v:shapetype id=\"_x0000_t75\" coordsize=\"21600,21600\" o:spt=\"75\"\r\n o:preferrelative=\"t\" path=\"m@4@5l@4@11@9@11@9@5xe\" filled=\"f\" stroked=\"f\">\r\n <v:stroke joinstyle=\"miter\"/>\r\n <v:formulas>\r\n <v:f eqn=\"if lineDrawn pixelLineWidth 0\"/>\r\n <v:f eqn=\"sum @0 1 0\"/>\r\n <v:f eqn=\"sum 0 0 @1\"/>\r\n <v:f eqn=\"prod @2 1 2\"/>\r\n <v:f eqn=\"prod @3 21600 pixelWidth\"/>\r\n <v:f eqn=\"prod @3 21600 pixelHeight\"/>\r\n <v:f eqn=\"sum @0 0 1\"/>\r\n <v:f eqn=\"prod @6 1 2\"/>\r\n <v:f eqn=\"prod @7 21600 pixelWidth\"/>\r\n <v:f eqn=\"sum @8 21600 0\"/>\r\n <v:f eqn=\"prod @7 21600 pixelHeight\"/>\r\n <v:f eqn=\"sum @10 21600 0\"/>\r\n </v:formulas>\r\n <v:path o:extrusionok=\"f\" gradientshapeok=\"t\" o:connecttype=\"rect\"/>\r\n <o:lock v:ext=\"edit\" aspectratio=\"t\"/>\r\n </v:shapetype><v:shape id=\"RH\" o:spid=\"_x0000_s1025\" type=\"#_x0000_t75\"\r\n style=\'position:absolute;margin-left:0;margin-top:0;width:154.5pt;height:40.5pt;\r\n z-index:1\'>\r\n <v:imagedata o:relid=\"{0}\" o:title=\"Logo\"/>\r\n <o:lock v:ext=\"edit\" rotation=\"t\"/>\r\n </v:shape></xml>", relationshipId); ;
writer.WriteRaw(vmlText);
writer.Flush();
writer.Close();
}
// Generates content of imagePart1.
private void GenerateImagePart1Content(ImagePart imagePart1)
{
var data = CreateRedBitmap();
imagePart1.FeedData(data);
data.Close();
}
// Update this to return your bitmap of choice
private static MemoryStream CreateRedBitmap()
{
Bitmap bmp = new Bitmap(8, 8);
for (int x = 0; x < bmp.Width; x++)
for (int y = 0; y < bmp.Height; y++)
{
bmp.SetPixel(x, y, System.Drawing.Color.Red);
}
MemoryStream ms = new MemoryStream();
bmp.Save(ms, System.Drawing.Imaging.ImageFormat.Png);
bmp.Dispose();
ms.Seek(0, SeekOrigin.Begin);
return ms;
}
}
我为此苦苦挣扎,所以这是一个有效的示例。
用途: 例如
var c = new ExcelHeaderGraphicGenerator();
c.CreatePackage(@"c:\temp\testWithHeader.xlsx");