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

Google Docs插件替换文本时如何保留原格式?

解决Google Docs插件替换文本丢失格式的问题

问题根源

问题出在replaceSelectedTextWithAPI方法里的replaceText调用。DocumentApp的replaceText方法会直接替换指定文本内容,同时清除该文本段的原有格式(加粗、颜色、高亮等),因为它是基于字符串匹配的替换操作,不处理格式信息。getSelectedText方法仅负责提取选中文本内容,和格式丢失无关。

解决方案:保留选区格式的替换方式

要保留原格式,需要先提取选中文本的格式属性,再将新文本插入到原位置并应用这些格式,具体步骤:

  1. 遍历选中的每个元素,获取选区的起始/结束位置
  2. 删除原选中的文本内容
  3. 在原位置插入新的替换文本
  4. 为新插入的文本复制原选区的所有格式属性

修改后的replaceSelectedTextWithAPI方法代码如下:

function replaceSelectedTextWithAPI(apiEndpoint) {  
  try {
    const selectedText = getSelectedText().join("");
    const replacement = callAPIWithSelected(apiEndpoint);
    
    const doc = DocumentApp.getActiveDocument();
    const selection = doc.getSelection();
    if (!selection) return;

    const elements = selection.getSelectedElements();
    // 逆序处理选区元素,避免索引偏移问题
    for (let i = elements.length - 1; i >= 0; --i) {
      const elementObj = elements[i];
      const element = elementObj.getElement();
      
      if (!element.editAsText) continue;
      
      const textElement = element.asText();
      let startIndex, endIndex;

      if (elementObj.isPartial()) {
        startIndex = elementObj.getStartOffset();
        endIndex = elementObj.getEndOffsetInclusive();
      } else {
        startIndex = 0;
        endIndex = textElement.getText().length - 1;
      }

      // 提取原选区的格式属性
      const formatProps = {
        bold: textElement.isBold(startIndex),
        italic: textElement.isItalic(startIndex),
        underline: textElement.isUnderline(startIndex),
        strikethrough: textElement.isStrikethrough(startIndex),
        foregroundColor: textElement.getForegroundColor(startIndex),
        backgroundColor: textElement.getBackgroundColor(startIndex),
        fontSize: textElement.getFontSize(startIndex),
        fontFamily: textElement.getFontFamily(startIndex)
      };

      // 删除原选中的文本
      textElement.deleteText(startIndex, endIndex);
      // 插入新文本
      textElement.insertText(startIndex, replacement);

      // 计算新文本的结束索引
      const newEndIndex = startIndex + replacement.length - 1;
      // 应用原格式到新文本
      if (formatProps.bold !== null) textElement.setBold(startIndex, newEndIndex, formatProps.bold);
      if (formatProps.italic !== null) textElement.setItalic(startIndex, newEndIndex, formatProps.italic);
      if (formatProps.underline !== null) textElement.setUnderline(startIndex, newEndIndex, formatProps.underline);
      if (formatProps.strikethrough !== null) textElement.setStrikethrough(startIndex, newEndIndex, formatProps.strikethrough);
      if (formatProps.foregroundColor) textElement.setForegroundColor(startIndex, newEndIndex, formatProps.foregroundColor);
      if (formatProps.backgroundColor) textElement.setBackgroundColor(startIndex, newEndIndex, formatProps.backgroundColor);
      if (formatProps.fontSize) textElement.setFontSize(startIndex, newEndIndex, formatProps.fontSize);
      if (formatProps.fontFamily) textElement.setFontFamily(startIndex, newEndIndex, formatProps.fontFamily);
    }
  } catch (error) {
    throw new Error('Error replacing selected text: ' + error.message);
  }
}

关键说明

  • 逆序处理选区元素:因为删除和插入文本会改变元素的索引,从后往前处理可以避免前面的操作影响后续元素的位置。
  • 提取格式属性:这里仅提取了常见的格式(加粗、斜体等),如果需要支持更多格式(比如上标、下标),可以添加对应的get方法获取属性,再用set方法应用。
  • 格式空值判断:部分格式属性可能返回null(比如未设置颜色时),需要判断后再应用,避免覆盖默认格式。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 06:25:37