NestJS中使用pdf2json解析上传PDF并转JSON且不落地存储的实现方案咨询
解决pdf2json无需持久化文件即可解析上传PDF的问题
我来帮你搞定这个问题——你想解析上传的PDF但不想把文件存到服务器永久目录,可pdf2json的loadPDF又必须要文件路径,对吧?这里有两个实用的解决方案,按优先级推荐:
方案一:用临时文件(最稳妥,兼容所有pdf2json版本)
我们可以用Node.js的临时文件模块创建一个一次性的临时PDF文件,解析完成后立刻自动删除,不会在服务器留下永久文件。
操作步骤:
- 先安装临时文件依赖:
npm install tmp --save # 用yarn的话就是 yarn add tmp
- 修改你的控制器代码,整合临时文件逻辑:
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
相关产品推荐
相关产品推荐

