Outlook含内嵌图片的MailItem保存为PDF时丢失图片的问题求解
解决Outlook MailItem保存为PDF时内嵌图片丢失的方案
问题根因
Outlook内嵌图片通过cid引用绑定到对应附件,调用GetInspector.WordEditor直接导出PDF时,Word的PDF导出逻辑不会主动把cid关联的附件图片嵌入到输出流,因此会将其识别为独立附件而非邮件内容的一部分。而保存RTF格式时Outlook会自动处理cid绑定逻辑,所以图片不会丢失。
可用解决方案
- 方案1:先转RTF过渡再导出PDF(改造成本最低,适配现有逻辑)
你已经验证保存RTF不会丢失图片,可先将WordEditor保存为临时RTF文件,再用Word对象打开该RTF后导出为PDF,示例代码如下:
该方案不需要修改你现有附件过滤逻辑,兼容性更高。// 生成临时RTF路径 string tempRtfPath = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString() + ".rtf"); Microsoft.Office.Interop.Word.Document doc = mailItem.GetInspector.WordEditor; doc.SaveAs2(tempRtfPath, Microsoft.Office.Interop.Word.WdSaveFormat.wdFormatRTF); doc.Close(); // 打开临时RTF转PDF Microsoft.Office.Interop.Word.Application wordApp = new Microsoft.Office.Interop.Word.Application(); Microsoft.Office.Interop.Word.Document rtfDoc = wordApp.Documents.Open(tempRtfPath); rtfDoc.ExportAsFixedFormat(PDFpath, Microsoft.Office.Interop.Word.WdExportFormat.wdExportFormatPDF); rtfDoc.Close(); wordApp.Quit(); // 清理临时RTF文件 if(File.Exists(tempRtfPath)) File.Delete(tempRtfPath); - 方案2:优化内嵌附件判断逻辑,替换cid为本地路径
你现有通过HTMLBody.Contains(aFileName)判断的逻辑准确率低,容易出现重名误判,建议通过MAPI属性判断是否为内嵌图片,同时将cid引用替换为本地图片路径,保证Word导出PDF时可以正常读取图片:// 内嵌图片的MAPI属性标识 const string PR_ATTACH_CONTENT_ID = "http://schemas.microsoft.com/mapi/proptag/0x3712001F"; foreach(Attachment a in mailItem.Attachments) { string contentId = ""; try { contentId = a.PropertyAccessor.GetProperty(PR_ATTACH_CONTENT_ID)?.ToString(); } catch { } // 存在contentId且HTMLBody包含对应cid引用则为内嵌图片 if(!string.IsNullOrEmpty(contentId) && mailItem.HTMLBody.Contains($"cid:{contentId}")) { // 导出内嵌图片到临时路径,替换HTMLBody中的cid引用 string tempImgPath = Path.Combine(Path.GetTempPath(), contentId + Path.GetExtension(a.FileName)); a.SaveAsFile(tempImgPath); mailItem.HTMLBody = mailItem.HTMLBody.Replace($"cid:{contentId}", new Uri(tempImgPath).AbsoluteUri); continue; } // 普通附件走原有绑定逻辑 a.SaveAsFile(attachmentPath); contentEditor.AddDocumentAttachment(attachmentPath, aFileName); } // 替换完成后转PDF Microsoft.Office.Interop.Word.Document doc = mailItem.GetInspector.WordEditor; doc.ExportAsFixedFormat(PDFpath, Microsoft.Office.Interop.Word.WdExportFormat.wdExportFormatPDF); - 方案3:用
ExportAsFixedFormat替换SaveAs方法
你当前使用的SaveAs方法对PDF导出的参数控制较少,改用参数更全的ExportAsFixedFormat可以避免图片被过滤:Microsoft.Office.Interop.Word.Document doc = mailItem.GetInspector.WordEditor; doc.ExportAsFixedFormat( OutputFileName: PDFpath, ExportFormat: Microsoft.Office.Interop.Word.WdExportFormat.wdExportFormatPDF, OpenAfterExport: false, OptimizeFor: Microsoft.Office.Interop.Word.WdExportOptimizeFor.wdExportOptimizeForPrint, Range: Microsoft.Office.Interop.Word.WdExportRange.wdExportAllDocument, Item: Microsoft.Office.Interop.Word.WdExportItem.wdExportDocumentContent, IncludeDocProps: true, KeepIRM: true, CreateBookmarks: Microsoft.Office.Interop.Word.WdExportCreateBookmarks.wdExportCreateWordBookmarks, DocStructureTags: true, BitmapMissingFonts: true, UseISO19005_1: false );
内容的提问来源于stack exchange,提问作者dreamy
相关产品推荐
相关产品推荐

