Google Apps Script仅导出勾选行到PDF:多文件与全行导出问题修复
问题描述
我在Google Apps Script中实现了一个函数,目标如下:
- 识别A列中Checkbox值为True(已勾选)的行
- 将仅勾选的行导出为单个PDF文件
- 仅将指定单元格区域C4:J803加入PDF,排除A列
当前遇到的问题:点击按钮后,Google Drive中生成多个PDF副本,且PDF包含所有行(勾选与未勾选)
现有代码
/* @OnlyCurrentDoc */ function exportRangeToPDf(range) { var ui = SpreadsheetApp.getUi(); var response=ui.alert("Export row(s) to PDF", "Export the Selected Row(s) to PDF?", ui.ButtonSet.YES_NO); //checking the user response if(response==ui.Button.NO) { return; //exit from this function } var blob,exportUrl,options,pdfFile,response,sheetTabNameToGet,sheetTabId,ss,ssID,url_base; pdf_range = range ? range : "C4:J803"; sheetTabNameToGet = "Bldg Condition";//Replace the name with the sheet tab name for your situation ss = SpreadsheetApp.getActiveSpreadsheet();//This assumes that the Apps Script project is bound to a G-Sheet ssID = ss.getId(); sh = ss.getSheetByName(sheetTabNameToGet); sheetTabId = sh.getSheetId(); url_base = ss.getUrl().replace(/edit$/,''); var sheet = SpreadsheetApp.getActive(); var dataRange = sheet.getRange("A4:A805"); var values = dataRange.getValues(); for (var i = 0; i < values.length; i++) { var row = values[i]; var checkbox = row[0]; // Assuming checkbox is in column A (0-based index) if(sh.getName() == "Bldg Condition" && checkbox == true) { exportUrl = url_base + 'export?exportFormat=pdf&format=pdf' + '&gid=' + sheetTabId + '&id=' + ssID + '&range=' + pdf_range + //'&range=NamedRange + '&size=A4' + // paper size '&portrait=true' + // orientation, false for landscape '&fitw=true' + // fit to width, false for actual size '&sheetnames=true&printtitle=false&pagenumbers=true' + //hide optional headers and footers '&gridlines=false' + // hide gridlines '&fzr=false'; // do not repeat row headers (frozen rows) on each page //Logger.log('exportUrl: ' + exportUrl) options = { headers: { 'Authorization': 'Bearer ' + ScriptApp.getOAuthToken(), } } options.muteHttpExceptions = true;//Make sure this is always set response = UrlFetchApp.fetch(exportUrl, options); //Logger.log(response.getResponseCode()) if (response.getResponseCode() !== 200) { console.log("Error exporting Sheet to PDF! Response Code: " + response.getResponseCode()); return; } blob = response.getBlob(); blob.setName('Bldg_Condition.pdf') pdfFile = DriveApp.createFile(blob);//Create the PDF file //Logger.log('pdfFile ID: ' +pdfFile.getId()) }} ss.toast("PDF file has been added to your Google Drive folder!") }
补充说明:在名为“Bldg Condition”的电子表格标签页中,用户可通过勾选Checkbox指定需显示在报告中的行。点击“导出到PDF”按钮后,应仅生成1个PDF文件保存至Google Drive。已搜索相关问题,但仅找到OnEdit(简单触发器)示例,未找到按钮触发的相关方案。
解决方案
问题根源
- 多PDF副本:原代码在
for循环内每次遍历到勾选行就执行一次PDF导出和文件创建,导致每有一个勾选行就生成一个PDF。 - PDF包含所有行:导出时固定使用
C4:J803作为范围,没有筛选出仅勾选的行,所以导出的是整个区域内容。
修改后的代码
/* @OnlyCurrentDoc */ function exportSelectedRowsToPDF() { const ui = SpreadsheetApp.getUi(); const response = ui.alert("Export row(s) to PDF", "Export the Selected Row(s) to PDF?", ui.ButtonSet.YES_NO); if (response === ui.Button.NO) return; const sheetName = "Bldg Condition"; const ss = SpreadsheetApp.getActiveSpreadsheet(); const sh = ss.getSheetByName(sheetName); const ssID = ss.getId(); const sheetTabId = sh.getSheetId(); const urlBase = ss.getUrl().replace(/edit$/, ''); // 获取A列勾选状态,收集选中行的行号 const checkRange = sh.getRange("A4:A805"); const checkValues = checkRange.getValues(); const selectedRows = []; for (let i = 0; i < checkValues.length; i++) { if (checkValues[i][0] === true) { // 原始范围从第4行开始,实际行号为i+4 selectedRows.push(i + 4); } } if (selectedRows.length === 0) { ui.alert("No rows selected! Please check at least one checkbox."); return; } // 构建包含所有选中行的范围参数 let rangeParams = ''; selectedRows.forEach(row => { rangeParams += `&range=C${row}:J${row}`; }); // 构建PDF导出URL const exportUrl = `${urlBase}export?exportFormat=pdf&format=pdf` + `&gid=${sheetTabId}&id=${ssID}` + rangeParams + '&size=A4' + '&portrait=true' + '&fitw=true' + '&sheetnames=true&printtitle=false&pagenumbers=true' + '&gridlines=false' + '&fzr=false'; const options = { headers: { 'Authorization': `Bearer ${ScriptApp.getOAuthToken()}` }, muteHttpExceptions: true }; const responseFetch = UrlFetchApp.fetch(exportUrl, options); if (responseFetch.getResponseCode() !== 200) { console.error(`Error exporting PDF! Response Code: ${responseFetch.getResponseCode()}`); ui.alert("Failed to export PDF. Check logs for details."); return; } const blob = responseFetch.getBlob().setName('Bldg_Condition_Selected.pdf'); DriveApp.createFile(blob); ss.toast("PDF file with selected rows has been added to your Google Drive!"); }
关键修改点
- 移出循环内的导出逻辑:先收集所有勾选行的行号,再一次性构建导出范围,仅执行一次PDF导出和文件创建,确保只生成一个PDF。
- 动态构建导出范围:针对每个勾选行拼接
C{行号}:J{行号}作为range参数,让PDF仅包含选中行的目标列内容。 - 增加空选择判断:无勾选行时弹出提示,避免无效操作。
- 优化变量命名:消除重复变量,提升代码可读性。
使用步骤
- 将原函数
exportRangeToPDf替换为修改后的exportSelectedRowsToPDF。 - 在电子表格中重新绑定按钮到这个新函数。
- 勾选A列Checkbox后点击按钮,即可生成仅包含选中行的单个PDF。
内容的提问来源于stack exchange,提问作者Jarvis Davis
相关产品推荐
相关产品推荐

