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

如何在Next.js API路由使用pdfkit生成PDF?附客户端方案

在Next.js API路由中使用pdfkit生成PDF的解决方案

问题背景

我正在开发一个需要使用pdfkit库生成PDF的项目,该功能已在Express.js服务器中正常运行,但在Next.js API路由中实现时遇到问题。

可用的Express.js代码(src/index.ts):

import express from 'express';
import PDFDocument from 'pdfkit';
const app = express();

app.get('/', (req, res) => {
  const doc = new PDFDocument();
  doc.text("hello hello hello HI");
  doc.end();
  doc.pipe(res);
});

const port = parseInt(process.env.PORT) || 3000;
app.listen(port, () => {
  console.log(`listening on port ${port}`);
});

访问根URL时,该代码可正常生成预期的PDF文件。

当前无法工作的Next.js API路由代码(api/route.ts):

import PDFDocument from 'pdfkit';
import { NextResponse } from 'next/server';

export async function GET(request: Request) {
  const doc = new PDFDocument();
  doc.text("hello hello hello HI");
  doc.end();
  doc.pipe(NextResponse);
}

在Next.js应用中访问对应API路由时,无法生成PDF且出现错误。

已尝试的操作:

  • 确认pdfkit已正确安装并导入。
  • 确认API路由已正确配置且可访问。

解决方案

1. Next.js API路由的正确实现

Next.js的API路由(App Router)需要返回完整的Response对象,不能直接将pdfkit的流pipe到NextResponse。需先将PDF流收集到缓冲区,再构建带正确头信息的响应:

import PDFDocument from 'pdfkit';
import { NextResponse } from 'next/server';

export async function GET(request: Request) {
  return new Promise<NextResponse>((resolve) => {
    const doc = new PDFDocument();
    const chunks: Uint8Array[] = [];

    // 收集流数据到缓冲区
    doc.on('data', (chunk) => chunks.push(chunk));
    doc.on('end', () => {
      const pdfBuffer = Buffer.concat(chunks);
      // 构建响应并设置必要的HTTP头
      const response = new NextResponse(pdfBuffer, {
        headers: {
          'Content-Type': 'application/pdf',
          'Content-Disposition': 'inline; filename="output.pdf"', // 替换为`attachment`可触发下载
        },
      });
      resolve(response);
    });

    // 添加PDF内容
    doc.text("hello hello hello HI");
    doc.end();
  });
}

2. 和Express.js实现的差异

  • 流处理逻辑不同:Express的res是原生可写流,pdfkit可直接pipe到res,由Express自动完成响应发送;Next.js API路由要求手动收集流数据,构建完整的Response实例返回。
  • 响应头配置:Next.js需要显式设置Content-Type、Content-Disposition等头信息,而Express会自动处理部分默认头。

3. 客户端浏览器生成PDF的方案

若无需服务器端生成,可直接在前端实现:

  • pdfkit-browser:pdfkit的浏览器兼容版本,可在前端生成PDF并通过Blob下载。
  • jsPDF:轻量前端PDF库,API简洁,适合简单PDF需求。
  • html2pdf.js:直接将页面HTML元素转换为PDF,适合基于现有页面内容生成PDF的场景。

客户端示例(pdfkit-browser):

// 安装依赖:npm install pdfkit-browser
import PDFDocument from 'pdfkit-browser';

function generateClientPDF() {
  const doc = new PDFDocument();
  const chunks = [];
  
  doc.on('data', (chunk) => chunks.push(chunk));
  doc.on('end', () => {
    const blob = new Blob(chunks, { type: 'application/pdf' });
    const url = URL.createObjectURL(blob);
    const link = document.createElement('a');
    link.href = url;
    link.download = 'client-generated.pdf';
    link.click();
    URL.revokeObjectURL(url);
  });

  doc.text("Hello from client-side PDF!");
  doc.end();
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 01:31:07