使用OpenXml为Word横向文档设置适配页面的背景图片问题
使用OpenXml为Word横向文档设置适配页面的背景图片问题
我明白你现在遇到的头疼问题——用OpenXml给横向Word文档加背景图,要么图溢出页面,要么干脆不显示,想要让背景图完美贴合横向页面确实需要调整几个关键设置。咱们一步步来改你的代码:
1. 先修复图片写入的冗余代码
你代码里这部分存在问题,可能是导致换Fill Type后图片不显示的原因之一:
using (MemoryStream stream = new MemoryStream(imageBytes)) { imagePart.FeedData(stream); BinaryWriter bw = new BinaryWriter(stream); bw.Write(imageBytes); bw.Close(); }
FeedData(stream)已经把内存流里的图片数据完整写入到ImagePart了,之后再用BinaryWriter写一次会导致图片数据重复损坏,直接删掉后面的BinaryWriter部分即可:
using (MemoryStream stream = new MemoryStream(imageBytes)) { imagePart.FeedData(stream); }
2. 调整背景填充与页面适配的核心设置
要让背景图精准贴合横向页面,需要修改V.Fill的类型,同时给V.Background设置和页面一致的尺寸:
2.1 修改V.Fill的Type属性
把原来的Type = V.FillTypeValues.Frame改成Type = V.FillTypeValues.Stretch,这样图片会自动拉伸适配背景区域大小。如果你想保持图片比例不变同时填满页面,可以换成Type = V.FillTypeValues.Fit(但这样可能会有留白,根据你的需求选择)。
2.2 给V.Background设置匹配页面的尺寸
你的文档是横向的,PageSize设置的宽是16838U、高是11906U(单位是twip,1英寸=1440twip),所以给V.Background加上对应尺寸和定位属性:
V.Background bg = new V.Background() { Id = "_x0000_s1025", BlackWhiteMode = V.Office.BlackAndWhiteModeValues.White, TargetScreenSize = V.Office.ScreenSizeValues.Sz1024x768, Width = "16838twip", // 和PageSize.Width保持一致 Height = "11906twip", // 和PageSize.Height保持一致 Position = "absolute", Left = "0", Top = "0" };
2.3 优化DocumentBackground的Color设置
既然用图片做背景,DocumentBackground的Color可以注释掉或者设为透明,避免影响图片显示:
DocumentBackground docBg = new DocumentBackground(); // 或者设为透明:Color = "transparent"
3. 整合修改后的关键代码片段
把以上调整整合到你的代码中,相关部分最终是这样的:
var MainPageImgUrl = tocsInfo.FirstOrDefault(x => x.id == 7)?.images["background1"]; if (!string.IsNullOrEmpty(MainPageImgUrl)) { byte[] imageBytes = await DownloadBackgroundImage(MainPageImgUrl); // 向ImagePart添加图片 ImagePart imagePart = mainPart.AddImagePart(ImagePartType.Png); using (MemoryStream stream = new MemoryStream(imageBytes)) { imagePart.FeedData(stream); } string imageId = mainPart.GetIdOfPart(imagePart); DocumentBackground docBg = new DocumentBackground(); V.Background bg = new V.Background() { Id = "_x0000_s1025", BlackWhiteMode = V.Office.BlackAndWhiteModeValues.White, TargetScreenSize = V.Office.ScreenSizeValues.Sz1024x768, Width = "16838twip", Height = "11906twip", Position = "absolute", Left = "0", Top = "0" }; bg.AddNamespaceDeclaration("v", "urn:schemas-microsoft-com:vml"); V.Fill fill = new V.Fill() { RelationshipId = imageId, Title = "background", Recolor = false, Type = V.FillTypeValues.Stretch, // 改为Stretch适配页面 Aspect = V.ImageAspectValues.Ignore, }; var settingsPart = mainPart.DocumentSettingsPart; if (settingsPart == null) { settingsPart = mainPart.AddNewPart<DocumentSettingsPart>(); settingsPart.Settings = new Settings(); } settingsPart.Settings.Append(new DisplayBackgroundShape()); settingsPart.Settings.Save(); bg.Append(fill); docBg.Append(bg); mainPart.Document.InsertAt(docBg, 0); }
为什么这样改能解决问题?
- 去掉冗余的BinaryWriter代码,保证图片数据完整,解决换Fill Type后图片不显示的问题;
- 给V.Background设置和页面完全一致的尺寸,确保背景区域正好覆盖整个横向页面;
- 使用
Stretch类型填充,让图片拉伸适配背景区域,既不会溢出也不会留白(选Fit则能保持图片比例,按需切换即可)。
备注:内容来源于stack exchange,提问作者Batuhan Başkır
相关产品推荐
相关产品推荐

