"react": "^17.0.2"
1.react去预览pdf文件,并且这个组件可以在移动端展示,但要注意安装版本
"react-pdf": "^5.7.2"
直接上代码了,做了一个两页的分页,因为放在移动端有个问题,有个文件全部加载手机就卡死了,但这个分页也没解决问题,换了个文件就是好的,代码能优化的地方比较多,自行优化:
import React, { useState, useEffect, useCallback } from 'react';
import { Page, pdfjs } from "react-pdf";
import { Document } from 'react-pdf/dist/esm/entry.webpack';
pdfjs.GlobalWorkerOptions.workerSrc = `//cdnjs.cloudflare.com/ajax/libs/pdf.js/${pdfjs.version}/pdf.worker.js`;
const PdfViewer = ({ file }: any) => {
const [page_jsx, set_page_jsx]: [any[], React.Dispatch<React.SetStateAction<any[]>>] = useState<any[]>([]);
const [totalPages, setTotalPages]: [number, React.Dispatch<React.SetStateAction<number>>] = useState(0);
const [end_num, set_end_num]: [any, React.Dispatch<React.SetStateAction<any>>] = useState(6);
const viewMore = useCallback(() => {
let current_end_num = end_num + 5 <= totalPages ? end_num + 5: totalPages;
set_end_num(current_end_num);
const array = [];
for (let i = current_end_num - 6; i < current_end_num; i++) {
array.push(i);
}
let pageJsx = array?.map((a: any) => <Page scale={.5} key={`page_${a}`} pageNumber={a + 1}/>);
set_page_jsx((jsx_arr: any[]) => [...jsx_arr, ...pageJsx]);
}, [end_num, totalPages, set_end_num, set_page_jsx])
useEffect(() => {
const array = [];
if (end_num === 6) {
for (let i = totalPages < 6 ? 0: end_num - 6; i < (totalPages < 6 ? totalPages: end_num); i++) {
array.push(i);
}
let pageJsx = array?.map((a: any) => <Page scale={.5} key={`page_${a}`} pageNumber={a + 1}/>);
set_page_jsx((jsx_arr: any[]) => [...jsx_arr, ...pageJsx]);
}
}, [end_num, set_page_jsx, totalPages])
return (
<div style={{ width: '100%', height: '100vh', overflow: 'auto' }}>
<Document
className={"pdf-content"}
file={file}
onLoadSuccess={({ numPages }: any) => setTotalPages(numPages)}
>
{page_jsx?.map((page: any) => page)}
{totalPages > end_num && <div style={{height: '40px', lineHeight: '40px', textAlign: 'center'}} onClick={() => viewMore()}>View more</div>}
</Document>
</div>
);
};
export default PdfViewer;
2. pdfjs-dist
"pdfjs-dist": "^2.5.207",这个插件的版本尤其要记录下,网上查了好多,只把代码放上去,如果版本不对,引入文件路径是不存在的,那么还是直接放代码吧,如第一种方法自行优化下:
import React, { useCallback, useEffect, useRef, useState } from 'react';
const pdfjsLib = require('pdfjs-dist/es5/build/pdf.js');
pdfjsLib.GlobalWorkerOptions.workerSrc = `//cdnjs.cloudflare.com/ajax/libs/pdf.js/${pdfjsLib.version}/pdf.worker.js`;
const PdfViewer = ({ file }: any) => {
const [totalPages, setTotalPages]: [number, React.Dispatch<React.SetStateAction<number>>] = useState(0);
const [end_num, set_end_num]: [any, React.Dispatch<React.SetStateAction<any>>] = useState(6);
const canvasRefs: any = useRef([]);
const pageNums: any = useRef([]);
const renderPage = useCallback(async (pdf: any, endNum: any) => {
pageNums.current = new Array(endNum)?.fill(0).map((_, i) => i + 1);
// 渲染每一页
for (let i = totalPages < 6 ? 1: endNum - 5; i <= (totalPages < 6 ? totalPages: endNum); i++) {
const page = await pdf.getPage(i);
const viewport = page.getViewport({ scale: 1.5 });
// 创建canvas元素
const canvas = document.createElement('canvas');
const context = canvas.getContext('2d');
canvas.height = viewport.height;
canvas.width = viewport.width;
// 将canvas添加到DOM中
const canvasContainer: any = document.getElementById('pdf-container');
canvasContainer.appendChild(canvas);
// 存储canvas的引用以便后续操作
canvasRefs.current[i - 1] = canvas;
// 渲染页面
const renderContext = {
canvasContext: context,
viewport: viewport
};
await page.render(renderContext);
}
}, [totalPages])
useEffect(() => {
async function loadPdf() {
const loadingTask = pdfjsLib.getDocument(file);
const pdf: any = await loadingTask.promise;
// 获取总页数
const numPages: any = pdf.numPages;
setTotalPages(numPages);
renderPage(pdf, end_num);
}
if (file && end_num === 6) {
loadPdf();
}
}, [file, end_num, renderPage])
return (
<>
<div id="pdf-container">
{/* 在这里,canvas元素将被动态添加到这个容器中 */}
</div>
{totalPages > end_num && <div onClick={async () => {
if (end_num < totalPages) {
let current_end_num = end_num + 5 <= totalPages ? end_num + 5: totalPages;
set_end_num(current_end_num);
const loadingTask = pdfjsLib.getDocument(file);
const pdf: any = await loadingTask.promise;
renderPage(pdf, current_end_num);
}
}} style={{height: '40px', lineHeight: '40px', textAlign: 'center'}}>View more</div>}
</>
);
};
export default PdfViewer;