如何在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
相关产品推荐
相关产品推荐

