React中嵌入QR码后,如何实现不转图片的可自定义PDF阅读器?
解决方案:PDF嵌入QR码+自定义高质量预览
一、在PDF中嵌入QR码(保持原生PDF格式)
不要在预览层叠加QR码,直接修改PDF文件本身,确保输出仍是标准PDF格式:
- 前端生成QR码:使用
qrcode库生成base64格式的QR码图片 - 修改PDF内容:用PDF处理库(前端选
@pdf-lib/pdf-lib,后端可选PyPDF2/iText)将QR码嵌入到PDF指定页面或位置
前端示例代码(React环境)
import { PDFDocument } from '@pdf-lib/pdf-lib'; import QRCode from 'qrcode'; // 给PDF添加QR码的异步函数 async function addQRCodeToPDF(originalPDFBytes, qrContent) { // 生成QR码的base64图片 const qrBase64 = await QRCode.toDataURL(qrContent); // 加载原始PDF const pdfDoc = await PDFDocument.load(originalPDFBytes); // 嵌入QR码图片到PDF const qrImage = await pdfDoc.embedPng(qrBase64); const targetPage = pdfDoc.getPages()[0]; // 取第一页为例 const { width, height } = targetPage.getSize(); // 设置QR码位置(右下角,可自定义坐标) targetPage.drawImage(qrImage, { x: width - 100, y: 50, width: 80, height: 80, }); // 导出修改后的PDF字节流 return await pdfDoc.save(); }
生成的PDF为完整原生格式,而非图片拼接,为后续高质量预览提供基础。
二、自定义高质量PDF预览
使用pdfjs-dist官方Viewer组件(基于矢量渲染,无画质损失),完全自定义UI:
1. 安装依赖
npm install pdfjs-dist pdfjs-dist/webpack
2. React中封装自定义预览组件
import React, { useEffect, useRef } from 'react'; import * as pdfjsLib from 'pdfjs-dist'; import 'pdfjs-dist/web/pdf_viewer.css'; import { PDFViewer } from 'pdfjs-dist/web/pdf_viewer'; // 配置PDF.js的Worker路径 pdfjsLib.GlobalWorkerOptions.workerSrc = `//cdnjs.cloudflare.com/ajax/libs/pdf.js/${pdfjsLib.version}/pdf.worker.min.js`; const CustomPDFViewer = ({ pdfBytes }) => { const containerRef = useRef(null); const viewerRef = useRef(null); useEffect(() => { if (!containerRef.current || !pdfBytes) return; // 初始化Viewer实例 if (!viewerRef.current) { viewerRef.current = new PDFViewer({ container: containerRef.current }); } // 加载修改后的PDF const loadingTask = pdfjsLib.getDocument({ data: pdfBytes }); loadingTask.promise.then(pdf => { viewerRef.current.setDocument(pdf); }); }, [pdfBytes]); // 自定义分页逻辑 const goToPrevPage = () => { viewerRef.current?.currentPageNumber && (viewerRef.current.currentPageNumber -= 1); }; const goToNextPage = () => { viewerRef.current?.currentPageNumber && (viewerRef.current.currentPageNumber += 1); }; return ( <div className="pdf-viewer-wrapper"> {/* 自定义工具栏 */} <div className="custom-toolbar"> <button onClick={goToPrevPage}>上一页</button> <button onClick={goToNextPage}>下一页</button> </div> {/* PDF预览容器 */} <div ref={containerRef} className="pdf-container" /> {/* 自定义样式 */} <style jsx>{` .pdf-viewer-wrapper { background-color: #f5f5f5; padding: 20px; border-radius: 8px; } .custom-toolbar { margin-bottom: 16px; gap: 8px; display: flex; } .pdf-container { height: 80vh; overflow-y: auto; } .pdfViewer .page { box-shadow: none; margin: 0 auto 16px; } `}</style> </div> ); }; export default CustomPDFViewer;
3. 核心优势
- 基于PDF.js原生矢量渲染,画质和标准PDF预览完全一致
- 可自由隐藏默认工具栏、自定义分页导航、调整配色和布局
- 支持PDF的所有原生特性(文本选择、缩放等)
三、整体流程
- 用户点击按钮,触发QR码生成和PDF修改逻辑
- 导出修改后的PDF字节流
- 传入自定义的
CustomPDFViewer组件完成高质量预览
内容的提问来源于stack exchange,提问作者arya
相关产品推荐
相关产品推荐

