搜尋

首頁  >  問答  >  主體

PDF.js無法顯示渲染的畫布影像

<p>我有一個顯示PDF的React元件。當我使用這個組件時,我只需要傳遞PDF的URL。 </p> <pre class="brush:php;toolbar:false;"><Previewer pdfUrl={pdfUrl}></Previewer></pre> <p>元件處理預覽的細節。我遇到的問題是這個組件不顯示PDF。我是否遺漏了什麼?我該怎麼做來解決這個問題?下面是示範:</p> <p><br />></p> <pre class="snippet-code-js lang-js Prettyprint-override"><code>const { StrictMode, useRef } = React; const { createRoot } = ReactDOM; 常量樣式= {}; const Previewer = (props) =>; { const canvasRef = useRef(null); React.useEffect(() => { if (props.pdfUrl) { initPdf(props.pdfUrl); } }, []); // 將 async/await 函數轉換為使用 Promise,因為 Stack Snippet 的 Babel 版本不支援 async/await const initPdf = (pdfUrl) =>; { // 引用PDF.js的CDN版本而不是使用ES6導入 const pdfJS = pdfjsLib; pdfJS.GlobalWorkerOptions.workerSrc = "https://unpkg.com/pdfjs-dist@3.9.179/build/pdf.worker.js"; 返回 pdfJS.getDocument({ 網址: pdfUrl, cMapUrl: 'https://cdn.jsdelivr.net/npm/pdfjs-dist@3.9.179/cmaps/', cMapPacked:真, }).promise.then((pdf) => { const 總頁數 = pdf.numPages; for (令 i = 0; i < 總頁數; i ) { renderPdfPage(pdf, pdfJS, i 1); } }); } // 將 async/await 函數轉換為使用 Promise,因為 Stack Snippet 的 Babel 版本不支援 async/await const renderPdfPage = (pdf, pdfJS, pageNum) =>; { 傳回 pdf.getPage(pageNum).then((page) => { const viewport = page.getViewport({ 規模:1.0 }); 讓 divPage = window.document.createElement("div"); if(!canvasRef || !canvasRef.current) 回傳; let canvas = divPage.appendChild(window.document.createElement("canvas")); const canvasContext = canvas.getContext('2d'); 畫布.高度 = 視口.高度; 畫布.寬度=視口.寬度; const renderContext = { canvasContext, 視口 }; const renderTask = page.render(renderContext); renderTask.promise.then(function () { const textContent = page.getTextContent(); 返回文字內容; }).then(函數(文字內容){ const textLayer = document.querySelector(`.${styles.textLayer}`); if (!textLayer) 返回; 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({ 文字內容來源:文字內容, 容器:文字圖層, 視口: 視口, 文字分區:[] }); }); canvasRef.current.appendChild(divPage); }); } 返回 ( <div className={styles.cavasLayer}> > {/**
**/}
); } const pdfUrl =“https://mozilla.github.io/pdf.js/web/compressed.tracemonkey-pldi-09.pdf” const root = createRoot(document.getElementById("root")); root.render(<預覽器 pdfUrl={pdfUrl} //>);; <pre class="snippet-code-html lang-html Prettyprint-override"><code><腳本跨域src="https://unpkg.com/react@18/umd/react.development. js “></腳本> <腳本跨域 src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script> <腳本跨域 src="https://unpkg.com/pdfjs-dist@3.9.179/build/pdf.js"></script> <div id="root"></div></code></pre> <p><br />></p>
P粉766520991P粉766520991453 天前580

全部回覆(1)我來回復

  • P粉298305266

    P粉2983052662023-08-18 15:50:09

    問題

    renderPdfPage函數中,您建立了一個包含渲染PDF頁面的canvas元素的div元素。然後將這些div元素附加到一個canvas元素上。然而,如果瀏覽器支援canvas元素,則不會渲染canvas元素的後代元素。根據canvas元素的規範

    回退內容的定義如下:

    解決方案

    您需要將父級canvas變更為適當的元素。在下面的演示中,我使用了一個div

    const { StrictMode, useRef } = React;
    const { createRoot } = ReactDOM;
    
    const styles = {};
    
    const Previewer = (props) => {
    
        const pdfContainerRef = useRef(null);
    
        React.useEffect(() => {
            if (props.pdfUrl) {
                initPdf(props.pdfUrl);
            }
        }, []);
        
        // Converted async/await function to use promise because Stack Snippet's Babel version does not support async/await
        const initPdf = (pdfUrl) => {
            // Reference CDN version of PDF.js instead of using ES6 import
            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: true,
            }).promise.then((pdf) => {
                const totalPages = pdf.numPages;
                for (let i = 0; i < totalPages; i++) {
                    renderPdfPage(pdf, pdfJS, i + 1);
                }
            });
        }
        
        // Converted async/await function to use promise because Stack Snippet's Babel version does not support async/await
        const renderPdfPage = (pdf, pdfJS, pageNum) => {
            return pdf.getPage(pageNum).then((page) => {
                const viewport = page.getViewport({
                    scale: 1.0
                });
                let divPage = window.document.createElement("div");
                if(!pdfContainerRef || !pdfContainerRef.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,
                        viewport: viewport,
                        textDivs: []
                    });
                });
                pdfContainerRef.current.appendChild(divPage);
            });
        }
    
        return (
            <div className={styles.cavasLayer}>
                <div id="pdf-container" ref={pdfContainerRef} />
                {/**<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>);
    <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>

    回覆
    0
  • 取消回覆