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

使用jsPDF AutoTable添加S3图片报错及PDF无图问题排查

在Angular中使用jsPDF AutoTable添加S3图片到PDF表格的问题

我尝试将AWS S3存储桶中的图片通过URL添加到jsPDF AutoTable生成的PDF表格中,使用版本:jspdf: ^2.5.1,jspdf-autotable: ^3.5.31,Angular 8。

数据格式

[{ netValue: 13702.5, prodCode: "UPP", prodDesc: "Privacy Panel", prodImg: "https://url/images/UPP02.png", prodQty: 20, unitPrice: 870 }]

HTML表格代码

<table class="table table-hover table-responsive-xxl table-bordered" id="prodTable" #prodTable>
    <thead>
        <tr class="table-reflow">
            <th>S. N</th>
            <th>Product Code</th>
            <th>Description</th>
            <th>Image</th>
            <th>Qty</th>
            <th>Price</th>
            <th>Amount</th>
        </tr>
    </thead>
    <tbody>
        <tr *ngFor="let prod of prodDetailsArr; let i = index">
            <td>{{ i+1 }}</td>
            <td>{{ prod.prodCode }}</td>
            <td>{{ prod.prodDesc }}</td>
            <td><img [src]="prod.prodImg"></td>
            <td>{{ prod.prodQty }}</td>
            <td>{{ prod.unitPrice }}</td>
            <td>{{ prod.netValue }}</td>
        </tr>
    </tbody>
</table>

尝试的PDF生成代码

autoTable(doc, { 
      html: '#prodTable',
      startY: 200,                    
      theme: 'plain',
      tableLineColor: [0, 0, 0],
      tableLineWidth: 0.5,
      margin: { left: 5, right: 7 },
      didDrawCell: function(data) {
        if (data.column.index === 3 && data.cell.section === 'body') {
          var td = data.cell.raw;
          console.log(td)
          var img = td.getElementsByTagName('img')[0];
          var dim = data.cell.height - data.cell.padding('vertical');
          doc.addImage(img.src, data.cell.x,  data.cell.y, dim, dim);         
        }
      }
    })

遇到的错误

编译错误

Property 'getElementsByTagName' does not exist on type 'HTMLTableCellElement | CellInput'.
Property 'getElementsByTagName' does not exist on type 'string'.

运行时错误

  1. CORS错误:

zone-evergreen.js:2981 Access to XMLHttpRequest at 'https://url/images/UPP02.png' from origin 'http://localhost:4200' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.

  1. addImage格式错误:

ERROR Error: addImage does not support files of type 'UNKNOWN', please ensure that a plugin for 'UNKNOWN' support is added.
at Object.P (jspdf.es.min.js:86:93253)
at push../node_modules/jspdf/dist/jspdf.es.min.js.e.addImage

  1. StackBlitz额外错误:

Incomplete or corrupt PNG File


解决方案

1. 修复编译错误

data.cell.raw的类型为HTMLTableCellElement | CellInput,需先做类型断言和校验,确保操作的是HTML元素:

didDrawCell: function(data) {
  if (data.column.index === 3 && data.cell.section === 'body') {
    const td = data.cell.raw as HTMLTableCellElement;
    if (td instanceof HTMLElement) {
      const img = td.getElementsByTagName('img')[0];
      if (img) {
        const dim = data.cell.height - data.cell.padding('vertical');
        // 后续图片处理逻辑
      }
    }
  }
}

2. 解决S3 CORS问题

在AWS S3存储桶中配置CORS规则,允许前端域名访问:

<CORSConfiguration>
  <CORSRule>
    <AllowedOrigin>http://localhost:4200</AllowedOrigin>
    <AllowedMethod>GET</AllowedMethod>
    <AllowedHeader>*</AllowedHeader>
  </CORSRule>
</CORSConfiguration>

生产环境可替换为实际的前端域名,或使用*允许所有域名(不推荐)。

3. 解决addImage格式与图片损坏问题

jsPDF无法直接使用远程URL添加图片,需先将图片转换为Base64格式:

// Angular中封装图片转Base64方法
async getImageBase64(url: string): Promise<string> {
  const response = await this.httpClient.get(url, { responseType: 'blob' }).toPromise();
  return new Promise((resolve, reject) => {
    const reader = new FileReader();
    reader.onloadend = () => resolve(reader.result as string);
    reader.onerror = reject;
    reader.readAsDataURL(response);
  });
}

// 预加载图片后生成PDF
async generatePdf() {
  const doc = new jsPDF();
  // 预加载所有图片的Base64
  const imgBase64Arr = await Promise.all(
    this.prodDetailsArr.map(prod => this.getImageBase64(prod.prodImg))
  );

  autoTable(doc, {
    html: '#prodTable',
    startY: 200,
    theme: 'plain',
    tableLineColor: [0, 0, 0],
    tableLineWidth: 0.5,
    margin: { left: 5, right: 7 },
    didDrawCell: (data) => {
      if (data.column.index === 3 && data.cell.section === 'body') {
        const imgBase64 = imgBase64Arr[data.row.index];
        const dim = data.cell.height - data.cell.padding('vertical');
        // 明确指定图片格式,如PNG/JPEG
        doc.addImage(imgBase64, 'PNG', data.cell.x, data.cell.y, dim, dim);
      }
    }
  });

  doc.save('products.pdf');
}

额外注意事项

  • 确保S3图片权限正确,可设置为公开可读,或使用预签名URL访问私有图片
  • 若图片为JPG格式,需将addImage的格式参数改为'JPEG'

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 04:53:27