• reactHooks+antd+react-pdf封装pdf预览组件


    1、下载插件:

    npm i react-pdf

    2、PdfPreview/index.tsx

    /*
      进入该组件时,通过路由传递path进来,形如:
        history.push({ pathname: '/pdfPreview', query: { path } })
    */
    import React, { useState } from 'react'
    import { Spin, Tooltip, Input } from 'antd'
    import {
      LeftOutlined,
      RightOutlined,
      PlusCircleOutlined,
      MinusCircleOutlined,
      FullscreenOutlined,
      FullscreenExitOutlined,
      ArrowLeftOutlined
    } from '@ant-design/icons'
    import styles from './index.less'
    
    import { Document, Page, pdfjs } from 'react-pdf'
    pdfjs.GlobalWorkerOptions.workerSrc = `//cdnjs.cloudflare.com/ajax/libs/pdf.js/${pdfjs.version}/pdf.worker.js`
    
    import { history } from 'umi'
    
    const PdfPreview: React.FC<{}> = (Props: any) => {
      const [pageNumber, setPageNumber] = useState(1)
      const [pageNumberInput, setPageNumberInput] = useState(1)
      const [pageNumberFocus, setPageNumberFocus] = useState(false)
      const [numPages, setNumPages] = useState(1)
      const [pageWidth, setPageWidth] = useState(600)
      const [fullscreen, setFullscreen] = useState(false)
      const { location } = history
      const { path }: any = location.query
    
      const onDocumentLoadSuccess = ({ numPages }: any) => {
        setNumPages(numPages)
      }
      const lastPage = () => {
        if (pageNumber == 1) return
        const page = pageNumber - 1
        setPageNumber(page)
        setPageNumberInput(page)
      }
      const nextPage = () => {
        if (pageNumber === numPages) return
        const page = pageNumber + 1
        setPageNumber(page)
        setPageNumberInput(page)
      }
      const onPageNumberFocus = (e: any) => {
        setPageNumberFocus(true)
      }
      const onPageNumberBlur = (e: any) => {
        setPageNumberFocus(false)
        setPageNumberInput(pageNumber)
      }
      const onPageNumberChange = (e: any) => {
        let value = e.target.value
        value = value <= 0 ? 1 : value
        value = value >= numPages ? numPages : value
        setPageNumberInput(value)
      }
      const toPage = (e: any) => {
        setPageNumber(Number(e.target.value))
      }
      const pageZoomOut = () => {
        if (pageWidth <= 600) return
        const width = pageWidth * 0.8
        setPageWidth(width)
      }
      const pageZoomIn = () => {
        const width = pageWidth * 1.2
        setPageWidth(width)
      }
      const pageFullscreen = () => {
        if (fullscreen) {
          setFullscreen(false)
          setPageWidth(600)
        } else {
          setFullscreen(true)
          setPageWidth(window.screen.width - 40)
        }
      }
    
      return (
        <div className={styles.view}>
          <ArrowLeftOutlined className={styles.back} onClick={() => history.goBack()} />
          <div className={styles.pageContainer}>
            <Document file={path} onLoadSuccess={onDocumentLoadSuccess} loading={<Spin size="large" />}>
              <Page pageNumber={pageNumber} width={pageWidth} loading={<Spin size="large" />} />
            </Document>
          </div>
          <div className={styles.pageTool}>
            <Tooltip title={pageNumber == 1 ? '已是第一页' : '上一页'}>
              <LeftOutlined className={styles.outlined} onClick={lastPage} />
            </Tooltip>
            <Input
              value={pageNumberFocus ? pageNumberInput : pageNumber}
              onFocus={onPageNumberFocus}
              onBlur={onPageNumberBlur}
              onChange={onPageNumberChange}
              onPressEnter={toPage}
              type="number"
            />
            / {numPages}
            <Tooltip title={pageNumber == numPages ? '已是最后一页' : '下一页'}>
              <RightOutlined className={styles.outlined} onClick={nextPage} />
            </Tooltip>
            <Tooltip title="放大">
              <PlusCircleOutlined className={styles.outlined} onClick={pageZoomIn} />
            </Tooltip>
            <Tooltip title="缩小">
              <MinusCircleOutlined className={styles.outlined} onClick={pageZoomOut} />
            </Tooltip>
            <Tooltip title={fullscreen ? '恢复默认' : '适合窗口'}>
              {fullscreen ? (
                <FullscreenExitOutlined className={styles.outlined} onClick={pageFullscreen} />
              ) : (
                <FullscreenOutlined className={styles.outlined} onClick={pageFullscreen} />
              )}
            </Tooltip>
          </div>
        </div>
      )
    }
    
    export default PdfPreview

    PdfPreview/index.less

    .view {
      display: flex;
      justify-content: center;
      height: calc(100vh - 206px);
      padding: 20px 0;
      overflow: auto;
      background: #444;
      .back {
        position: absolute;
        top: 0;
        left: 0;
        color: #fff;
        font-size: 20px;
        transition: color .3s;
        width: 40px;
        line-height: 30px;
        background-color: red;
      }
      .back:hover {
        // color: #1890ff;
      }
      .pageContainer {
        width: max-content;
        max-width: 100%;
        box-shadow: rgba(0, 0, 0, 0.2) 0px 2px 4px 0px;
      }
      .pageTool {
        position: absolute;
        bottom: 20px;
        padding: 8px 15px;
        color: white;
        background: rgb(66, 66, 66);
        border-radius: 15px;
        .outlined {
          margin: 0 10px;
          user-select: none;
        }
        input {
          display: inline-block;
          width: 50px;
          height: 24px;
          margin-right: 10px;
          text-align: center;
        }
        input::-webkit-outer-spin-button,
        input::-webkit-inner-spin-button {
          -webkit-appearance: none;
        }
        input[type='number'] {
          -moz-appearance: textfield;
        }
      }
    }
    View Code

    3、效果:

  • 相关阅读:
    2017 《Java》预备作业计科1502宋奇蕊
    在 Kubernetes 上调度 GPU 资源
    ceph
    网络设备的 38 个知识点
    CF1066 ABCD
    单调队列优化动态规划
    对拍
    【关于此博客】
    使用Morphia框架操作mongodb
    通过mybatis读取数据库数据并提供rest接口访问
  • 原文地址:https://www.cnblogs.com/wuqilang/p/15012849.html
Copyright © 2020-2023  润新知