如何在ReactJS中打印Base64格式的PDF文件?
解决React中Base64格式PDF打印白屏问题
原因分析
react-to-print 核心是打印已渲染的React组件,若直接嵌入Base64 PDF时未等待PDF加载完成就触发打印,或者PDF资源未正确解析,就会出现白屏。
方案一:基于react-to-print + iframe 实现(确保PDF加载完成)
创建一个包含iframe的组件,监听iframe的加载状态,确保PDF完全加载后再触发打印:
import React, { useRef, useState } from 'react'; import { useReactToPrint } from 'react-to-print'; const PdfPrintComponent = ({ base64Pdf }) => { const componentRef = useRef(); const [isPdfLoaded, setIsPdfLoaded] = useState(false); // 转换Base64为Blob URL const getBlobUrl = () => { // 确保Base64字符串包含正确的前缀,若没有则添加 const formattedBase64 = base64Pdf.startsWith('data:application/pdf;base64,') ? base64Pdf : `data:application/pdf;base64,${base64Pdf}`; const blob = new Blob([atob(formattedBase64.split(',')[1])], { type: 'application/pdf' }); return URL.createObjectURL(blob); }; const handlePrint = useReactToPrint({ content: () => componentRef.current, // 打印前确认PDF已加载 beforePrint: () => new Promise(resolve => { const interval = setInterval(() => { if (isPdfLoaded) { clearInterval(interval); resolve(); } }, 100); }), afterPrint: () => { // 打印后释放Blob URL,避免内存泄漏 URL.revokeObjectURL(getBlobUrl()); } }); return ( <div> <button onClick={handlePrint} disabled={!isPdfLoaded}>打印PDF</button> {/* 隐藏iframe,仅用于渲染PDF */} <div style={{ display: 'none' }}> <iframe ref={componentRef} src={getBlobUrl()} onLoad={() => setIsPdfLoaded(true)} title="PDF Preview" width="100%" height="600px" /> </div> </div> ); }; export default PdfPrintComponent;
方案二:不依赖react-to-print,直接通过原生API打印
如果react-to-print的组件渲染逻辑导致问题,可以直接用iframe加载PDF后调用原生打印:
import React from 'react'; const PdfPrint = ({ base64Pdf }) => { const printPdf = () => { // 处理Base64前缀 const formattedBase64 = base64Pdf.startsWith('data:application/pdf;base64,') ? base64Pdf : `data:application/pdf;base64,${base64Pdf}`; const blob = new Blob([atob(formattedBase64.split(',')[1])], { type: 'application/pdf' }); const url = URL.createObjectURL(blob); // 创建隐藏iframe const iframe = document.createElement('iframe'); iframe.style.display = 'none'; iframe.src = url; document.body.appendChild(iframe); iframe.onload = () => { // 触发打印 iframe.contentWindow.print(); // 打印后清理资源 setTimeout(() => { document.body.removeChild(iframe); URL.revokeObjectURL(url); }, 1000); }; }; return <button onClick={printPdf}>打印PDF</button>; }; export default PdfPrint;
关键注意点
- 确认Base64字符串格式正确,必须包含
data:application/pdf;base64,前缀(若没有则手动添加) - 必须等待PDF完全加载后再触发打印,否则会出现白屏
- 打印完成后记得释放Blob URL,避免内存泄漏
内容的提问来源于stack exchange,提问作者Gopinadh
相关产品推荐
相关产品推荐

