如何设置Google Sheets脚本仅为新增行生成PDF
解决Google Sheets批量生成PDF重复生成问题
问题说明
在Google Sheets中配置了「新增数据后从模板生成PDF」的功能,但当前脚本每次新增行时,会为所有行重新生成PDF,产生大量重复文件。核心问题是原代码遍历了表格中所有数据行,未区分已处理和未处理的行。
修改方案
通过添加状态标记列跟踪已生成PDF的行,仅处理未标记的新增行:
- 在表格新增一列(比如第25列,标题设为「PDF生成状态」):
- 未处理的行该列为空
- 已成功生成PDF的行标记为
Done - 生成失败的行标记为
Failed
- 修改脚本,仅遍历状态列为空的行,处理完成后更新状态列。
修改后的完整代码
function createBulkPDFs(){ const docFile = DriveApp.getFileById("你的文档模板ID"); const tempFolder = DriveApp.getFolderById("临时文件夹ID"); const pdfFolder = DriveApp.getFolderById("PDF存储文件夹ID"); const currentSheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Hoja 1"); // 获取包含状态列(第25列)的所有数据行 const dataRange = currentSheet.getRange(2, 1, currentSheet.getLastRow()-1, 25); const data = dataRange.getValues(); const statusUpdates = []; data.forEach(row => { // 仅处理第25列(索引24)为空的未生成PDF行 if (!row[24]) { try{ createPDF( row[2], row[3], row[4], row[8], row[9], row[16], row[17], row[18], row[19], "manny"+row[2], docFile, tempFolder, pdfFolder ); statusUpdates.push(["Done"]); }catch(err){ statusUpdates.push(["Failed"]); } } else { // 已处理的行保留原有状态 statusUpdates.push([row[24]]); } }); // 更新状态列(第25列) currentSheet.getRange(2, 25, statusUpdates.length, 1).setValues(statusUpdates); } function createPDF(cliente, cotizacion, atencion, ciudad, fecha, manoDeObra, traslados, materiales, total, pdfName, docFile, tempFolder, pdfFolder) { const tempFile = docFile.makeCopy(tempFolder); const tempDocFile = DocumentApp.openById(tempFile.getId()); const body = tempDocFile.getBody(); body.replaceText("{Cliente}", cliente); body.replaceText("{Cotizacion}", cotizacion); body.replaceText("{Atencion}", atencion); body.replaceText("{Ciudad}", ciudad); body.replaceText("{Fecha}", fecha); body.replaceText("{ManoDeObra}", manoDeObra); body.replaceText("{Traslados}", traslados); body.replaceText("{Material}", materiales); body.replaceText("{Total}", total); tempDocFile.saveAndClose(); const pdfContentBlob = tempFile.getAs(MimeType.PDF); pdfFolder.createFile(pdfContentBlob).setName(pdfName); tempFolder.removeFile(tempFile); }
可选优化:自动触发生成
如果希望新增行后自动生成PDF,可添加onEdit触发器:
function onEdit(e) { const sheet = e.source.getActiveSheet(); if (sheet.getName() !== "Hoja 1") return; // 假设新增行时会填写第2列(Cliente),编辑该列时触发检查 if (e.range.columnStart === 2 && e.value) { const row = e.range.rowStart; const statusCol = 25; // 仅处理未生成PDF的行 if (!sheet.getRange(row, statusCol).getValue()) { const docFile = DriveApp.getFileById("你的文档模板ID"); const tempFolder = DriveApp.getFolderById("临时文件夹ID"); const pdfFolder = DriveApp.getFolderById("PDF存储文件夹ID"); const rowData = sheet.getRange(row, 1, 1, 24).getValues()[0]; try { createPDF( rowData[2], rowData[3], rowData[4], rowData[8], rowData[9], rowData[16], rowData[17], rowData[18], rowData[19], "manny"+rowData[2], docFile, tempFolder, pdfFolder ); sheet.getRange(row, statusCol).setValue("Done"); } catch(err) { sheet.getRange(row, statusCol).setValue("Failed"); } } } }
内容的提问来源于stack exchange,提问作者Luis Velazquez
相关产品推荐
相关产品推荐

