PDF.js tidak boleh memaparkan imej kanvas yang diberikan
P粉766520991
P粉766520991 2023-08-17 20:02:20
0
1
644
<p>Saya mempunyai komponen React yang memaparkan PDF. Apabila saya menggunakan komponen ini, saya hanya perlu menghantar URL PDF. </p> <pre class="brush:php;toolbar:false;"><Previewer pdfUrl={pdfUrl}></Previewer></pre> <p>Komponen mengendalikan butiran pratonton. Masalah yang saya hadapi ialah komponen ini tidak memaparkan PDF.Adakah saya kehilangan sesuatu? Apakah yang perlu saya lakukan untuk menyelesaikan masalah ini?下面是一个演示:</p> <p><br /></p> <pre class="snippet-code-js lang-js prettyprint-override"><code>const { StrictMode, useRef } = React; const { createRoot } = ReactDOM; gaya const = {}; const Pratonton = (props) => { const canvasRef = useRef(null); React.useEffect(() => { jika (props.pdfUrl) { initPdf(props.pdfUrl); } }, []); // Fungsi async/wait ditukar untuk menggunakan promise kerana versi Babel Stack Snippet tidak menyokong async/menunggu const initPdf = (pdfUrl) => { // Rujukan versi CDN PDF.js dan bukannya menggunakan import ES6 const pdfJS = pdfjsLib; pdfJS.GlobalWorkerOptions.workerSrc = "https://unpkg.com/pdfjs-dist@3.9.179/build/pdf.worker.js"; kembalikan pdfJS.getDocument({ url: pdfUrl, cMapUrl: 'https://cdn.jsdelivr.net/npm/pdfjs-dist@3.9.179/cmaps/', cMapPacked: benar, }).janji.kemudian((pdf) => { const totalPages = pdf.numPages; untuk (biar i = 0; i < jumlahHalaman; i++) { renderPdfPage(pdf, pdfJS, i + 1); } }); } // Fungsi async/wait ditukar untuk menggunakan promise kerana versi Babel Stack Snippet tidak menyokong async/menunggu const renderPdfPage = (pdf, pdfJS, pageNum) => { kembalikan pdf.getPage(pageNum).then((halaman) => { const viewport = page.getViewport({ skala: 1.0 }); biarkan divPage = window.document.createElement("div"); jika(!canvasRef || !canvasRef.current) kembali; biarkan kanvas = divPage.appendChild(window.document.createElement("kanvas")); 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(); kembalikan kandungan teks; }).then(function (textContent) { const textLayer = document.querySelector(`.${styles.textLayer}`); jika (!textLayer) kembali; 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, bekas: textLayer, viewport: viewport, textDivs: [] }); }); canvasRef.current.appendChild(divPage); }); } kembali ( <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>
P粉766520991
P粉766520991

membalas semua(1)
P粉298305266

Soalan

Unsur yang merupakan keturunan unsur renderPdfPage函数中,您创建了一个包含渲染PDF页面的canvas元素的div元素。然后将这些div元素附加到一个canvas元素上。然而,如果浏览器支持canvas元素,则不会渲染canvas. Mengikut spesifikasi elemen kanvas:

Rewind kandungan ditakrifkan seperti berikut:

Penyelesaian

Anda perlu menjadi ibu bapa 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>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan