PDF.js kann kein gerendertes Leinwandbild anzeigen
P粉766520991
2023-08-17 20:02:20
<p>Ich habe eine React-Komponente, die ein PDF anzeigt. Wenn ich diese Komponente verwende, muss ich nur die URL der PDF übergeben. </p>
<pre class="brush:php;toolbar:false;"><Previewer pdfUrl={pdfUrl}></Previewer></pre>
<p>Die Komponente verwaltet die Details der Vorschau. Das Problem, das ich habe, ist, dass diese Komponente das PDF nicht anzeigt.Vermisse ich etwas? Was soll ich tun, um dieses Problem zu lösen?下面是一个演示:</p>
<p><br /></p>
<pre class="snippet-code-js lang-js Prettyprint-override"><code>const { StrictMode, useRef } = React;
const { createRoot } = ReactDOM;
const Styles = {};
const Previewer = (props) => {
const canvasRef = useRef(null);
React.useEffect(() => {
if (props.pdfUrl) {
initPdf(props.pdfUrl);
}
}, []);
// Async/await-Funktion zur Verwendung von Promise konvertiert, da die Babel-Version von Stack Snippet async/await nicht unterstützt
const initPdf = (pdfUrl) => {
// Referenzieren Sie die CDN-Version von PDF.js, anstatt den ES6-Import zu verwenden
const pdfJS = pdfjsLib;
pdfJS.GlobalWorkerOptions.workerSrc = "https://unpkg.com/pdfjs-dist@3.9.179/build/pdf.worker.js";
return pdfJS.getDocument({
URL: pdfUrl,
cMapUrl: 'https://cdn.jsdelivr.net/npm/pdfjs-dist@3.9.179/cmaps/',
cMapPacked: wahr,
}).promise.then((pdf) => {
const totalPages = pdf.numPages;
for (let i = 0; i < totalPages; i++) {
renderPdfPage(pdf, pdfJS, i + 1);
}
});
}
// Async/await-Funktion zur Verwendung von Promise konvertiert, da die Babel-Version von Stack Snippet async/await nicht unterstützt
const renderPdfPage = (pdf, pdfJS, pageNum) => {
return pdf.getPage(pageNum).then((page) => {
const viewport = page.getViewport({
Maßstab: 1,0
});
let divPage = window.document.createElement("div");
if(!canvasRef || !canvasRef.current) return;
let canvas = divPage.appendChild(window.document.createElement("canvas"));
const canvasContext = canvas.getContext('2d');
canvas.height = viewport.height;
canvas.width = viewport.width;
const renderContext = { canvasContext, viewport };
const renderTask = page.render(renderContext);
renderTask.promise.then(function () {
const textContent = page.getTextContent();
return textContent;
}).then(function (textContent) {
const textLayer = document.querySelector(`.${styles.textLayer}`);
if (!textLayer) return;
textLayer.style.left = canvas.offsetLeft + 'px';
textLayer.style.top = canvas.offsetTop + 'px';
textLayer.style.height = canvas.offsetHeight + 'px';
textLayer.style.width = canvas.offsetWidth + 'px';
textLayer.style.setProperty('--scale-factor', '1.0');
pdfJS.renderTextLayer({
textContentSource: textContent,
Container: textLayer,
Ansichtsfenster: Ansichtsfenster,
textDivs: []
});
});
canvasRef.current.appendChild(divPage);
});
}
zurückkehren (
<div className={styles.cavasLayer}>
<canvas id="the-cavas" ref={canvasRef} />
{/**<div className={styles.textLayer}></div>**/}
</div>
);
}
const pdfUrl = „https://mozilla.github.io/pdf.js/web/compressed.tracemonkey-pldi-09.pdf“
const root = createRoot(document.getElementById("root"));
root.render(<StrictMode><Previewer pdfUrl={pdfUrl} /></StrictMode>);</code></pre>
<pre class="snippet-code-html lang-html Prettyprint-override"><code><script crossorigin src="https://unpkg.com/react@18/umd/react.development.js "></script>
<script crossorigin src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>
<script crossorigin src="https://unpkg.com/pdfjs-dist@3.9.179/build/pdf.js"></script>
<div id="root"></div></code></pre>
<p><br /></p>
问题
在
renderPdfPage
函数中,您创建了一个包含渲染PDF页面的canvas
元素的div
元素。然后将这些div
元素附加到一个canvas
元素上。然而,如果浏览器支持canvas
元素,则不会渲染canvas
元素的后代元素。根据canvas元素的规范:回退内容的定义如下:
解决方案
您需要将父级
canvas
更改为适当的元素。在下面的演示中,我使用了一个div
: