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
相关产品推荐
相关产品推荐

