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

合并Docx文件为PDF时JavaScript运行时意外退出问题

问题分析与解决方案

错误根源

  1. URL匹配范围不足:原正则仅适配Drive文件URL(/file/d/),但输入的URL包含Google Docs文档(/document/d/),导致无法提取对应文件ID,后续流程直接出错。
  2. 未覆盖Google Docs类型:Google Docs的MIME类型为application/vnd.google-apps.document,原代码未处理该类型,无法完成格式转换。
  3. Blob创建逻辑异常:原代码中[...new Int8Array(bytes)]的转换方式可能导致数据损坏,触发运行时意外退出。

修改后的完整代码

async function newMain() {
  // 替换为你的目标文件夹ID
  const destinationFolderId = "your-folder-id";
  const destinationFolder = DriveApp.getFolderById(destinationFolderId);
  
  // 从表格读取URL列表(需确保sheet变量已提前定义)
  const urls = sheet.getRange(2, 2).getValue().toString().split(",");

  // 提取文件ID:兼容Google Docs和Drive文件URL
  const ids = urls.map(url => {
    const matches = url.match(/(?:\/file\/d\/|\/document\/d\/)([^\/]+)\/edit/);
    return matches ? matches[1] : null;
  }).filter(id => id !== null); // 过滤无效ID

  // 批量获取PDF格式数据
  const pdfDatas = await Promise.all(ids.map(async id => {
    const file = DriveApp.getFileById(id);
    const mimeType = file.getMimeType();
    
    let pdfBlob;
    switch(mimeType) {
      case 'application/vnd.openxmlformats-officedocument.wordprocessingml.document':
        // 转换docx为PDF并清理临时文件
        const tempFile = Drive.Files.insert({}, file.getBlob(), {convert: true});
        pdfBlob = DriveApp.getFileById(tempFile.id).getBlob();
        Drive.Files.remove(tempFile.id);
        break;
      case 'application/pdf':
        pdfBlob = file.getBlob();
        break;
      case 'application/vnd.google-apps.document':
        // 直接导出Google Docs为PDF
        pdfBlob = Drive.Files.export(id, MimeType.PDF);
        break;
      default:
        console.log(`跳过不支持的文件类型:${mimeType}`);
        return null;
    }
    return pdfBlob ? new Uint8Array(pdfBlob.getBytes()) : null;
  })).then(datas => datas.filter(data => data !== null)); // 过滤无效数据

  // 加载pdf-lib库
  const cdnjs = "https://cdn.jsdelivr.net/npm/pdf-lib/dist/pdf-lib.min.js";
  eval(UrlFetchApp.fetch(cdnjs).getContentText().replace(/setTimeout\(.*?,.*?(\d*?)\)/g, "Utilities.sleep($1);return t();"));

  // 合并PDF文件
  const pdfDoc = await PDFLib.PDFDocument.create();
  for (const data of pdfDatas) {
    const pdfData = await PDFLib.PDFDocument.load(data);
    const pages = await pdfDoc.copyPages(pdfData, pdfData.getPageIndices());
    pages.forEach(page => pdfDoc.addPage(page));
  }

  // 生成并保存合并后的PDF
  const bytes = await pdfDoc.save();
  const blob = Utilities.newBlob(Array.from(bytes), MimeType.PDF, "merged_sample.pdf");
  const mergedFile = DriveApp.createFile(blob);
  mergedFile.moveTo(destinationFolder);
}

核心修改说明

  • URL正则优化:更新正则表达式,同时匹配Google Docs和Drive文件的URL格式,确保所有有效文件ID都能被提取。
  • 新增Google Docs处理:添加对Google Docs类型的判断,使用Drive.Files.export直接导出为PDF,无需创建临时文件。
  • 异步逻辑优化:用Promise.all并行处理文件转换,提升执行效率;过滤无效ID和不支持的文件类型,避免后续流程报错。
  • Blob创建优化:将pdf-lib返回的Uint8Array转换为普通数组传入Utilities.newBlob,避免数据转换异常。
  • 代码可读性提升:用switch替代多段if-else,添加日志输出方便调试。

注意事项

  1. 需在Google Apps Script编辑器的「资源」→「高级Google服务」中启用Drive API。
  2. 首次运行脚本时需完成权限授权,确保脚本可访问Drive和表格资源。
  3. 若合并的PDF总页数过多,可能触发GAS内存限制,可考虑分批次合并。

内容的提问来源于stack exchange,提问作者EagleEye

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 12:26:10