如何用Open XML 2.7.2在已有docx中插入“Behind The Text”环绕的图片?
I totally get the frustration—older Open XML 2.5 code often breaks in newer versions due to stricter validation or updated element structures. The "content error" you’re seeing almost always comes from missing required wrapping properties or incorrectly structured drawing elements when setting an image to sit behind text.
Here’s a complete, tested C# example for Open XML 2.7.2 that inserts an image into an existing .docx and sets its wrapping to "Behind The Text":
First, ensure you have the DocumentFormat.OpenXml NuGet package (version 2.7.2) installed in your project.
using System.IO; using System.Collections.Generic; using DocumentFormat.OpenXml; using DocumentFormat.OpenXml.Packaging; using DocumentFormat.OpenXml.Wordprocessing; using DocumentFormat.OpenXml.Drawing; using DocumentFormat.OpenXml.Drawing.Wordprocessing; using DocumentFormat.OpenXml.Drawing.Pictures; public static void InsertImageBehindText(string docxPath, string imagePath, int insertParagraphIndex = 0) { // Open the existing document in edit mode using (var wordDoc = WordprocessingDocument.Open(docxPath, true)) { var mainPart = wordDoc.MainDocumentPart; // Add the image to the document's ImagePart (adjust type for JPEG/GIF/etc.) var imagePart = mainPart.AddImagePart(ImagePartType.Png); using (var imageStream = new FileStream(imagePath, FileMode.Open)) { imagePart.FeedData(imageStream); } // Get the unique ID to reference the image in the drawing element var imageId = mainPart.GetIdOfPart(imagePart); // Build the Drawing element with proper "Behind The Text" wrapping var floatingImageDrawing = new Drawing( new DW.Anchor( // Set initial position and size (EMUs: 1 inch = 914400 EMUs) new DW.SimplePosition { X = 0L, Y = 0L }, new DW.PositionH( new DW.HorizontalPositionRelativeToColumn()) { PositionOffset = 150000L }, new DW.PositionV( new DW.VerticalPositionRelativeToParagraph()) { PositionOffset = 150000L }, new DW.Extent { Cx = 1000000, Cy = 750000 }, new DW.EffectExtent { LeftEdge = 0L, TopEdge = 0L, RightEdge = 0L, BottomEdge = 0L }, // Required document properties for the image new DW.DocProperties { Id = (UInt32Value)1U, Name = "Inserted Image", Description = "Image placed behind text" }, new DW.NonVisualGraphicFrameDrawingProperties( new A.GraphicFrameLocks { NoChangeAspect = true }), // Core image content new A.Graphic( new A.GraphicData( new Pic.Picture( new Pic.NonVisualPictureProperties( new Pic.NonVisualDrawingProperties { Id = (UInt32Value)0U, Name = Path.GetFileName(imagePath) }, new Pic.NonVisualPictureDrawingProperties()), new Pic.BlipFill( new A.Blip { Embed = imageId, CompressionState = A.BlipCompressionValues.Print }, new A.Stretch(new A.FillRectangle())), new Pic.ShapeProperties( new A.Transform2D( new A.Offset { X = 0L, Y = 0L }, new A.Extents { Cx = 1000000, Cy = 750000 }), new A.PresetGeometry(new A.AdjustValueList()) { Preset = A.ShapeTypeValues.Rectangle })) { Uri = "http://schemas.openxmlformats.org/drawingml/2006/picture" }), // Critical: Set wrapping to "Behind The Text" new DW.WrapSquare { WrapText = DW.WrapTextValues.Behind } ) { AllowOverlap = true, DistanceFromTop = 0L, DistanceFromBottom = 0L, DistanceFromLeft = 0L, DistanceFromRight = 0L } ); // Insert the image into the target paragraph var paragraphs = mainPart.Document.Body.Elements<Paragraph>().ToList(); if (insertParagraphIndex >= paragraphs.Count) { // Add new paragraph if target index is out of range var newParagraph = new Paragraph(new Run(floatingImageDrawing)); mainPart.Document.Body.Append(newParagraph); } else { paragraphs[insertParagraphIndex].Append(new Run(floatingImageDrawing)); } // Save all changes mainPart.Document.Save(); } }
Key Fixes from Old 2.5 Code:
- Using
Anchorinstead ofInline: Floating images (like those behind text) require anAnchorelement—Inlineis only for images embedded directly in the text flow. - Explicit
WrapSquarewithWrapText = Behind: This tells Word to render the image behind the text, which is the exact setting you need. - Complete element hierarchy: Open XML 2.7.2 enforces strict validation, so all required child elements (like
DocPropertiesandGraphicFrameLocks) are included to avoid content errors.
How to Use:
Call the method like this to insert an image into the first paragraph of your document:
InsertImageBehindText(@"C:\YourExistingDoc.docx", @"C:\YourImage.png", 0);
Troubleshooting Tips:
- Adjust
Cx/Cyvalues (in EMUs) to resize the image to your needs. - If you still get errors, use Word’s "Open and Repair" feature on the output file—Word will often show a detailed message about which element is missing or invalid.
- Ensure your image file isn’t corrupted and the path is correct.
内容的提问来源于stack exchange,提问作者snvrthn

