繁体   English   中英

如何使用 Nest js 作为服务器端并在客户端反应从 puppeteer 下载 pdf?

[英]How to download pdf from puppeteer using Nest js as Server Side and React in Client Side?

我在后端使用 Nest 使用 Puppeteer 生成 pdf 文件。 当我给它提供在磁盘上创建 pdf 的路径时,Puppeteer 工作正常。

我目前正在退回 pdf。

这是生成 pdf 的代码:

const browser = await puppeteer.launch({ headless: true });
    const page = await browser.newPage();
    await page.goto('https://blog.risingstack.com', {waitUntil: 'networkidle0'});


    var options = {
      width: '1230px',
      displayHeaderFooter: false,
      margin: {
        top: "10px",
        bottom: "30px"
      },
      printBackground: true,
    }

    const pdf = await page.pdf(options);
  
    await browser.close();
    return pdf

这是调用前面的function的controller:

  @Header('Content-Type', 'application/pdf')
  async Printpdf(@Body() message: any) {
    console.log(message);
    return this.PrintpdfService.printpdf();
  }

在 React 中,我使用 axios 来调用它,如下所示:

return axios.post(`http://localhost:3000/printpdf`,data, {
    responseType: 'arraybuffer',
    headers: {
      'Accept': 'application/pdf'
    }
  });

我正在尝试使用以下命令下载 pdf:

getBuildingReport(data).then((response) => {
      console.log(response);
      const blob = new Blob([response.data], {type: 'application/pdf'})
       const link = document.createElement('a')
       link.href = window.URL.createObjectURL(blob)
       link.download = `name.pdf`
       link.click();
    })
    .catch(err => {
      console.log(err)
    }); 

我按照本教程进行操作。 https://blog.risingstack.com/pdf-from-html-node-js-puppeteer/#option3

但下载的 pdf 构建正确,无法打开它,因为我得到“加载 PDF 文档失败”。

我曾经为一个项目解决了这个问题并保存了代码片段......关键是将 PDF 加载到缓冲区中,然后将其发送回客户端。

这是在 NestJS 服务中实现的示例 function:

  async generatePDF(): Promise<Buffer> {
    const content = fs.readFileSync(
      path.resolve(__dirname, './templates/invoice.html'),
      'utf-8'
    )

    const browser = await puppeteer.launch({ headless: true })
    const page = await browser.newPage()
    await page.setContent(content)

    const buffer = await page.pdf({
      format: 'A4',
      printBackground: true,
      margin: {
        left: '0px',
        top: '0px',
        right: '0px',
        bottom: '0px'
      }
    })

    await browser.close()

    return buffer
  }

这是一个示例 NestJS controller:

  @Get('/:uuid/pdf')
  async getInvoicePdfByUUID(
    @Param('uuid', ParseUUIDPipe) uuid: string,
    @GetUser() user: User,
    @Res() res: Response,
  ): Promise<void> {

    // ...

    const buffer = await this.invoicesService.generatePDF()

    res.set({
      // pdf
      'Content-Type': 'application/pdf',
      'Content-Disposition': 'attachment; filename=invoice.pdf',
      'Content-Length': buffer.length,

      // prevent cache
      'Cache-Control': 'no-cache, no-store, must-revalidate',
      'Pragma': 'no-cache',
      'Expires': 0,
    })

    res.end(buffer)
  }

请注意,以上假设您将 NestJS 与 Express 一起使用。

干杯!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM