react项目中展示pdf
1.安装依赖
npm install react-pdf
2.封装一个根据url展示pdf的组件
javascript
import { useState } from 'react'
import { Card } from "antd";
import style from './index.module.css'
import {message ,} from 'antd'
import PropTypes from 'prop-types';
import { Document, Page, pdfjs } from 'react-pdf'
import { DownOutlined, UpOutlined, MinusCircleOutlined, PlusCircleOutlined } from '@ant-design/icons';
import 'react-pdf/dist/esm/Page/AnnotationLayer.css'
import 'react-pdf/dist/esm/Page/TextLayer.css';
// 配置 PDF.js 的 worker 文件
pdfjs.GlobalWorkerOptions.workerSrc = new URL('pdfjs-dist/build/pdf.worker.min.js', import.meta.url).toString()
export default function PdfViewModal(props) {
const [pageNumber, setPageNumber] = useState(1);
const [numPages, setNumPages] = useState(1);
const [scale, setScale] = useState(1.0);
const onDocumentLoadSuccess = ({ numPages }) => {
setNumPages(numPages)
}
//上一页
const lastPage = () =>{
if (pageNumber == 1) {
message.info('已是第一页');
return;
}
const page = pageNumber - 1;
setPageNumber(page);
}
//下一页
const nextPage = () =>{
if (pageNumber == numPages) {
message.info("已是最后一页");
return;
}
const page = pageNumber + 1;
setPageNumber(page);
}
//缩小
const pageZoomOut = () => {
if (scale <= 0.5) {
message.info('已缩放至最小');
return;
}
const newScale = scale - 0.1;
setScale(newScale);
}
//放大
const pageZoomIn = () => {
if (scale >= 1) {
message.info('已放大至最大');
return;
}
const newScale = scale + 0.1;
setScale(newScale);
}
return (
<>
<div className={style.setting_box}>
<div className={style.setting_box_item} onClick={lastPage}><UpOutlined /></div>
<div className={style.setting_box_item}>{pageNumber}/{numPages}</div>
<div className={style.setting_box_item} onClick={nextPage}><DownOutlined /></div>
<div className={style.setting_box_item} onClick={pageZoomIn}><PlusCircleOutlined /></div>
<div className={style.setting_box_item} onClick={pageZoomOut}><MinusCircleOutlined /></div>
</div>
<Card className={style.pdf_box}>
<Document
file={new URL(props.url, import.meta.url).toString()}
onLoadSuccess={onDocumentLoadSuccess}
>
<Page pageNumber={pageNumber} scale={scale} />
</Document>
</Card>
{/* <div >
</div> */}
</>
)
}
// 定义 propTypes 验证
PdfViewModal.propTypes = {
url: PropTypes.string.isRequired,
};
// 设置默认 props
/* PdfViewModal.defaultProps = {
url: '',
}; */
css样式
css
.setting_box {
display: flex;
justify-content: space-between;
height: 16px;
align-items: center;
background-color: #444;
opacity: 0.5;
border-radius: 20px;
padding: 3px 8px;
width: 125px;
margin: 0 auto;
}
.setting_box_item {
color: #ffffff;
}
.pdf_box {
display: flex;
justify-content: center;
height: calc(100vh - 125px);
margin-top: 10px;
overflow-y: scroll;
}
3.调用组件
javascript
const items = [
{
key: '1',
label: '课程内容',
children: (
<>
{courseContent.pdfUrl && <PdfViewModal url={courseContent.pdfUrl} />}
</>
),
icon: <FilePdfFilled />,
},
{
key: '2',
label: '课程视频',
children: (
<>
{courseContent.videoUrl && <VideoViewModal url={courseContent.videoUrl} ref={voideChildRef} />}
</>
),
icon: <VideoCameraFilled />,
},
{
key: '3',
label: '知识图谱',
children: (
<>
<ChartViewModal />
</>
),
icon: <InteractionFilled />,
},
];