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

NestJS中使用pdf2json解析上传PDF并转JSON且不落地存储的实现方案咨询

解决pdf2json无需持久化文件即可解析上传PDF的问题

我来帮你搞定这个问题——你想解析上传的PDF但不想把文件存到服务器永久目录,可pdf2json的loadPDF又必须要文件路径,对吧?这里有两个实用的解决方案,按优先级推荐:

方案一:用临时文件(最稳妥,兼容所有pdf2json版本)

我们可以用Node.js的临时文件模块创建一个一次性的临时PDF文件,解析完成后立刻自动删除,不会在服务器留下永久文件。

操作步骤:

  1. 先安装临时文件依赖:
npm install tmp --save
# 用yarn的话就是
yarn add tmp
  1. 修改你的控制器代码,整合临时文件逻辑:
import * as tmp from 'tmp';
import * as fs from 'fs';
import { PDFParser } from 'pdf2json';

// ... 你的其他控制器代码
@Post('getFields')
@UseInterceptors(AzureStorageFileInterceptor('file'))
async getFields(@UploadedFile() file?: UploadedFileMetadata) {
  if (!file || Object.keys(file).length === 0 || file.constructor !== Object) {
    throw UtilError.createErrorError('Missing file.');
  }

  // 用Promise包装异步流程,方便NestJS处理返回值
  return new Promise((resolve, reject) => {
    // 创建带.pdf后缀的临时文件,自动清理
    tmp.file({ postfix: '.pdf' }, (err, tmpFilePath, fd, cleanupCallback) => {
      if (err) {
        reject(err);
        return;
      }

      // 把上传的文件Buffer写入临时文件
      fs.writeFile(tmpFilePath, file.buffer, (writeErr) => {
        if (writeErr) {
          cleanupCallback(); // 哪怕写入失败,也要清理临时文件
          reject(writeErr);
          return;
        }

        const pdfParser = new PDFParser();
        
        // 错误处理:清理临时文件并抛出错误
        pdfParser.on("pdfParser_dataError", errData => {
          cleanupCallback();
          reject(errData.parserError);
        });
        
        // 解析完成:清理临时文件,返回解析结果
        pdfParser.on("pdfParser_dataReady", pdfData => {
          cleanupCallback(); // 关键:解析完立刻删掉临时文件
          resolve(pdfData);
          // 如果你不需要把JSON写到本地,下面这段可以删掉
          // fs.writeFile(path.join(__dirname, './../../../../src/entities/skiplino/form/F1040EZ.json'), JSON.stringify(pdfData), () => {
          //   console.log("JSON saved!")
          // });
        });

        // 加载临时文件路径,开始解析
        pdfParser.loadPDF(tmpFilePath);
      });
    });
  });
}

为什么选这个方案?

  • 临时文件会在解析完成(或出错)后立即被清理,完全不会占用服务器永久存储
  • 完美适配pdf2json对文件路径的要求,不管你用的是哪个版本都能跑通
  • 容错性强:哪怕解析出错,也能保证临时文件被删除,不会留下垃圾文件

方案二:直接用Buffer(仅适配新版pdf2json)

如果你的pdf2json版本比较新(大概v1.3.0以上),可以尝试直接传入文件Buffer,不需要创建任何文件:

// ... 其他代码不变
@Post('getFields')
@UseInterceptors(AzureStorageFileInterceptor('file'))
async getFields(@UploadedFile() file?: UploadedFileMetadata) {
  if (!file || Object.keys(file).length === 0 || file.constructor !== Object) {
    throw UtilError.createErrorError('Missing file.');
  }

  return new Promise((resolve, reject) => {
    const pdfParser = new PDFParser();
    
    pdfParser.on("pdfParser_dataError", errData => reject(errData.parserError));
    pdfParser.on("pdfParser_dataReady", pdfData => resolve(pdfData));

    // 直接传入上传文件的Buffer,跳过文件路径
    pdfParser.parseBuffer(file.buffer);
  });
}

注意:这个方法不是所有版本都支持,如果你的pdf2json版本较低,还是用方案一更稳妥。

额外优化小建议

  • 如果你不需要把解析后的JSON写到本地文件,建议删掉fs.writeFile那段代码,减少不必要的磁盘IO
  • 可以加个MIME类型校验,确保上传的是PDF:if (file.mimetype !== 'application/pdf') throw new Error('Only PDF files are allowed');
  • 临时文件可以加超时自动清理,比如给tmp.file加detachDescriptor: true和keep: false,极端情况下也不会残留文件

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.30 07:47:37