如何使用OfficeJS获取Outlook 365邮件的打印预览URL?
嘿,我来帮你梳理下这个问题——首先得明确:Office JavaScript API并没有直接提供获取Outlook打印预览URL的接口,因为打印预览是Outlook客户端内部渲染的页面,根本没对外暴露可访问的URL地址。不过别担心,我们有替代方案能拿到和打印预览效果一致的完整邮件内容,还能适配Outlook 365和2016桌面版,下面具体说:
方案1:用Office JS直接拿完整HTML正文
如果你的需求只是拿到完整的邮件HTML内容(和打印预览格式几乎一致),那这个方案最直接,而且Outlook 2016桌面版和365都支持。你可以用body.getAsync方法指定Office.CoercionType.Html来获取全量的邮件HTML:
Office.context.mailbox.item.body.getAsync( Office.CoercionType.Html, function(result) { if (result.status === Office.AsyncResultStatus.Succeeded) { const fullHtmlBody = result.value; // 这里直接把fullHtmlBody发给你的Web API就行,或者做进一步处理 console.log(fullHtmlBody); } else { console.error('获取HTML正文失败:', result.error); } } );
这个方法拿到的HTML包含邮件所有内容——格式、图片引用啥的都有,渲染效果和打印预览基本一致,是最省心的方案。
方案2:通过EWS拿完整MIME内容(生成PDF/HTML)
如果需要生成标准的PDF文件,或者要和打印预览完全一模一样的格式,那可以试试通过Exchange Web Services (EWS) 获取邮件的完整MIME内容,然后让你的Web API来转成PDF或HTML。Outlook 2016桌面版和365都支持makeEwsRequestAsync调用EWS:
第一步:调用EWS获取MIME内容
const itemId = Office.context.mailbox.item.itemId; // 构造EWS请求XML,用来拿邮件的MIME内容 const ewsRequest = `<?xml version="1.0" encoding="utf-8"?> <soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:m="http://schemas.microsoft.com/exchange/services/2006/messages" xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"> <soap:Header> <t:RequestServerVersion Version="Exchange2013" /> </soap:Header> <soap:Body> <m:GetItem> <m:ItemShape> <t:BaseShape>IdOnly</t:BaseShape> <t:AdditionalProperties> <t:FieldURI FieldURI="item:MimeContent" /> </t:AdditionalProperties> </m:ItemShape> <m:ItemIds> <t:ItemId Id="${itemId}" /> </m:ItemIds> </m:GetItem> </soap:Body> </soap:Envelope>`; Office.context.mailbox.makeEwsRequestAsync(ewsRequest, function(result) { if (result.status === Office.AsyncResultStatus.Succeeded) { // 解析XML响应,提取MIME内容 const parser = new DOMParser(); const xmlDoc = parser.parseFromString(result.value, "text/xml"); const mimeContent = xmlDoc.getElementsByTagName("t:MimeContent")[0].textContent; // 把base64编码的MIME内容发给Web API,后端可以用工具转成PDF或HTML sendToWebApi(mimeContent); } else { console.error('调用EWS失败:', result.error); } });
第二步:后端转换MIME为PDF/HTML
拿到MIME内容后,你的Web API可以用MimeKit(.NET)、mailparser(Node.js)这类库解析MIME,然后用wkhtmltopdf或Puppeteer把解析后的HTML渲染成PDF,完全能达到打印预览的效果。
方案3:用Microsoft Graph API(优先推荐给Outlook 365用户)
如果你的插件主要服务Outlook 365用户,那用Microsoft Graph API更方便,不仅能拿完整内容,还能直接生成PDF:
获取邮件MIME内容
// 先通过Office JS的身份验证流程拿到访问令牌 const accessToken = await getAccessToken(); const messageId = Office.context.mailbox.item.itemId; // 把Outlook的itemId转成Graph能识别的格式 const graphId = Office.context.mailbox.convertToRestId(messageId, Office.MailboxEnums.RestVersion.v2_0); fetch(`https://graph.microsoft.com/v1.0/me/messages/${graphId}/$value`, { headers: { 'Authorization': `Bearer ${accessToken}` } }) .then(response => response.text()) .then(mimeContent => { // 发给Web API处理就行 sendToWebApi(mimeContent); }) .catch(error => console.error('调用Graph API失败:', error));
直接获取PDF预览(Graph专属福利)
Graph API还支持直接拿邮件的PDF文件,不过这个功能只有Outlook 365能用:
fetch(`https://graph.microsoft.com/v1.0/me/messages/${graphId}/$value?format=pdf`, { headers: { 'Authorization': `Bearer ${accessToken}` } }) .then(response => response.blob()) .then(pdfBlob => { // 把PDF blob打包发给Web API const formData = new FormData(); formData.append('pdf', pdfBlob, 'email.pdf'); fetch('你的Web API地址', { method: 'POST', body: formData }); }) .catch(error => console.error('获取PDF失败:', error));
注意:Outlook 2016桌面版对Graph API的支持有限,要是你必须适配这个版本,优先选方案1或方案2。
几个关键提醒
- 权限配置:用EWS或Graph API时,得在插件的
manifest.xml里配置对应的权限(比如ReadItem),不然插件没权限访问邮件内容。 - 兼容性测试:Outlook 2016桌面版的Office JS版本比较老,建议在测试环境里挨个验证API能不能用。
- 图片引用处理:拿到的HTML里的图片可能是Outlook内部的cid引用,发给Web API后得处理这些引用,确保图片能正常显示(可以通过EWS或Graph获取图片附件的内容)。
内容的提问来源于stack exchange,提问作者vcRobe

