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

Angular 7中Base64转PDF及前端显示PDF缩略图技术问询

在Angular中展示Base64编码的PDF缩略图

我来帮你解决这个问题——先从你现有代码的小问题说起,再给你两种可行的方案,适配不同的缩略图需求:

首先,你当前代码里用fetch(fileUploaded.content)是踩了个小坑:fileUploaded.content是Base64字符串,不是可直接请求的URL,所以这个方法根本走不通。我们得换个思路,先把Base64转成Blob,再生成能被DOM识别的资源地址。


方案1:快速展示小尺寸PDF(简易缩略图)

如果只是需要把完整PDF缩小展示(相当于简易缩略图),可以用这种轻量方法:

1. 组件代码调整

先在组件里定义存储PDF资源地址的数组,同时处理Base64转Blob的逻辑:

import { Component, OnDestroy } from '@angular/core';
import { InvoiceCreationHttpService } from './your-service-path.service';

@Component({
  selector: 'app-pdf-thumbnail',
  templateUrl: './pdf-thumbnail.component.html'
})
export class PdfThumbnailComponent implements OnDestroy {
  pdfObjectUrls: string[] = [];

  constructor(private _invoiceCreationHttpService: InvoiceCreationHttpService) {}

  getImage() {
    this._invoiceCreationHttpService.getImage().subscribe((data: any) => {
      this.pdfObjectUrls = data.map((fileUploaded: any) => {
        // 解码Base64字符串为二进制数组
        const byteCharacters = atob(fileUploaded.content);
        const byteNumbers = new Array(byteCharacters.length);
        for (let i = 0; i < byteCharacters.length; i++) {
          byteNumbers[i] = byteCharacters.charCodeAt(i);
        }
        const byteArray = new Uint8Array(byteNumbers);
        
        // 创建PDF类型的Blob对象
        const pdfBlob = new Blob([byteArray], { type: 'application/pdf' });
        
        // 生成可用于DOM的Object URL
        return URL.createObjectURL(pdfBlob);
      });
    });
  }

  // 组件销毁时必须释放Object URL,避免内存泄漏
  ngOnDestroy() {
    this.pdfObjectUrls.forEach(url => URL.revokeObjectURL(url));
  }
}

2. HTML模板代码

用<iframe>展示PDF,通过宽高控制缩略图大小:

<div *ngFor="let pdfUrl of pdfObjectUrls" class="pdf-thumbnail">
  <iframe [src]="pdfUrl" width="200" height="250" frameborder="0" title="PDF缩略图"></iframe>
</div>

添加一点基础样式优化展示效果:

.pdf-thumbnail {
  display: inline-block;
  margin: 10px;
  border: 1px solid #e0e0e0;
  padding: 5px;
  border-radius: 4px;
}

方案2:生成真正的PDF第一页缩略图(图片形式)

如果需要的是只显示PDF第一页的图片式缩略图(更符合传统缩略图的预期),可以用pdfjs-dist库来渲染PDF的第一页:

1. 安装依赖

先安装PDF.js库:

npm install pdfjs-dist

然后从node_modules/pdfjs-dist/build/pdf.worker.min.js复制文件到项目的assets目录下(避免依赖外部CDN)。

2. 组件代码调整

import { Component, OnDestroy } from '@angular/core';
import { InvoiceCreationHttpService } from './your-service-path.service';
import * as pdfjsLib from 'pdfjs-dist';
import { getDocument } from 'pdfjs-dist';

// 配置PDF.js的Worker路径(指向assets里的文件)
pdfjsLib.GlobalWorkerOptions.workerSrc = '/assets/pdf.worker.min.js';

@Component({
  selector: 'app-pdf-image-thumbnail',
  templateUrl: './pdf-image-thumbnail.component.html'
})
export class PdfImageThumbnailComponent implements OnDestroy {
  pdfThumbnailUrls: string[] = [];
  private blobUrls: string[] = []; // 存储Blob URL用于后续清理

  constructor(private _invoiceCreationHttpService: InvoiceCreationHttpService) {}

  async getImage() {
    this._invoiceCreationHttpService.getImage().subscribe(async (data: any) => {
      for (const fileUploaded of data) {
        try {
          // 解码Base64为二进制数组
          const byteCharacters = atob(fileUploaded.content);
          const byteNumbers = Array.from(byteCharacters, c => c.charCodeAt(0));
          const byteArray = new Uint8Array(byteNumbers);
          const pdfBlob = new Blob([byteArray], { type: 'application/pdf' });
          const blobUrl = URL.createObjectURL(pdfBlob);
          this.blobUrls.push(blobUrl);

          // 加载PDF文档并获取第一页
          const pdfDoc = await getDocument(blobUrl).promise;
          const page = await pdfDoc.getPage(1);

          // 设置缩放比例(0.5对应原尺寸的50%,可按需调整)
          const viewport = page.getViewport({ scale: 0.5 });

          // 创建Canvas元素用于渲染页面
          const canvas = document.createElement('canvas');
          const context = canvas.getContext('2d');
          canvas.height = viewport.height;
          canvas.width = viewport.width;

          // 将PDF第一页渲染到Canvas
          await page.render({
            canvasContext: context!,
            viewport: viewport
          }).promise;

          // 将Canvas转为图片URL,添加到缩略图数组
          this.pdfThumbnailUrls.push(canvas.toDataURL('image/png'));
        } catch (error) {
          console.error('生成PDF缩略图失败:', error);
        }
      }
    });
  }

  // 组件销毁时清理所有Blob URL
  ngOnDestroy() {
    this.blobUrls.forEach(url => URL.revokeObjectURL(url));
  }
}

3. HTML模板代码

直接用<img>标签展示生成的图片缩略图:

<div *ngFor="let thumbnailUrl of pdfThumbnailUrls" class="pdf-image-thumbnail">
  <img [src]="thumbnailUrl" alt="PDF第一页缩略图" width="200" />
</div>

关键注意事项

  • 内存泄漏:一定要在组件销毁时调用URL.revokeObjectURL()释放Blob URL,否则会持续占用浏览器内存。
  • Base64清理:如果后端返回的Base64字符串包含换行或空格,需要先通过fileUploaded.content.replace(/\s/g, '')清理后再解码。
  • 兼容性:部分复杂PDF可能存在渲染异常,可调整pdfjs的缩放比例或添加错误处理逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.12 05:35:13