NestJS使用jsPDF生成带图PDF:响应返回无图片的正确处理方法
解决NestJS中jsPDF生成PDF返回客户端无图片的问题
你的问题核心在于返回客户端时的PDF数据编码处理错误:doc.output()默认返回UTF-8编码的字符串,直接推送到Readable流会导致图片的二进制数据被破坏;而本地保存时你指定了'binary'编码,所以能正常显示图片。另外代码里还有个笔误:writeFileSync里的data应该是pdf,不过这是本地保存的问题,和客户端返回无关。
下面是几种正确的响应实现方式:
方法一:直接返回Buffer(最简单)
利用doc.output('arraybuffer')获取二进制数据,转换成Buffer后直接通过Response发送:
@Post('/') async generatePdf(@Res() response: Response) { const doc = new jsPDF(); doc.text('PDF with image', 10, 10); const imageData = readFileSync('src/pdf/template_1.png'); doc.addImage(imageData, 'PNG', 0, 0, 100, 100); // 获取PDF的ArrayBuffer格式数据,转成Buffer const pdfBuffer = Buffer.from(doc.output('arraybuffer')); // 设置响应头 response.set({ 'Content-Type': 'application/pdf', 'Content-Disposition': 'inline; filename="document.pdf"' // 可选,指定文件名,改成attachment可触发下载 }); // 直接发送Buffer response.send(pdfBuffer); }
方法二:正确处理Readable流
如果一定要用流,需确保推送的是二进制数据而非字符串:
@Post('/') async generatePdf(@Res() response: Response) { const doc = new jsPDF(); doc.text('PDF with image', 10, 10); const imageData = readFileSync('src/pdf/template_1.png'); doc.addImage(imageData, 'PNG', 0, 0, 100, 100); // 获取ArrayBuffer并转成Buffer const pdfBuffer = Buffer.from(doc.output('arraybuffer')); const stream = new Readable(); stream.push(pdfBuffer); stream.push(null); response.set({ 'Content-Type': 'application/pdf', 'Content-Disposition': 'inline; filename="document.pdf"' }); stream.pipe(response); }
方法三:使用NestJS的StreamableFile(推荐)
NestJS提供的StreamableFile工具类能更优雅地处理文件流响应,无需手动管理流:
import { StreamableFile } from '@nestjs/common'; import { createReadStream } from 'fs'; @Post('/') async generatePdf() { const doc = new jsPDF(); doc.text('PDF with image', 10, 10); const imageData = readFileSync('src/pdf/template_1.png'); doc.addImage(imageData, 'PNG', 0, 0, 100, 100); // 先将PDF写入临时文件(你已能正常保存) const tempPath = '/tmp/document.pdf'; writeFileSync(tempPath, doc.output('arraybuffer')); // 创建可读流并包装成StreamableFile const fileStream = createReadStream(tempPath); return new StreamableFile(fileStream, { type: 'application/pdf', disposition: 'inline; filename="document.pdf"' }); }
关键说明
- 必须使用
doc.output('arraybuffer')获取二进制格式的PDF数据,避免字符串编码导致的图片损坏; Content-Disposition响应头可控制浏览器是直接预览PDF(inline)还是触发下载(attachment);- 使用
StreamableFile时无需手动注入@Res(),NestJS会自动处理响应头和流的传输逻辑。
内容的提问来源于stack exchange,提问作者Ivan
相关产品推荐
相关产品推荐

