【问题标题】:How to convert formatted text to html tag in Google-apps-script?如何在 Google-apps-script 中将格式化文本转换为 html 标签?
【发布时间】:2017-06-13 10:31:39
【问题描述】:

我想将单元格中的格式化文本转换为 html,但我不知道如何读取文本的格式。

假设我在一个单元格中有以下文本: 带有粗体字词的文本。

我想在另一个单元格中将其转换为: 带有<b>bold</b> 字样的文本。

我该怎么做?

我没有在电子表格 API 中找到任何有用的信息来读取格式信息...有没有人有任何提示? 谢谢。

编辑:我创建了一个feature request。请投票以使用该功能。

【问题讨论】:

标签: google-apps-script google-sheets


【解决方案1】:

我的 Google 脚本

/**
 * Rich Text to HTML.
 * @param {string} qRange Input text.
 * @returns {string} Text as HTML.
 * @customfunction
 */
function RICHTEXT_TO_HTML(qRange) {
  var indexBool = false;
  var indexItalic = false;
  var indexUnderline = false;
  var indexStrikethrough = false;

  var sheet = SpreadsheetApp.getActiveSpreadsheet();
  var range = sheet.getRange(qRange);
  var cell = range;
  var cellValue = cell.getRichTextValue();
  var txt = String(cell.getDisplayValue());
  var styles = cell.getTextStyles();
  var result = '';

  for (var i = 0; i < txt.length; i++) {
    var style = cellValue.getTextStyle(i, i + 1);

    if (!indexStrikethrough && style.isStrikethrough()) {
      indexStrikethrough = true;
      result += '<strike>';
    } else if (indexStrikethrough && !style.isStrikethrough()) {
      indexStrikethrough = false;
      result += '</strike>';
    }

    if (!indexUnderline && style.isUnderline()) {
      indexUnderline = true;
      result += '<u>';
    } else if (indexUnderline && !style.isUnderline()) {
      indexUnderline = false;
      result += '</u>';
    }

    if (!indexBool && style.isBold()) {
      indexBool = true;
      result += '<b>';
    } else if (indexBool && !style.isBold()) {
      indexBool = false;
      result += '</b>';
    }

    if (!indexItalic && style.isItalic()) {
      indexItalic = true;
      result += '<i>';
    } else if (indexItalic && !style.isItalic()) {
      indexItalic = false;
      result += '</i>';
    }

    result += txt[i];
  }

  if (indexStrikethrough) {
    result += '</strike>';
  }

  if (indexUnderline) {
    result += '</u>';
  }

  if (indexBool) {
    result += '</b>';
  }

  if (indexItalic) {
    result += '</i>';
  }

  return result;
}

用法

  • A1 = "我的格式化 示例!!!"
  • A2 = =RICHTEXT_TO_HTML("A1")
  • A2 结果 = My &lt;i&gt;formatted&lt;/i&gt; &lt;b&gt;example&lt;/b&gt;!!!

工作示例

https://docs.google.com/spreadsheets/d/1mVvE8AdXYKSnaSIfRBrjfOeXxmTkVZovhguMZ3sc47M/edit?usp=sharing

【讨论】:

  • 非常感谢您。你认为有可能得到颜色和字体吗?
【解决方案2】:

我继续更新了这个想法,以更好地反映我们在 2021 年如何做到这一点。

/**
 * @Author: Emma Sargent
 * Rich Text to HTML.
 * @param {Range} Google Sheets Range object
 * @returns {string} Text as HTML.
 * @customfunction
 */
function richTextToHtml(range) {
  const runs = range.getRichTextValue().getRuns();
  const formattedRuns = runs.map((run) => {
    const attr = {
      style: '',
    };
    const text = run.getText();
    const link = run.getLinkUrl();
    let parentTag = 'span';
    if (link) {
      parentTag = 'a';
      attr.href = link;
    }

    const style = run.getTextStyle();
    const styles = {
      'font-family': `'${style.getFontFamily()}'`,
      'font-size': `${style.getFontSize()}px`,
      color: style.getForegroundColor(),
    };
    attr.style = Object.entries(styles)
      .map(([key, val]) => `${key}: ${val}`)
      .join('; ');

    let tags = [];
    if (style.isBold()) {
      tags.push('b');
    }
    if (style.isItalic()) {
      tags.push('i');
    }
    if (style.isUnderline()) {
      tags.push('u');
    }
    if (style.isStrikethrough()) {
      tags.push('strike');
    }
    const headTags = tags.length ? `<${tags.join('><')}>` : '';
    const closeTags = tags.length ? `</${tags.join('></')}>` : '';
    const attrStr = Object.entries(attr)
      .map(([key, val]) => `${key}="${val}"`)
      .join(' ');

    const mainTag = `<${parentTag} ${attrStr}>${headTags}${text}${closeTags}</${parentTag}>`;
    const lineBreakFormattedStr = mainTag.replace(/[\r\n]/g, '<br>');
    return lineBreakFormattedStr;
  });

  return formattedRuns.join('');
}

因为有人给我发邮件询问,这里有一个可以作为自定义函数从公式栏中运行的版本。

电子表格公式:=richTextToHtml("YourSheetName!A1NotationRange")

function richTextToHtml(rangeStr) {
  let [sheetName, rangeName] = rangeStr.split("!");
  sheetName = sheetName.replaceAll("'",'');
  const range = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(sheetName).getRange(rangeName);
  const runs = range.getRichTextValue().getRuns();
  const formattedRuns = runs.map((run) => {
    const attr = {
      style: '',
    };
    const text = run.getText();
    const link = run.getLinkUrl();
    let parentTag = 'span';
    if (link) {
      parentTag = 'a';
      attr.href = link;
    }

    const style = run.getTextStyle();
    const styles = {
      'font-family': `'${style.getFontFamily()}'`,
      'font-size': `${style.getFontSize()}px`,
      color: style.getForegroundColor(),
    };
    attr.style = Object.entries(styles)
      .map(([key, val]) => `${key}: ${val}`)
      .join('; ');

    let tags = [];
    if (style.isBold()) {
      tags.push('b');
    }
    if (style.isItalic()) {
      tags.push('i');
    }
    if (style.isUnderline()) {
      tags.push('u');
    }
    if (style.isStrikethrough()) {
      tags.push('strike');
    }
    const headTags = tags.length ? `<${tags.join('><')}>` : '';
    const closeTags = tags.length ? `</${tags.join('></')}>` : '';
    const attrStr = Object.entries(attr)
      .map(([key, val]) => `${key}="${val}"`)
      .join(' ');

    const mainTag = `<${parentTag} ${attrStr}>${headTags}${text}${closeTags}</${parentTag}>`;
    const lineBreakFormattedStr = mainTag.replace(/[\r\n]/g, '<br>');
    return lineBreakFormattedStr;
  });

  return formattedRuns.join('');
}

演示表在这里:https://docs.google.com/spreadsheets/d/1X8I_lRXwoUXWRKb2hZPztDIPRs2nmXGtOuWmnrKWjAg/edit?usp=sharing

【讨论】:

    【解决方案3】:

    您需要使用 Range 的 getFontWeight 属性来读取这些格式化值。此处给出的示例:GAS-check-cell-format

    检查 Rucent88 的答案。

    【讨论】:

    • 如果单元格有混合格式,这会起作用吗?例如“这是我的 cell 内容”,这可能是我阅读 OP 的方式。
    • 正如@Karl_S 指出的那样,这不适用于混合格式。我需要获取格式的开始索引和结束索引才能添加 html 标记。
    • +1 据我所知,对于具有混合格式的单元格,无法获取此类信息。 1个月前,我自己对此进行了广泛搜索,但没有任何运气。
    • 感谢您的回答。我在这里为谷歌创建了一个功能请求:code.google.com/p/google-apps-script-issues/issues/…
    【解决方案4】:

    感谢 Eduardo Cuomo 的回答。我想添加代码以通过一些小修复来达到底线。

    /**
     * @Author: Eduardo Cuomo 
     * Rich Text to HTML.
     * @param {string} qRange Input text.
     * @returns {string} Text as HTML.
     * @customfunction
     */
    
    function RICHTEXT_TO_HTML(qRange) {
      var indexBool = false;
      var indexItalic = false;
      var indexUnderline = false;
      var indexStrikethrough = false;
      
      var sheet = SpreadsheetApp.getActiveSpreadsheet();
      var range = sheet.getRange(qRange);
      var cell = range;
      var cellValue = cell.getRichTextValue();
      var txt = String(cell.getDisplayValue());
      var styles = cell.getTextStyles();
      var result = '';
      
      for (var i = 0; i < txt.length; i++) {
        if(txt[i]=="\n"){
          result += '<br>';
        }else{
        var style = cellValue.getTextStyle(i, i + 1);
        
        if (!indexStrikethrough && style.isStrikethrough()) {
          indexStrikethrough = true;
          result += '<strike>';
        } else if (indexStrikethrough && !style.isStrikethrough()) {
          indexStrikethrough = false;
          result += '</strike>';
        }
        
        if (!indexUnderline && style.isUnderline()) {
          indexUnderline = true;
          result += '<u>';
        } else if (indexUnderline && !style.isUnderline()) {
          indexUnderline = false;
          result += '</u>';
        }
        
        if (!indexBool && style.isBold()) {
          indexBool = true;
          result += '<b>';
        } else if (indexBool && !style.isBold()) {
          indexBool = false;
          result += '</b>';
        }
        
        if (!indexItalic && style.isItalic()) {
          indexItalic = true;
          result += '<i>';
        } else if (indexItalic && !style.isItalic()) {
          indexItalic = false;
          result += '</i>';
        }
        
        result += txt[i];
        }
      }
      
      if (indexStrikethrough) {
        result += '</strike>';
      }
      
      if (indexUnderline) {
        result += '</u>';
      }
      
      if (indexBool) {
        result += '</b>';
      }
      
      if (indexItalic) {
        result += '</i>';
      }
      
      return result;
    }
    

    【讨论】:

      【解决方案5】:

      这是一个创建更紧凑 HTML 的版本(避免大量跨度设置样式):

      function richTextToHtml(range) {
        let lastFont = null, lastSize = null, lastColor = null, lastLink = null;
        let parentClose = '';
      
        return range.getRichTextValue()
            .getRuns()
            .map(run => {
              const text = run.getText().replace(/[\r\n]/g, '<br>');
              const style = run.getTextStyle();
              const font = style.getFontFamily();
              const size = style.getFontSize();
              const color = style.getForegroundColor();
              const link = run.getLinkUrl();
      
              let mainTag = '';
              if (font !== lastFont || size !== lastSize || color !== lastColor || link !== lastLink) {
                mainTag += parentClose;
                mainTag += link ? `<a href="${link}"` : '<span';
                mainTag +=
                    ` style="font-family:'${font}';font-size:${size}px;color:${color}">`;
                parentClose = link ? '</a>' : '</span>';
                lastFont = font;
                lastSize = size;
                lastColor = color;
                lastLink = link;
              }
      
              let closeTags = '';
              Object.entries({isBold: 'b', isItalic: 'i', isUnderline: 'u', isStrikethrough: 'strike'})
                  .filter(([getter, tag]) => style[getter]())
                  .forEach(([getter, tag]) => {
                    mainTag += `<${tag}>`;
                    closeTags = `</${tag}>${closeTags}`;
                  });
      
              return `${mainTag}${text}${closeTags}`;
            })
            .join('') + parentClose;
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2018-03-06
        • 2021-11-04
        • 1970-01-01
        • 1970-01-01
        • 2015-11-20
        • 1970-01-01
        • 2012-09-05
        相关资源
        最近更新 更多