如何使用 OpenXML 在 Excel 中插入标题图像?

问题描述 投票:0回答:1

我目前正在使用 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 文件的水印一样。我想将图像放在文本后面。

c# excel openxml
1个回答
0
投票
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");
© www.soinside.com 2019 - 2024. All rights reserved.