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

Word Online中ContentControl显示/隐藏的问题及解决尝试

预期目标

我希望能基于特定逻辑,通过编程方式显示/隐藏文本块(单个或多个段落)。

尝试方案

我试过以下几种解决方法,但每种都存在相应问题,具体如下:

隐藏文本

最简单的方式是开启段落的「隐藏」选项。这种方法原本效果很好,但遗憾的是它在Word Online中不受支持。真的是这样吗?

OOXML方案

另一种方法是将内容控件(Content Control)的内容存储在文档内的XML部件中,之后再恢复。该方案仅部分可行,体验极不稳定:操作速度极慢,且经常静默失败。

隐藏Content Control

隐藏Content Control的操作相当简单,且每次都能快速完成:

/**
 * 存储文档设置的辅助函数
 **/
type DocumentSettingSet = <T>(settingName: string, settingValue: T) => void;
const documentSettingSet: DocumentSettingSet = (settingName, settingValue) =>
  Office.context.document.settings.set(settingName, settingValue);

/**
 * 将所有文档设置保存到文档中
 **/
export type DocumentSettingsSave = () => Promise<void>;
export const documentSettingsSave: DocumentSettingsSave = async () => {
    await Office.context.document.settings.saveAsync();
};

/**
 * 在文档中设置XML部件的辅助函数
 **/
const xmlPartSet = (xml: string): Promise<Office.CustomXmlPart> =>
  new Promise((resolve, reject) => {
    Office.context.document.customXmlParts.addAsync(xml, (result) => {
      if (result.status === Office.AsyncResultStatus.Failed) {
        reject(result.error);
        return;
      }
      resolve(result.value);
    });
  });

/**
 * 隐藏Content Control并存储其内容以便后续恢复
 **/
Word.run(async (context) => {
  // 找到要隐藏的Content Control - 假设已知其ID
  const contentControl = context.document.contentControls.getById('the-control-id');
  context.load(contentControl, ['appearance', 'tag', 'title']);
  await context.sync();
  // 获取Content Control内的OOXML并存储到自定义XML部件中
  // 将自定义XML部件的ID存储到文档设置中,供后续使用
  const xml = contentControl.getRange('Content').getOoxml();
  await context.sync();
  const xmlPart = await xmlPartSet(xml.value);
  documentSettingSet<string>(`block-xml-part-id-${contentControl.tag}`, xmlPart.id);
  await documentSettingsSave();
  // 清空Content Control并隐藏其作为控件的外观
  contentControl.cannotEdit = false;
  await context.sync();
  contentControl.appearance = Word.ContentControlAppearance.hidden;
  contentControl.insertText('\u200b', Word.InsertLocation.replace);
  contentControl.cannotEdit = true;
  await context.sync();
});

显示Content Control

显示Content Control时问题频发:首先加载耗时极长,加载器消失后仍需等待一分钟以上才能显示,多次出现显示失败,控制台提示需刷新页面才能显示内容。

/**
 * 获取文档设置值的辅助函数
 **/
export type DocumentSettingGet = <T>(settingName: string) => T;
export const documentSettingGet: DocumentSettingGet = (settingName) =>
  Office.context.document.settings.get(settingName);

/**
 * 从文档中获取自定义XML部件的辅助函数
 **/
export const xmlPartGet = (id: string): Promise<Office.CustomXmlPart | null> =>
  new Promise((resolve, reject) => {
    Office.context.document.customXmlParts.getByIdAsync(id, (result) => {
      if (result.status === Office.AsyncResultStatus.Failed) {
        reject(result.error);
        return;
      }
      resolve(result.value);
    });
  });

/**
 * 读取自定义XML部件值的辅助函数
 **/
export const xmlPartRead = (
  xmlPart: Office.CustomXmlPart | Office.CustomXmlNode,
): Promise<string> =>
  new Promise((resolve, reject) => {
    xmlPart.getXmlAsync((result) => {
      if (result.status === Office.AsyncResultStatus.Failed) {
        reject(result.error);
        return;
      }
      resolve(result.value);
    });
  });

/**
 * 从文档中移除自定义XML部件的辅助函数
 **/
export const xmlPartRemove = (xmlPart: Office.CustomXmlPart): Promise<void> =>
  new Promise((resolve, reject) => {
    xmlPart.deleteAsync((result) => {
      if (result.status === Office.AsyncResultStatus.Failed) {
        reject(result.error);
        return;
      }
      resolve();
    });
  });

/**
 * 显示之前隐藏的Content Control(如上述操作)
 **/
Word.run(async (context) => {
  // 找到要显示的Content Control - 假设已知其ID
  const contentControl = context.document.contentControls.getById(contentControlId);
  context.load(contentControl, ['appearance', 'tag', 'title']);
  await context.sync();
  // 获取要插入到Content Control中的OOXML
  const xmlPartId = documentSettingGet<string>(`block-xml-part-id-${contentControl.tag}`);
  const xmlPart = await xmlPartGet(xmlPartId);
  if (xmlPart) {
    const xml = await xmlPartRead(xmlPart);
    contentControl.cannotEdit = false;
    await context.sync();
    contentControl.insertOoxml(value, Word.InsertLocation.replace);
    contentControl.appearance = Word.ContentControlAppearance.boundingBox;
    await context.sync();
    // 使用完毕后移除XML部件
    await xmlPartRemove(xmlPart);
  }
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 03:27:06