使用DocumentFormat.OpenXml插入图片至Word文档时打开报错问题
问题排查与修复方案
核心问题分析
你的文档报错直接关联图片插入逻辑,结合OpenXML规范和代码细节,主要存在以下几个问题:
1. Document Body赋值方式错误
在GenerateDocxDocument方法中,使用mainPart.Document.Append(body)添加Body违反了OpenXML规范——Document节点只能包含一个Body子节点,Append操作会导致XML结构不符合Word解析要求,这是文档损坏的关键原因。
2. 图片尺寸参数不匹配
DW.Inline中的Extent(图片显示区域)和ShapeProperties中的Extents(图片自身尺寸)数值不一致,会导致Word渲染时出现布局冲突,触发解析错误。
3. GraphicData缺失必要Uri属性
A.GraphicData未指定必须的Uri属性,这会导致Word无法识别图片的类型定义,引发解析失败。
4. 非视觉元素ID冲突
DW.DocProperties的Id为1,而A.NonVisualDrawingProperties的Id为0,虽非致命错误,但可能引发Word内部资源标识冲突。
修复后的代码
修正GenerateDocxDocument方法
public void GenerateDocxDocument(TreeView treeViewFunction) { using (WordprocessingDocument wordDocument = WordprocessingDocument.Create($"Prova_documento.docx", WordprocessingDocumentType.Document)) { MainDocumentPart mainPart = wordDocument.AddMainDocumentPart(); mainPart.Document = new Document(); Body body = new Body(); foreach (var hf in HydFunctionList) { // 保留原有类属性迭代和表格生成逻辑 if (hf is Cylinder cyl) { IterateClassProperties(cyl, mainPart, table); } else if (hf is MasterValve mv) { IterateClassProperties(mv, mainPart, table); } body.Append(table); body.Append(new Paragraph(new Run(new Text("")))); } InsertImageIntoWord(mainPart, body, imagePath); // 替换Append为直接赋值Body属性,符合OpenXML规范 mainPart.Document.Body = body; mainPart.Document.Save(); } }
修正InsertImageIntoWord方法
public void InsertImageIntoWord(MainDocumentPart mainPart, Body body, string imagePath) { // 根据实际图片格式调整类型,比如Jpeg/Png ImagePart imagePart = mainPart.AddImagePart(ImagePartType.Png); using (FileStream stream = new FileStream(imagePath, FileMode.Open)) { imagePart.FeedData(stream); } string imagePartId = mainPart.GetIdOfPart(imagePart); // 统一图片尺寸(EMU单位:1cm ≈ 360000 EMU) long imageWidth = 990000L; long imageHeight = 792000L; var drawingElement = new Drawing( new DW.Inline( new DW.Extent() { Cx = imageWidth, Cy = imageHeight }, new DW.EffectExtent() { LeftEdge = 0L, TopEdge = 0L, RightEdge = 0L, BottomEdge = 0L }, new DW.DocProperties() { Id = (UInt32Value)1U, Name = "Immagine" }, new DW.NonVisualGraphicFrameDrawingProperties(new A.GraphicFrameLocks() { NoChangeAspect = true }), new A.Graphic( new A.GraphicData( new A.Picture( new A.NonVisualPictureProperties( new A.NonVisualDrawingProperties() { Id = (UInt32Value)2U, Name = "Picture" }, // 设置唯一ID new A.NonVisualPictureDrawingProperties()), new A.BlipFill( new A.Blip() { Embed = imagePartId, CompressionState = A.BlipCompressionValues.Print }, new A.Stretch(new A.FillRectangle())), new A.ShapeProperties( new A.Transform2D( new A.Offset() { X = 0L, Y = 0L }, new A.Extents() { Cx = imageWidth, Cy = imageHeight }), // 和Inline尺寸保持一致 new A.PresetGeometry(new A.AdjustValueList()) { Preset = A.ShapeTypeValues.Rectangle }))) { Uri = "http://schemas.openxmlformats.org/drawingml/2006/picture" } // 必须指定图片类型的Uri ) { DistanceFromTop = 0L, DistanceFromBottom = 0L, DistanceFromLeft = 0L, DistanceFromRight = 0L } // 补充Inline的间距属性 ); Paragraph imagePara = new Paragraph(new Run(drawingElement)); body.Append(imagePara); }
额外检查项
- 确保
imagePath是绝对路径,或程序有访问权限的相对路径,避免图片流读取不完整。 - 验证图片本身无损坏,可尝试用系统自带的测试图片排查问题。
- 若图片格式不是PNG,对应修改
ImagePartType(如ImagePartType.Jpeg)。
内容的提问来源于stack exchange,提问作者simone.m
相关产品推荐
相关产品推荐

