react-to-print能否正常渲染react-pdf输出的SVG内容以完成打印?
问题解决方案
问题原因
react-to-print 默认会将目标DOM克隆到隐藏iframe中触发打印,但react-pdf渲染的SVG依赖专属样式、内置字体资源,且默认固定宽高不适配打印纸张尺寸,克隆过程中容易出现资源丢失、样式错位,导致打印框内无法正常渲染内容。
方案1:调整react-to-print配置适配SVG打印
如果要保留当前基于SVG渲染的打印逻辑,修改handlePrint配置如下:
const handlePrint = useReactToPrint({ content: () => elmRef.current, copyStyles: true, // 强制克隆所有关联的页面样式 // 等待SVG所有资源加载完成后再生成打印内容 onBeforeGetContent: () => { return new Promise(resolve => { const svgs = elmRef.current.querySelectorAll('svg'); let loadedSvgCount = 0; if (svgs.length === 0) return resolve(); svgs.forEach(svg => { const innerResources = [...svg.querySelectorAll('image, font')]; if (innerResources.length === 0) { loadedSvgCount++; return loadedSvgCount === svgs.length && resolve(); } let loadedResCount = 0; innerResources.forEach(res => { const onResFinish = () => { loadedResCount++; if (loadedResCount === innerResources.length) { loadedSvgCount++; loadedSvgCount === svgs.length && resolve(); } }; res.onload = onResFinish; res.onerror = onResFinish; }) }) }) }, // 注入打印专属样式 pageStyle: ` @media print { /* 隐藏不需要打印的控制元素 */ .PdfDocumentControls, .dialogBox header { display: none !important; } /* 适配SVG打印尺寸 */ .pdfViewer svg { width: 100% !important; height: auto !important; page-break-after: always; overflow: visible !important; } } ` });
方案2:调用原生PDF打印(更稳定,文本可识别)
因为你本身持有服务端返回的Uint8Array原始PDF数据,直接调用浏览器原生PDF打印能力可以完全规避SVG渲染问题,打印内容和原始PDF完全一致,文本可选可识别:
// 假设你服务端返回的Uint8Array格式PDF数据存在变量pdfUint8Array中 const handlePrint = () => { // 转成PDF Blob对象 const pdfBlob = new Blob([pdfUint8Array], { type: 'application/pdf' }); const blobUrl = URL.createObjectURL(pdfBlob); // 创建隐藏iframe加载PDF const printIframe = document.createElement('iframe'); printIframe.style.cssText = 'position:fixed;right:0;bottom:0;width:0;height:0;border:none;'; printIframe.src = blobUrl; document.body.appendChild(printIframe); // 加载完成后触发打印,之后清理资源 printIframe.onload = () => { printIframe.contentWindow.print(); setTimeout(() => { URL.revokeObjectURL(blobUrl); document.body.removeChild(printIframe); }, 100); }; };
内容的提问来源于stack exchange,提问作者Mladen Milosavljevic
相关产品推荐
相关产品推荐

