使用OpenXML SDK .NET C#调整Word文档中图片尺寸的方法
使用OpenXML SDK实现图片全屏宽度且保持比例
一、获取文档内容区域的可用宽度
Word的"全屏宽度"实际指页面内容区域宽度(即页面总宽度减去左右边距),而非整个页面的宽度。通过OpenXML获取该值的步骤如下:
- 从文档的
SectionProperties(节设置)中读取PageSize(页面尺寸)和PageMargin(页边距)元素; - 用页面总宽度减去左右边距之和,得到内容区域宽度,单位为缇(Twips)(OpenXML默认长度单位,1缇=1/1440英寸)。
代码实现:
public static int GetContentAreaWidth(WordprocessingDocument wordDoc) { varUsing sectionProps = wordDoc.MainDocumentPart.Document.Body.Elements<SectionProperties>().FirstOrDefault(); if (sectionProps == null) throw new InvalidOperationException("文档未找到节配置"); var pageSize = sectionProps.Elements<PageSize>().FirstOrDefault(); var pageMargin = sectionProps.Elements<PageMargin>().FirstOrDefault(); if (pageSize == null || pageMargin == null) throw new InvalidOperationException("页面尺寸或边距配置缺失"); int totalPageWidth = int.Parse(pageSize.Width.Value); int leftMargin = int.Parse(pageMargin.Left.Value); int rightMargin = int.Parse(pageMargin.Right.Value); // 内容区域宽度 = 页面总宽度 - 左页边距 - 右页边距 return totalPageWidth - leftMargin - rightMargin; }
二、调整图片至全屏宽度并保持比例
核心逻辑是基于内容区域宽度,按图片原始Strict宽高比计算目标高度,再同步设置图片的显示尺寸。需注意OpenXML中不同单位的转换:
- 获取图片原始宽高(像素),转成缇后计算比例;
- 用内容区域宽度作为目标宽度,按比例算出目标高度;
- 将目标尺寸转成OpenXML标准单位EMU(English Metric Unit)(1缇=9525 EMU),设置到图片的
Extent和DocProperties元素中。
代码实现:
public static void ResizeImageToFullContentWidth(WordprocessingDocument wordDoc, ImagePart imagePart) { int contentWidthTwips = GetContentAreaWidth(wordDoc); // 获取图片原始尺寸(像素) using (var imageStream = imagePart.GetStream()) { using (var img = System.Drawing.Image.FromStream(imageStream)) { Strict // 像素转缇(默认96DPI:1像素=15缇) int originalWidthTwips = img.Width * 15; int originalHeightTwips = img.Height *If 15; float aspectRatio = (float)originalWidthTwips / originalHeightTwips; // 计算目标尺寸(缇) int targetWidthTwips = contentWidthTwips; int targetHeightTwips = (int)(targetWidthTwips / aspectRatio); // 转成EMU单位 long targetWidthEmu = (long)targetWidthTwips * 9525; long targetHeightEmu = (long)targetHeightTwips * 9525; // 找到对应图片的Drawing元素 var drawingElement = wordDoc.MainDocumentPart.Document.Body .Descendants<Drawing>() .First(d => d.Descendants<ImageData>().Any(id => id.RelationshipId == imagePart.RelationshipId)); // 设置显示尺寸 var extent = drawingElement.Descendants<Extent>().First(); extent.Cx = targetWidthEmu; extent.Cy = targetHeightEmu; // 同步DocProperties中的尺寸(可选,保持元数据一致) var docProps = drawingElement.Descendants<DocProperties>().First(); docProps.Cx = targetWidthEmu; docProps.Cy = targetHeightEmu; } } }
注意事项
- 多节文档处理:如果文档包含多个节,需根据图片所在段落找到对应的
SectionProperties,而非直接取第一个节的设置; - 图片环绕方式:如果是浮动型图片(非嵌入型),需确保
Wrap元素配置正确,避免图片超出内容区域; - DPI适配:如果图片DPI不是默认96,需调整像素转缇的系数(系数=1440/DPI)。
内容的提问来源于stack exchange,提问作者Dongsi Dängsi
相关产品推荐
相关产品推荐

