Google Apps Script从Gmail子标签导入CSV至表格的异常排查与优化
解决Google Apps Script自动化报表的两个异常:未获取最新附件/CSV数据丢失
针对你遇到的两个问题,以下是修改后的脚本及关键调整说明:
修改后的完整代码
function automatedReportsGAM() { var labelName = 'MY_GMAIL_LABEL_NAME'; var spreadsheetId = '1l6qtLINKCTLkxl0WqUjmCxb8VSZynQ7jJtJqwni5JGA'; var sheetName = 'RAW 2023 DATA'; // 获取Gmail标签 var label = GmailApp.getUserLabelByName(labelName); if (!label) { Logger.log('未找到指定标签: ' + labelName); return; } // 获取标签下所有线程,按时间升序排列(最新线程在最后) var threads = label.getThreads(); if (threads.length === 0) { Logger.log('该标签下无邮件'); return; } // 修正:线程内的消息默认按时间升序,取最后一个元素才是线程里的最新邮件 var latestThread = threads[threads.length - 1]; var messages = latestThread.getMessages(); var latestEmail = messages[messages.length - 1]; // 获取最新邮件的所有附件 var attachments = latestEmail.getAttachments(); // 修正:通过文件扩展名识别CSV,替代不准确的contentType判断 var csvAttachment = attachments.find(att => att.getFileName().toLowerCase().endsWith('.csv')); if (!csvAttachment) { Logger.log('最新邮件中未找到CSV附件'); return; } // 处理CSV可能的UTF-8 BOM头,避免解析时丢失首行或出现格式错误 var csvData = csvAttachment.getDataAsString(); if (csvData.startsWith('\ufeff')) { csvData = csvData.substring(1); } // 解析CSV数据 var parsedCsvData = Utilities.parseCsv(csvData); if (parsedCsvData.length === 0) { Logger.log('CSV文件无有效数据'); return; } // 打开目标表格和工作表 var spreadsheet = SpreadsheetApp.openById(spreadsheetId); var sheet = spreadsheet.getSheetByName(sheetName); if (!sheet) { Logger.log('未找到指定工作表: ' + sheetName); return; } // 修正:清空A-K列的所有行(从第1行到表格最大行),避免旧数据残留 var maxRows = sheet.getMaxRows(); sheet.getRange(1, 1, maxRows, 11).clearContent(); // 将解析后的CSV写入A-K列 sheet.getRange(1, 1, parsedCsvData.length, parsedCsvData[0].length).setValues(parsedCsvData); // 获取A-K列的最后数据行 var lastDataRow = sheet.getLastRow(); // 如果只有表头,无需填充公式 if (lastDataRow < 2) { Logger.log('仅导入表头,无需填充公式'); return; } // 获取L-R列第2行的公式(R1C1格式) var formulaRange = sheet.getRange(2, 12, 1, sheet.getLastColumn() - 11); var formulas = formulaRange.getFormulasR1C1()[0]; // 填充公式到对应行 var fillRange = sheet.getRange(2, 12, lastDataRow - 1, formulas.length); fillRange.setFormulasR1C1(Array(lastDataRow - 1).fill(formulas)); }
关键调整说明
- 修复最新邮件获取逻辑:线程内的消息默认按时间升序存储,原代码取
getMessages()[0]是线程里最早的邮件,改为取messages[messages.length - 1]才能拿到线程内的最新邮件,确保获取到最新的CSV附件。 - 改用文件扩展名识别CSV:替代原有的
application/octet-stream判断,通过getFileName().toLowerCase().endsWith('.csv')更准确识别CSV文件,避免因contentType标记错误漏判附件。 - 处理CSV BOM头:部分CSV文件会带UTF-8 BOM头(
\ufeff),导致Utilities.parseCsv解析时出现格式错误或丢失行,新增代码去除BOM头后再解析。 - 优化A-K列清空逻辑:原代码只清空到之前的
getLastRow(),如果新CSV行数少于旧数据行数,会残留旧数据;改为清空到表格getMaxRows(),确保A-K列完全清空。 - 公式填充边界处理:新增判断如果CSV只有表头(
lastDataRow < 2),则跳过公式填充,避免数组越界错误。
内容的提问来源于stack exchange,提问作者avaf
相关产品推荐
相关产品推荐

