Apps Script中HTMLService转HTML为PDF失败求助
D&D动态法术书:HTML转PDF失败及打印裁切问题解决方案
问题描述
我正在为D&D玩家制作动态法术书,已将所有法术数据存储在Google表格中并生成了HTML页面,但使用getAs('application/pdf')命令无法将HTML转换为PDF。不使用该命令时HTML显示正常,但直接打印HTML会出现严重裁切问题,求有效的HTML转PDF方案。
原代码
function doGet() { var actualSpreadSheet=SpreadsheetApp.getActiveSpreadsheet(); var allSheets=actualSpreadSheet.getSheets(); var spellsSheet; allSheets.forEach(function(sheet){ if(sheet.getName()=="LibroConjuros"){ spellsSheet=sheet; } }); var spellBook=spellsSheet.getRange("C2:AE9").getValues(); spellBook.forEach(function(spell){ if(spell[2]!=''){ spellsData.push(spell); } }); var html=HtmlService.createTemplateFromFile('Card').evaluate().getAs('application/pdf'); return html; }
可行解决方案
方案1:修正PDF转换逻辑,补全代码缺失项
原代码存在两个关键问题:spellsData未声明,且HtmlOutput.getAs('application/pdf')的返回方式不符合Web应用要求。修改后的代码如下:
function doGet() { // 简化Sheet获取逻辑 var actualSpreadSheet = SpreadsheetApp.getActiveSpreadsheet(); var spellsSheet = actualSpreadSheet.getSheetByName("LibroConjuros"); var spellBook = spellsSheet.getRange("C2:AE9").getValues(); var spellsData = []; // 声明变量,避免报错 spellBook.forEach(function(spell){ if(spell[2]!=''){ spellsData.push(spell); } }); // 将数据传入模板 var htmlTemplate = HtmlService.createTemplateFromFile('Card'); htmlTemplate.spellsData = spellsData; var htmlOutput = htmlTemplate.evaluate(); // 生成PDF Blob并设置文件名 var pdfBlob = htmlOutput.getAs('application/pdf') .setName('D&D法术书.pdf'); // 正确返回PDF内容 return ContentService.createTextOutput(pdfBlob.getDataAsString()) .setMimeType(ContentService.MimeType.PDF); }
方案2:添加打印专用CSS,解决裁切问题
直接打印HTML出现裁切,核心是未适配纸张尺寸。在Card.html中添加以下CSS:
/* 全局样式确保内容适配 */ body { max-width: 210mm; margin: 0 auto; padding: 1cm; } /* 打印专用样式 */ @media print { @page { size: A4; margin: 1cm; } body { width: 100%; height: auto; overflow: visible; padding: 0; } /* 隐藏不需要打印的元素 */ .no-print { display: none !important; } }
该样式会强制内容适配A4纸张,避免边缘裁切。
方案3:使用Drive API强制转换PDF
如果方案1仍无法生效,可启用Google Drive高级服务,通过API完成HTML到PDF的转换:
- 在Apps Script编辑器中,点击
扩展>Apps Script>服务,启用Drive API。 - 使用以下代码:
function doGet() { var actualSpreadSheet = SpreadsheetApp.getActiveSpreadsheet(); var spellsSheet = actualSpreadSheet.getSheetByName("LibroConjuros"); var spellBook = spellsSheet.getRange("C2:AE9").getValues(); var spellsData = []; spellBook.forEach(function(spell){ if(spell[2]!=''){ spellsData.push(spell); } }); // 生成HTML内容 var htmlTemplate = HtmlService.createTemplateFromFile('Card'); htmlTemplate.spellsData = spellsData; var htmlContent = htmlTemplate.evaluate().getContent(); // 创建临时HTML文件 var htmlBlob = Utilities.newBlob(htmlContent, 'text/html', '临时法术书.html'); var tempHtmlFile = DriveApp.createFile(htmlBlob); // 通过Drive API转换为PDF var pdfFile = Drive.Files.insert( {title: 'D&D法术书.pdf', mimeType: 'application/pdf'}, tempHtmlFile.getBlob(), {convert: true} ); // 获取PDF并清理临时文件 var pdfBlob = DriveApp.getFileById(pdfFile.id).getBlob(); tempHtmlFile.setTrashed(true); // 返回PDF return ContentService.createTextOutput(pdfBlob.getDataAsString()) .setMimeType(ContentService.MimeType.PDF); }
内容的提问来源于stack exchange,提问作者Niktro B
相关产品推荐
相关产品推荐

