1. 程式人生 > 其它 >reactHooks+antd+react-pdf封裝pdf預覽元件

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 SchoolYear: 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 SchoolYear

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