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

如何在Google App Script中使用Juice CSS Inliner修复邮件格式

解决Google Apps Script中Gmail邮件HTML格式丢失问题(使用Juice内联CSS)

实现步骤

  • 第一步:添加Juice的适配代码到GAS项目
    Google Apps Script无法直接安装npm包,我们可以使用简化适配后的Juice核心逻辑,将其作为独立脚本文件(命名为Juice.gs)加入项目。
  • 第二步:修改原有函数,加入CSS内联处理
    在获取Google文档的HTML后,调用Juice逻辑将CSS内联到元素属性中,再用处理后的HTML发送邮件。

完整代码

首先创建Juice.gs文件,粘贴以下适配代码:

// Juice CSS内联工具的简化适配版本(适配Google Apps Script环境)
function juice(html, options = {}) {
  const doc = XmlService.parse(html);
  const root = doc.getRootElement();
  
  // 提取<style>标签中的CSS内容
  const styleElements = root.getDescendants().filter(elem => elem.getType() === XmlService.ElementType.ELEMENT && elem.getName() === 'style');
  let css = '';
  styleElements.forEach(styleElem => {
    css += styleElem.getText();
    styleElem.getParentElement().removeContent(styleElem);
  });
  
  // 解析CSS规则
  const rules = parseCSS(css);
  
  // 遍历元素并应用内联样式
  const elements = root.getDescendants().filter(elem => elem.getType() === XmlService.ElementType.ELEMENT);
  elements.forEach(elem => {
    const matchingRules = rules.filter(rule => matchesSelector(elem, rule.selector));
    
    let inlineStyle = elem.getAttribute('style') ? elem.getAttribute('style').getValue() : '';
    matchingRules.forEach(rule => {
      inlineStyle += (inlineStyle ? ';' : '') + rule.declarations.join(';');
    });
    
    if (inlineStyle) {
      elem.setAttribute('style', inlineStyle.trim());
    }
  });
  
  return XmlService.getPrettyFormat().format(doc);
}

// 简化CSS解析函数,支持基础选择器
function parseCSS(css) {
  return css.replace(/\/\*[\s\S]*?\*\//g, '')
            .split('}')
            .filter(rule => rule.trim())
            .map(rule => {
              const [selectorPart, declarationsPart] = rule.split('{');
              const selector = selectorPart.trim();
              const declarations = declarationsPart.trim().split(';').filter(d => d.trim()).map(d => d.trim());
              return { selector, declarations };
            });
}

// 生成元素的匹配选择器
function getElementSelector(elem) {
  let selector = elem.getName();
  const id = elem.getAttribute('id');
  if (id) selector += `#${id.getValue()}`;
  const className = elem.getAttribute('class');
  if (className) selector += `.${className.getValue().split(' ').join('.')}`;
  return selector;
}

// 基础选择器匹配逻辑
function matchesSelector(elem, selector) {
  // 匹配标签选择器
  if (selector === elem.getName()) return true;
  
  // 匹配ID选择器
  if (selector.startsWith('#')) {
    const elemId = elem.getAttribute('id');
    return elemId && elemId.getValue() === selector.slice(1);
  }
  
  // 匹配类选择器
  if (selector.startsWith('.')) {
    const elemClass = elem.getAttribute('class');
    if (!elemClass) return false;
    const classes = elemClass.getValue().split(' ');
    return classes.includes(selector.slice(1));
  }
  
  // 匹配简单复合选择器(如div.class)
  const parts = selector.split('.');
  if (parts.length === 2) {
    const tag = parts[0];
    const cls = parts[1];
    if (elem.getName() !== tag) return false;
    const elemClass = elem.getAttribute('class');
    return elemClass && elemClass.getValue().split(' ').includes(cls);
  }
  
  return false;
}

然后修改原有的doc2html函数:

function doc2html(googleDocId){
  const exporturl = `https://docs.google.com/feeds/download/documents/export/Export?id=${googleDocId}&exportFormat=html`;
  
  const fetchParam = {
    method: "get",
    headers: {
      "Authorization": "Bearer " + ScriptApp.getOAuthToken()
    },
    muteHttpExceptions: true
  };

  let finalhtml = UrlFetchApp.fetch(exporturl, fetchParam).getContentText();
  
  // 用Juice处理HTML,内联CSS样式
  const inlinedHtml = juice(finalhtml);
  
  // 发送邮件,使用内联后的HTML内容
  GmailApp.sendEmail('目标邮箱地址', '邮件主题', '请使用支持HTML的邮件客户端查看', { htmlBody: inlinedHtml });
}

注意事项

  • 上述适配版Juice仅支持基础CSS选择器(标签、ID、类、简单复合选择器),若需复杂样式支持,可替换为官方完整UMD版本代码。
  • Google文档导出的HTML可能包含特殊格式,建议测试发送后确认效果。
  • 确保GAS项目已启用UrlFetchApp和GmailApp的相关权限。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 04:45:45