如何将Google Apps Script模态对话框改为Alert并保留PDF新标签打开功能?
解决方案
一、修复模态对话框大小问题
原代码中通过HTML div的style设置宽高无法生效,因为Google Apps Script的模态对话框尺寸由HtmlOutput实例的方法控制,而非内部HTML样式。只需在创建HtmlOutput后调用setWidth()和setHeight()即可指定弹窗大小:
// 替换原HtmlOutput创建代码 var html = '<div>' + message + '</div><script>window.open("' + pdfUrl + '", "_blank");</script>'; var userInterface = HtmlService.createHtmlOutput(html) .setWidth(300) // 设置弹窗宽度 .setHeight(150); // 设置弹窗高度 SpreadsheetApp.getUi().showModalDialog(userInterface, "Generate CPD Certificate");
二、替换模态框为Alert后打开PDF的方案
原生alert()是浏览器原生弹窗,不支持执行JavaScript代码,因此无法直接触发window.open()。推荐以下两种替代方案:
方案1:用侧边栏(Sidebar)替代Alert
侧边栏支持执行JS脚本,既能展示提示信息,又能自动打开PDF:
// 替换原模态框代码部分 var pdfUrl = pdfFileInDrive.getUrl(); var message = "证书已生成,PDF将在新标签页打开。"; var html = '<div style="padding: 15px;">' + message + '</div><script>window.open("' + pdfUrl + '", "_blank");google.script.host.close();</script>'; var sidebar = HtmlService.createHtmlOutput(html) .setTitle("CPD证书生成完成"); SpreadsheetApp.getUi().showSidebar(sidebar);
方案2:复制PDF链接到剪贴板+Alert提示
如果必须使用Alert,可以将PDF链接复制到用户剪贴板,再提示用户手动打开:
// 替换原模态框代码部分 var pdfUrl = pdfFileInDrive.getUrl(); // 复制链接到剪贴板的HTML var html = '<script>navigator.clipboard.writeText("' + pdfUrl + '").then(() => {google.script.host.close();});</script>'; // 先执行复制操作 SpreadsheetApp.getUi().showModalDialog(HtmlService.createHtmlOutput(html), "正在复制链接"); // 延迟后弹出Alert提示 Utilities.sleep(1000); SpreadsheetApp.getUi().alert("证书已生成,PDF链接已复制到剪贴板,请粘贴到浏览器打开:\n" + pdfUrl);
完整修改后的代码(修复模态框大小版本)
function generateCPDCertificate() { var spreadsheet = SpreadsheetApp.getActiveSpreadsheet(); var certificateSheet = spreadsheet.getSheetByName("Certificate"); // Check if AG cell needs to be updated var sheetName = certificateSheet.getRange("D4").getValue(); var targetSheet = spreadsheet.getSheetByName(sheetName); var targetCell = targetSheet.getRange("D:D").createTextFinder(certificateSheet.getRange("D6").getValue()).findNext(); var agCell = targetCell.offset(0, 28); // Assuming AG is 28 columns to the right of D if (agCell.isBlank()) { // Define the range to be included in the PDF var range = certificateSheet.getRange("A1:A30"); // Define the filename var filename = certificateSheet.getRange("D4").getValue() + "_" + certificateSheet.getRange("B6").getValue() + "_" + certificateSheet.getRange("D6").getValue() + ".pdf"; // Export the range as a PDF var url = spreadsheet.getUrl(); var exportUrl = url.replace(/\/edit.*$/, '') + '/export?format=pdf&size=A4&portrait=true&fitw=true&sheetnames=false&printtitle=false&pagenum=false&gridlines=false&horizontal_alignment=CENTER&vertical_alignment=TOP'; var options = { headers: { 'Authorization': 'Bearer ' + ScriptApp.getOAuthToken() } }; var response = UrlFetchApp.fetch(exportUrl + "&gid=" + certificateSheet.getSheetId() + "&range=A1:A30", options); var blob = response.getBlob().setName(filename); // Create or get the "CPD Certificate" folder var folderName = "CPD Certificate"; var folderIterator = DriveApp.getFoldersByName(folderName); var folder; if (folderIterator.hasNext()) { folder = folderIterator.next(); } else { folder = DriveApp.createFolder(folderName); } // Delete existing files in the "CPD Certificate" folder var files = folder.getFiles(); while (files.hasNext()) { var file = files.next(); file.setTrashed(true); } // Save the PDF file to "CPD Certificate" folder var pdfFileInDrive = folder.createFile(blob); // Set permissions to 'anyone can view' pdfFileInDrive.setSharing(DriveApp.Access.ANYONE_WITH_LINK, DriveApp.Permission.VIEW); // Open the PDF file using the Mozilla PDF Viewer var pdfUrl = pdfFileInDrive.getUrl(); var message = "The PDF file is now open in the new tab."; var html = '<div>' + message + '</div><script>window.open("' + pdfUrl + '", "_blank");</script>'; var userInterface = HtmlService.createHtmlOutput(html) .setWidth(300) .setHeight(150); // Show the modal dialog SpreadsheetApp.getUi().showModalDialog(userInterface, "Generate CPD Certificate"); // Update AG cell with today's date agCell.setValue(new Date()); } else { // Display message if AG cell is not blank SpreadsheetApp.getUi().alert("This certificate is already printed: " + agCell.getValue()); } }
内容的提问来源于stack exchange,提问作者Angelei
相关产品推荐
相关产品推荐

