如何在ASP.NET的Crystal Report中替换图片并适配原有宽度?
ASP.NET Crystal Report 替换图片后保持原有尺寸的解决方案
你的核心问题是获取了旧图片的尺寸但未实际应用到新图片上,且代码中使用了未定义的w和h变量。以下是修正后的完整实现,确保新图片继承旧图片的宽高:
private void ReplaceHeaderAndFooter(ReportDocument report) { var clientDoc = report.ReportClientDocument.ReportDefController; const string HeaderPath = "Reports\\Images\\headerSIS.png"; const string FooterPath = "Reports\\Images\\footerSIS.png"; string newHeaderImagePath = Path.GetFullPath(HeaderPath); string newFooterImagePath = Path.GetFullPath(FooterPath); // 获取报表页眉区域 var headerSection = clientDoc.ReportDefinition.ReportHeaderArea.Sections[0]; int oldWidth = 0; int oldHeight = 0; string oldHeaderPictureName = string.Empty; // 定位页眉中的旧图片并保存其尺寸和名称 if (headerSection.ReportObjects.Count > 0) { for (int i = 0; i < headerSection.ReportObjects.Count; i++) { var reportObj = headerSection.ReportObjects[i]; if (reportObj.Kind == CrystalDecisions.ReportAppServer.ReportDefModel.CrReportObjectKindEnum.crReportObjectKindPicture) { oldHeaderPictureName = reportObj.Name; oldWidth = reportObj.Width; oldHeight = reportObj.Height; break; // 假设页眉只有一张图片,找到后退出循环 } } } // 删除旧图片并导入新图片 if (!string.IsNullOrEmpty(oldHeaderPictureName)) { clientDoc.ReportObjectController.Remove(headerSection.ReportObjects[oldHeaderPictureName]); // 导入新图片到页眉的(0,0)位置 clientDoc.ReportObjectController.ImportPicture(newHeaderImagePath, headerSection, 0, 0); } // 调整新图片的尺寸为旧图片的尺寸 if (headerSection.ReportObjects.Count > 0) { for (int i = 0; i < headerSection.ReportObjects.Count; i++) { var reportObj = headerSection.ReportObjects[i]; if (reportObj.Kind == CrystalDecisions.ReportAppServer.ReportDefModel.CrReportObjectKindEnum.crReportObjectKindPicture) { var newPictureObj = (CrystalDecisions.ReportAppServer.ReportDefModel.PictureObject)reportObj; // 直接应用旧图片的宽高(Crystal Report使用缇(Twip)作为单位,无需转换) newPictureObj.Width = oldWidth; newPictureObj.Height = oldHeight; // 提交修改到报表定义 clientDoc.ReportObjectController.Modify(newPictureObj); break; } } } // 以下是页脚图片的替换逻辑,和页眉同理 var footerSection = clientDoc.ReportDefinition.ReportFooterArea.Sections[0]; int oldFooterWidth = 0; int oldFooterHeight = 0; string oldFooterPictureName = string.Empty; if (footerSection.ReportObjects.Count > 0) { for (int i = 0; i < footerSection.ReportObjects.Count; i++) { var reportObj = footerSection.ReportObjects[i]; if (reportObj.Kind == CrystalDecisions.ReportAppServer.ReportDefModel.CrReportObjectKindEnum.crReportObjectKindPicture) { oldFooterPictureName = reportObj.Name; oldFooterWidth = reportObj.Width; oldFooterHeight = reportObj.Height; break; } } } if (!string.IsNullOrEmpty(oldFooterPictureName)) { clientDoc.ReportObjectController.Remove(footerSection.ReportObjects[oldFooterPictureName]); clientDoc.ReportObjectController.ImportPicture(newFooterImagePath, footerSection, 0, 0); } if (footerSection.ReportObjects.Count > 0) { for (int i = 0; i < footerSection.ReportObjects.Count; i++) { var reportObj = footerSection.ReportObjects[i]; if (reportObj.Kind == CrystalDecisions.ReportAppServer.ReportDefModel.CrReportObjectKindEnum.crReportObjectKindPicture) { var newPictureObj = (CrystalDecisions.ReportAppServer.ReportDefModel.PictureObject)reportObj; newPictureObj.Width = oldFooterWidth; newPictureObj.Height = oldFooterHeight; clientDoc.ReportObjectController.Modify(newPictureObj); break; } } } }
关键修正点:
- 使用旧图片的尺寸变量:将原来未定义的
w和h替换为之前保存的oldWidth和oldHeight,确保新图片和旧图片尺寸完全一致。 - 明确对象类型转换:将
ISCRPictureObject转换为PictureObject,确保可以正确访问和修改尺寸属性。 - 提交修改:调用
ReportObjectController.Modify()方法,确保尺寸修改被应用到报表定义中。 - 优化循环逻辑:找到目标图片后立即退出循环,避免不必要的遍历。
额外注意事项:
- Crystal Report的尺寸单位是缇(Twip),1缇=1/1440英寸,无需手动转换,直接复用旧图片的数值即可。
- 如果报表页眉/页脚存在多张图片,需要调整逻辑(比如通过名称匹配)来定位目标图片,本代码假设每个区域只有一张图片。
内容的提问来源于stack exchange,提问作者Ahmad_Lutfi
相关产品推荐
相关产品推荐

