React项目react-pdf使用

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 />,
    },
  ];

实现效果

相关推荐
群联云防护小杜7 分钟前
构建分布式高防架构实现业务零中断
前端·网络·分布式·tcp/ip·安全·游戏·架构
ohMyGod_1231 小时前
React16,17,18,19新特性更新对比
前端·javascript·react.js
前端小趴菜051 小时前
React-forwardRef-useImperativeHandle
前端·vue.js·react.js
@大迁世界1 小时前
第1章 React组件开发基础
前端·javascript·react.js·前端框架·ecmascript
Hilaku1 小时前
从一个实战项目,看懂 `new DataTransfer()` 的三大妙用
前端·javascript·jquery
爱分享的程序员1 小时前
前端面试专栏-算法篇:20. 贪心算法与动态规划入门
前端·javascript·node.js
我想说一句1 小时前
事件委托与合成事件:前端性能优化的"偷懒"艺术
前端·javascript
爱泡脚的鸡腿1 小时前
Web第二次笔记
前端·javascript
良辰未晚1 小时前
Canvas 绘制模糊?那是你没搞懂 DPR!
前端·canvas
Dream耀2 小时前
React合成事件揭秘:高效事件处理的幕后机制
前端·javascript