You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Outlook React加载项:新增按钮打开自定义任务窗格/弹窗及文本插入实现

解决Outlook加载项弹窗加载失败及文本插入实现方案

一、先修复弹窗页面加载失败的问题

1. 检查Manifest配置

确保你的加载项manifest.xml中,<AppDomains>节点包含弹窗页面的域名(本地开发填http://localhost:3000,线上环境填实际域名):

<AppDomains>
  <AppDomain>http://localhost:3000</AppDomain>
  <!-- 线上环境添加你的实际域名 -->
</AppDomains>

2. 修正弹窗页面路径

不要用示例的https://www.contoso.com/myDialog.html,换成React项目内的实际路径。比如通过React Router配置弹窗路由:

// App.jsx
import { BrowserRouter as Router, Routes, Route } from 'react-router-dom';
import TaskPane from './TaskPane';
import Dialog from './Dialog';

function App() {
  return (
    <Router>
      <Routes>
        <Route path="/" element={<TaskPane />} />
        <Route path="/dialog" element={<Dialog />} />
      </Routes>
    </Router>
  );
}

然后调用displayDialogAsync时使用本地路径,并添加错误排查:

Office.context.ui.displayDialogAsync('http://localhost:3000/dialog', {
  height: 30,
  width: 20,
  displayInIframe: true
}, (result) => {
  if (result.status === Office.AsyncResultStatus.Failed) {
    console.error('弹窗加载失败:', result.error.message);
  } else {
    const dialog = result.value;
    dialog.addEventHandler(Office.EventType.DialogEventReceived, (args) => {
      if (args.error) console.error('弹窗事件错误:', args.error.message);
    });
  }
});

3. 排查页面加载报错

打开Outlook加载项的开发者工具(右键→检查),根据控制台报错调整:

  • 404错误:确认路径拼写正确,React项目已启动且端口匹配
  • CORS错误:确认域名已加入AppDomains,本地开发可尝试用HTTPS=true npm start启动项目(部分Outlook环境要求HTTPS)

二、实现弹窗输入文本插入邮件功能

1. 弹窗页面(Dialog.jsx)实现

添加输入框和按钮,点击后将文本传给主任务窗格并关闭弹窗:

import React, { useState } from 'react';

function Dialog() {
  const [inputText, setInputText] = useState('');

  const handleInsert = () => {
    if (!inputText.trim()) return;
    // 向主任务窗格发送文本
    Office.context.ui.messageParent(inputText);
    // 关闭弹窗
    Office.context.ui.closeContainer();
  };

  return (
    <div style={{ padding: '20px', textAlign: 'center' }}>
      <h3>输入要插入的文本</h3>
      <input
        type="text"
        value={inputText}
        onChange={(e) => setInputText(e.target.value)}
        style={{ width: '80%', padding: '8px', margin: '10px 0' }}
        placeholder="输入文本..."
      />
      <button
        onClick={handleInsert}
        style={{ padding: '8px 16px', cursor: 'pointer' }}
      >
        插入到邮件
      </button>
    </div>
  );
}

export default Dialog;

2. 主任务窗格监听弹窗消息

在打开弹窗的逻辑中,监听弹窗传来的文本并插入到邮件正文:

// 主任务窗格中打开弹窗的按钮点击事件
const openInsertDialog = () => {
  Office.context.ui.displayDialogAsync('http://localhost:3000/dialog', {
    height: 30,
    width: 20,
    displayInIframe: true
  }, (result) => {
    if (result.status === Office.AsyncResultStatus.Succeeded) {
      const dialog = result.value;
      // 监听弹窗消息
      dialog.addEventHandler(Office.EventType.DialogMessageReceived, async (args) => {
        const textToInsert = args.message;
        try {
          // 插入文本到邮件正文
          await Office.context.mailbox.item.body.setSelectedDataAsync(
            textToInsert,
            { coercionType: Office.CoercionType.Text }
          );
          console.log('文本插入成功');
        } catch (error) {
          console.error('插入失败:', error.message);
        }
      });
    } else {
      console.error('弹窗打开失败:', result.error.message);
    }
  });
};

3. 新增加载项按钮

在manifest.xml中添加第三个按钮,关联openInsertDialog函数:

<ExtensionPoint xsi:type="MessageReadCommandSurface">
  <OfficeTab id="TabDefault">
    <Group id="msgReadGroup">
      <!-- 现有两个按钮 -->
      <Control xsi:type="Button" id="msgReadOpenPaneButton">
        <!-- 原有配置 -->
      </Control>
      <Control xsi:type="Button" id="msgReadFunctionButton">
        <!-- 原有配置 -->
      </Control>
      <!-- 新增插入文本按钮 -->
      <Control xsi:type="Button" id="msgReadInsertTextButton">
        <Label resid="TaskpaneButtonInsertLabel" />
        <Supertip>
          <Title resid="TaskpaneButtonInsertTitle" />
          <Description resid="TaskpaneButtonInsertDesc" />
        </Supertip>
        <Icon>
          <bt:Image size="16" resid="Icon.16x16" />
          <bt:Image size="32" resid="Icon.32x32" />
          <bt:Image size="80" resid="Icon.80x80" />
        </Icon>
        <Action xsi:type="ExecuteFunction">
          <FunctionName>openInsertDialog</FunctionName>
        </Action>
      </Control>
    </Group>
  </OfficeTab>
</ExtensionPoint>

同时在Resources节点添加对应字符串资源:

<Resources>
  <bt:ShortStrings>
    <bt:String id="TaskpaneButtonInsertLabel" DefaultValue="插入文本" />
    <bt:String id="TaskpaneButtonInsertTitle" DefaultValue="插入自定义文本" />
  </bt:ShortStrings>
  <bt:LongStrings>
    <bt:String id="TaskpaneButtonInsertDesc" DefaultValue="打开弹窗输入文本,插入到当前邮件" />
  </bt:LongStrings>
</Resources>

三、测试注意事项

  • 本地开发时,确保Outlook加载项已正确加载,可使用网页版或桌面版的测试模式
  • 弹窗页面需加载Office.js:在React项目的public/index.html中添加<script src="https://appsforoffice.microsoft.com/lib/1/hosted/office.js"></script>
  • HTTPS本地开发时,需信任自签名证书,避免证书报错

内容的提问来源于stack exchange,提问作者Ross

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 22:15:03