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

实现效果

相关推荐
觉醒法师几秒前
HarmonyOS开发 - 电商App实例二( 网络请求http)
前端·http·华为·typescript·harmonyos·ark-ts
沈剑心几秒前
Kotlin的协程,真能提升编程效率么?
android·前端·kotlin
堕落年代11 分钟前
Vue主流的状态保存框架对比
前端·javascript·vue.js
OpenTiny社区22 分钟前
TinyVue的DatePicker 组件支持日期面板单独使用啦!
前端·vue.js
冴羽22 分钟前
Svelte 最新中文文档教程(22)—— Svelte 5 迁移指南
前端·javascript·svelte
树上有只程序猿26 分钟前
Vue3组件通信:多个实战场景,轻松玩转复杂数据流!
前端·vue.js
青红光硫化黑31 分钟前
React基础之useEffect
javascript·react.js·ecmascript
剪刀石头布啊34 分钟前
css属性值计算过程
前端·css
Nine eight seven four35 分钟前
pdf修改内容:分享5款好用的工具
pdf
bin915339 分钟前
DeepSeek 助力 Vue3 开发:打造丝滑的表格(Table)之添加列宽调整功能,示例Table14基础固定表头示例
前端·javascript·vue.js·ecmascript·deepseek