You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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的转换:

  1. 在Apps Script编辑器中,点击扩展 > Apps Script > 服务,启用Drive API。
  2. 使用以下代码:
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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.17 02:17:36