如何通过Outlook VSTO将含邮件头和正文的完整邮件保存为PDF
Outlook VSTO 完整导出邮件(含头部信息)为PDF解决方案
你现有代码的核心问题有两个:
- 直接调用
GetInspector.WordEditor获取的文档默认处于受保护的只读状态,直接编辑会失败 - 未拼接发件人、收件人、主题、时间等邮件头信息,仅导出了正文内容
下面提供两种可行解决方案:
方案1:自定义拼接邮件头后导出
该方案支持灵活调整头部显示格式,不会修改原邮件内容
using Word = Microsoft.Office.Interop.Word; using System.IO; private void SaveMailAsPDF(Outlook.MailItem _mailitem) { Outlook.MailItem mi = _mailitem; string datetimeReceived = mi.ReceivedTime.ToString("yyyyMMdd-Hmmss"); string fullPath = @"C:\Users\al\Documents\OutlookMailsTest\" + datetimeReceived + "Test.pdf"; string tempHtmlPath = Path.Combine(Path.GetTempPath(), $"{Guid.NewGuid()}.html"); // 拼接格式化的邮件头HTML string headerHtml = $@" <div style='font-family:微软雅黑;font-size:14px;border-bottom:1px solid #eee;padding-bottom:10px;margin-bottom:10px;'> <p><strong>主题:</strong>{mi.Subject}</p> <p><strong>发件人:</strong>{mi.SenderName} <{mi.SenderEmailAddress}></p> <p><strong>收件人:</strong>{mi.To}</p> <p><strong>抄送:</strong>{mi.CC}</p> <p><strong>收件时间:</strong>{mi.ReceivedTime.ToString("yyyy年MM月dd日 HH:mm:ss")}</p> </div>"; // 拼接完整HTML内容 string fullHtml = headerHtml + mi.HTMLBody; // 写入临时HTML文件 File.WriteAllText(tempHtmlPath, fullHtml, System.Text.Encoding.UTF8); // 新建Word实例加载临时HTML,导出为PDF Word.Application wordApp = new Word.Application(); wordApp.Visible = false; Word.Document doc = wordApp.Documents.Open(tempHtmlPath); doc.SaveAs2(fullPath, FileFormat: Word.WdSaveFormat.wdFormatPDF); // 清理资源 doc.Close(); wordApp.Quit(); File.Delete(tempHtmlPath); // 释放COM对象避免内存泄漏 System.Runtime.InteropServices.Marshal.ReleaseComObject(doc); System.Runtime.InteropServices.Marshal.ReleaseComObject(wordApp); }
方案2:调用Outlook原生打印功能导出PDF
该方案导出的内容和Outlook原生打印效果完全一致,自动包含所有标准邮件头信息,无需手动拼接格式
private void SaveMailAsPDF(Outlook.MailItem _mailitem) { string datetimeReceived = _mailitem.ReceivedTime.ToString("yyyyMMdd-Hmmss"); string fullPath = @"C:\Users\al\Documents\OutlookMailsTest\" + datetimeReceived + "Test.pdf"; // 保存当前默认打印机 object originalPrinter = _mailitem.Application.ActiveExplorer().Application.ActivePrinter; try { // 切换到系统自带的PDF打印机 _mailitem.Application.ActiveExplorer().Application.ActivePrinter = "Microsoft Print to PDF"; // 直接打印输出到指定路径 _mailitem.PrintOut( Copies: 1, Preview: false, OutputFileName: fullPath ); } finally { // 恢复原来的默认打印机 _mailitem.Application.ActiveExplorer().Application.ActivePrinter = originalPrinter.ToString(); } }
注意事项
- 方案2需要系统预装「Microsoft Print to PDF」打印机,Win10及以上版本系统默认自带
- 生产环境使用建议添加异常捕获逻辑,处理文件占用、权限不足等问题
内容的提问来源于stack exchange,提问作者Alexander
相关产品推荐
相关产品推荐

