如何解决Google Apps Script生成Gmail时模板格式丢失的问题
解决方案
核心原因
- 现有代码调用
Document.getText()仅提取纯文本内容,Google Doc中设置的所有格式会被直接剥离 - 调用
GmailApp.createDraft()时仅传入了纯文本正文,未指定HTML格式的邮件内容,邮箱仅会渲染无格式文本
修改步骤
1. 新增Google Doc转HTML的工具方法
将Google Doc模板导出为HTML格式,保留所有原始格式(加粗、下划线、表格、段落样式等)
2. 调整占位符替换逻辑,适配HTML格式的模板
3. 修改邮件创建参数,传入HTML正文
完整修改后的代码
// What is the Google Document ID for your email template? var googleDocId = "<my id>"; // Which column has the email address? Enter the column row header exactly. var emailField = 'email'; // What is the subject line? var emailSubject = 'Weekly Engagement Indicator'; // Which column is the indicator for email drafted? Enter the column row header exactly. var emailStatus = 'date drafted'; /* ----------------------------------- */ // Be careful editing beyond this line // /* ----------------------------------- */ var sheet = SpreadsheetApp.getActiveSheet(); // Use data from the active sheet function draftMyEmails() { // 替换原有getText(),改为获取HTML格式的模板 var emailTemplate = getDocAsHtml(googleDocId); var data = getCols(2, sheet.getLastRow() - 1); var myVars = getCols(1, 1)[0]; var draftedRow = myVars.indexOf(emailStatus) + 1; // Work through each data row in the spreadsheet data.forEach(function(row, index){ // Build a configuration for each row var config = createConfig(myVars, row); // Prevent from drafing duplicates and from drafting emails without a recipient if (config[emailStatus] === '' && config[emailField]) { // Replace template variables with the receipient's data var emailBodyHtml = replaceTemplateVars(emailTemplate, config); // 生成纯文本备用版本(不支持HTML的邮箱会显示这个) var emailBodyPlain = replaceTemplateVars(DocumentApp.openById(googleDocId).getText(), config); // Replace template variables in subject line var emailSubjectUpdated = replaceTemplateVars(emailSubject, config); // Create the email draft,新增htmlBody参数 GmailApp.createDraft( config[emailField], // Recipient emailSubjectUpdated, // Subject emailBodyPlain, // 纯文本备用正文 { htmlBody: emailBodyHtml // HTML格式正文 } ); sheet.getRange(2 + index, draftedRow).setValue(new Date()); // Update the last column SpreadsheetApp.flush(); // Make sure the last cell is updated right away } }); } // 新增:将Google Doc导出为HTML格式 function getDocAsHtml(docId) { var url = "https://docs.google.com/feeds/download/documents/export/Export?id=" + docId + "&exportFormat=html"; var param = { method: "get", headers: {"Authorization": "Bearer " + ScriptApp.getOAuthToken()}, muteHttpExceptions: true, }; var html = UrlFetchApp.fetch(url, param).getContentText(); // 可选:清理Google Doc导出的冗余HTML代码,减少邮件体积 html = html.replace(/<meta.*?>|<style.*?>[\s\S]*?<\/style>/g, ""); return html; } function replaceTemplateVars(string, config) { return string.replace(/{[^{}]+}/g, function(key){ return config[key.replace(/[{}]+/g, "")] || ""; }); } function createConfig(myVars, row) { return myVars.reduce(function(obj, myVar, index) { obj[myVar] = row[index]; return obj; }, {}); } function getCols(startRow, numRows) { var lastColumn = sheet.getLastColumn(); // Last column var dataRange = sheet.getRange(startRow, 1, numRows, lastColumn) // Fetch the data range of the active sheet return dataRange.getValues(); // Fetch values for each row in the range }
注意事项
- 第一次运行修改后的代码时,会请求额外的Drive访问权限,同意授权即可
- 直接在Google Doc模板中设置所有你需要的格式(加粗、下划线、插入表格、调整字体颜色等),导出为HTML后都会自动保留
- 如果出现占位符替换失效的情况,检查模板中的占位符
{xxx}是否为连续输入的无格式文本,不要给占位符本身单独设置格式即可解决
内容的提问来源于stack exchange,提问作者smcodemeister
相关产品推荐
相关产品推荐

