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

如何在Angular Universal服务端使用jsPDF生成PDF文件?

Angular Universal 服务端渲染导出分页表格PDF实现示例

前置准备

首先完成依赖安装和组件改造:

  • 安装所需依赖:npm install jspdf jspdf-autotable @angular/ssr express
  • 给现有data grid组件新增导出模式输入参数,开启时关闭分页、渲染全量数据,避免分页逻辑干扰导出结果

示例组件改造代码:

// data-grid.component.ts
@Component({
  selector: 'app-data-grid',
  templateUrl: './data-grid.component.html',
  styleUrls: ['./data-grid.component.css']
})
export class DataGridComponent {
  // 原有组件参数
  @Input() pageSize = 20;
  @Input() currentPage = 1;
  // 新增导出专用参数
  @Input() exportMode = false;
  @Input() fullExportData: any[] = [];
  @Input() columns: {field: string, header: string}[] = [];
}

对应组件模板新增全量渲染逻辑:

<!-- 原有分页模式展示 -->
<div *ngIf="!exportMode">
  <table>
    <tr *ngFor="let row of pagedData">
      <td *ngFor="let col of columns">{{row[col.field]}}</td>
    </tr>
  </table>
  <app-pagination></app-pagination>
</div>

<!-- 导出模式全量展示 -->
<table class="export-table" *ngIf="exportMode">
  <thead>
    <tr>
      <th *ngFor="let col of columns">{{col.header}}</th>
    </tr>
  </thead>
  <tbody>
    <tr *ngFor="let row of fullExportData">
      <td *ngFor="let col of columns">{{row[col.field]}}</td>
    </tr>
  </tbody>
</table>

Express 接口与服务端渲染逻辑

在Angular Universal的server.ts文件中新增导出接口,实现服务端渲染组件+生成PDF的完整逻辑:

// server.ts
import { renderComponent } from '@angular/core/server';
import { DataGridComponent } from './app/data-grid/data-grid.component';
import jsPDF from 'jspdf';
import autoTable from 'jspdf-autotable';
import express from 'express';

const server = express();
server.use(express.json({limit: '50mb'})); // 配置大文件请求限制,适配大数据量导出

// PDF导出接口
server.post('/api/export-grid-pdf', async (req, res) => {
  try {
    // 方案1:从请求体获取全量数据,也可以直接在服务端查询数据库获取,避免前端传输大数据
    const { fullExportData, columns } = req.body;

    // 若需要完全复用组件现有样式,可先渲染组件拿到完整HTML
    const renderedHtml = await renderComponent(DataGridComponent, {
      inputs: {
        exportMode: true,
        fullExportData,
        columns
      },
      enableHydration: false, // 关闭hydration提升渲染性能
      document: '<!DOCTYPE html><html><head><link rel="stylesheet" href="dist/browser/styles.css"></head><body></body></html>' // 引入全局样式保证渲染效果和前端一致
    });

    // 方案2:大数据量优先选择直接用数据生成PDF,性能更高
    const doc = new jsPDF('landscape', 'mm', 'a4');
    doc.setFontSize(12);
    doc.text('表格导出结果', 10, 15);

    autoTable(doc, {
      head: [columns.map(col => col.header)],
      body: fullExportData.map(row => columns.map(col => row[col.field])),
      startY: 20,
      headStyles: { fillColor: '#1976d2', textColor: '#fff' },
      alternateRowStyles: { fillColor: '#f5f5f5' },
      pageBreak: 'auto',
      rowPageBreak: 'auto',
      // 配置固定表头,每页都显示表头
      didDrawPage: (data) => {
        doc.text('表格导出结果', 10, 15);
      }
    });

    // 返回PDF文件
    const pdfBuffer = doc.output('arraybuffer');
    res.setHeader('Content-Type', 'application/pdf');
    res.setHeader('Content-Disposition', 'attachment; filename="grid-export.pdf"');
    res.status(200).send(Buffer.from(pdfBuffer));
  } catch (err) {
    res.status(500).send('PDF生成失败');
  }
});

// 其他原有服务端逻辑

核心注意事项

  • 数千行大数据量场景优先选择直接用数据调用autoTable生成PDF,比解析渲染后的HTML生成效率高3-5倍,内存占用更低
  • 若需要1:1复用前端组件样式,可使用jsPDF的html()方法传入渲染后的组件HTML生成PDF,需提前加载对应样式文件
  • 服务端接收前端传的全量数据时,要调整express的请求体大小限制,避免大数据量请求被拦截
  • 生成的PDF直接以arraybuffer形式返回,不要在服务端本地落盘,减少IO开销和存储占用

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 09:39:03