如何用OpenXML在C#中设置图片内容控件内图片浮于文字上方?
解决方案:C#中用OpenXML将图片插入图片内容控件并设置浮于文字上方
要实现将图片插入图片内容控件并设置浮于文字上方的效果,核心是用Anchor元素替代默认的Inline元素来定义图片布局(Inline对应嵌入型)。以下是完整实现代码和关键说明:
必要命名空间
确保引用以下OpenXML相关命名空间:
using DocumentFormat.OpenXml; using DocumentFormat.OpenXml.Packaging; using DocumentFormat.OpenXml.Wordprocessing; using DocumentFormat.OpenXml.Drawing; using DocumentFormat.OpenXml.Drawing.Wordprocessing; using System.IO;
实现代码
public static void InsertFloatingImageIntoPictureControl(string docPath, string imagePath, string controlTag) { using (WordprocessingDocument wordDoc = WordprocessingDocument.Open(docPath, true)) { MainDocumentPart mainPart = wordDoc.MainDocumentPart; // 查找指定Tag的图片内容控件(块级控件对应SdtBlock) SdtBlock pictureControl = mainPart.Document.Body.Descendants<SdtBlock>() .FirstOrDefault(sdt => sdt.SdtProperties.Descendants<Tag>().Any(tag => tag.Val == controlTag)); if (pictureControl == null) { throw new InvalidOperationException("未找到指定Tag的图片内容控件"); } // 清空控件原有内容 pictureControl.SdtContentBlock.RemoveAllChildren(); // 添加图片到文档的ImagePart ImagePart imagePart = mainPart.AddImagePart(ImagePartType.Png); // 根据图片类型调整(如Jpeg、Gif) using (FileStream fs = new FileStream(imagePath, FileMode.Open)) { imagePart.FeedData(fs); } string imagePartId = mainPart.GetIdOfPart(imagePart); // 构建Anchor元素(实现浮动布局) Anchor anchor = new Anchor() { AllowOverlap = true, BehindDoc = false, // false表示图片在文字上方,true则在下方 LayoutInCell = true, // 允许图片在表格单元格内布局 RelativeHeight = 251658240 // 相对于段落的高度基准 }; // 设置图片位置(左上角对齐段落) anchor.Append(new PositionH() { RelativeFrom = PositionHValues.Column, PosOffset = "0" }); anchor.Append(new PositionV() { RelativeFrom = PositionVValues.Paragraph, PosOffset = "0" }); // 设置图片尺寸(单位:EMU,1英寸=914400 EMU) long emuWidth = ConvertToEmu(100, 96); // 示例:100px宽度,96DPI long emuHeight = ConvertToEmu(75, 96); // 示例:75px高度,96DPI anchor.Append(new Extent() { Cx = emuWidth, Cy = emuHeight }); // 指定文字环绕方式为浮于文字上方 anchor.Append(new WrapPositioning() { Val = WrapPositioningValues.InFrontOfText }); // 构建图片的DrawingML结构 DocumentFormat.OpenXml.Drawing.Picture picture = new DocumentFormat.OpenXml.Drawing.Picture(); BlipFill blipFill = new BlipFill(); Blip blip = new Blip() { Embed = imagePartId }; blip.Append(new BlipExtensionList(new BlipExtension() { Uri = "{28A0092B-C50C-407E-A947-70E740481C1C}" })); blipFill.Append(blip); blipFill.Append(new Stretch(new FillRectangle())); ShapeProperties shapeProps = new ShapeProperties(); shapeProps.Append(new Transform2D(new Offset() { X = 0, Y = 0 }, new Extents() { Cx = emuWidth, Cy = emuHeight })); shapeProps.Append(new PresetGeometry(new AdjustValueList()) { Preset = ShapeTypeValues.Rectangle }); picture.Append(blipFill); picture.Append(shapeProps); // 构建GraphicFrame并关联图片 Graphic graphic = new Graphic(new GraphicData(picture) { Uri = "http://schemas.openxmlformats.org/drawingml/2006/picture" }); GraphicFrame graphicFrame = new GraphicFrame() { Transform = new Transform() { OffsetX = 0, OffsetY = 0, ExtentX = emuWidth, ExtentY = emuHeight } }; graphicFrame.Append(graphic); // 将Anchor加入Drawing,再插入到内容控件中 anchor.Append(graphicFrame); Drawing drawing = new Drawing(anchor); pictureControl.SdtContentBlock.Append(drawing); // 保存文档 mainPart.Document.Save(); } } // 辅助方法:将像素转换为EMU单位 private static long ConvertToEmu(int pixels, int dpi) { // 公式:EMU = (像素 / DPI) * 914400 return (long)((double)pixels / dpi * 914400); }
关键说明
- Anchor vs Inline:
Inline对应嵌入型布局,Anchor用于浮动布局,是实现浮于文字上方的核心。 - BehindDoc属性:设置为
false确保图片显示在文字层上方,设为true则在文字下方。 - WrapPositioning:通过
WrapPositioningValues.InFrontOfText明确指定文字环绕规则。 - EMU单位转换:OpenXML使用EMU作为尺寸单位,需将图片的像素尺寸转换为EMU(通过辅助方法
ConvertToEmu实现)。
内容的提问来源于stack exchange,提问作者Bonse
相关产品推荐
相关产品推荐

