react-pdf 实现 pdf 在线预览(翻页、放大缩小等)

原创文章,转载请注明出处,谢谢~
https://mp.weixin.qq.com/s/EyFKeMujSmcEPQXjYNBL8w

react实现pdf文档可翻页查看,可放大缩小及全屏等功能,选的是 react-pdf 插件, react-file-viewer 插件也试了下,可以查看pdf,不过是一次性加载全部,最终选了前者

插件引用

Ant Design Pro + react-pdf插件

插件地址:

https://www.npmjs.com/package/react-pdf

1、安装插件
$ npm install react-pdf 
# or
$ yarn add react-pdf
2、组件引用
import { Document, Page } from "react-pdf";
3、简单使用

  

Page {pageNumber} of {numPages}

运行后报错:

解决:

import { Document, Page, pdfjs } from "react-pdf";
pdfjs.GlobalWorkerOptions.workerSrc = `//cdnjs.cloudflare.com/ajax/libs/pdf.js/${pdfjs.version}/pdf.worker.js`;

可以加载出pdf即可

实现功能

先按自己想要的样式把界面搭好

一些功能主要是修改Page组件参数来达到想要的效果


1、翻页、跳到指定页面

修改PagepageNumber属性值,加一些特定约束,比如已经翻到了第一页或者最后一页,输入的数值最小为1,最大为pdf的总页数值

2、放大缩小、一键适应窗口

修改Pagewidth属性值,如果单纯放大缩小,也可以用scale属性,不过跟宽度同时用会有点乱,索性只用了宽度

放大缩小过程中发现问题,页面居中用的flex布局,pdf放大溢出后,无法通过滚动条完全展示

子元素加了样式,已修复

width:max-content;
max-width:100%;
3、最终源码

样式:

.view {
  background:#444;
  display: flex;
  justify-content: center;
  height: 100vh;
  padding: 50px 0;
  overflow: auto;
}
.pageContainer {
  box-shadow: rgba(0, 0, 0, 0.2) 0px 2px 4px 0px;
  width:max-content;
  max-width:100%;
}
.pageTool{
  position: absolute;
  bottom: 20px;
  background: rgb(66, 66, 66);
  color: white;
  padding: 8px 15px;
  border-radius: 15px;
  i{
    padding: 5px;
    margin:0 5px;
    &:hover{
      background: #333;
    }
  }
  input{
    display: inline-block;
    width: 50px;
    text-align: center;
    margin-right: 10px;
    height: 24px;
  }
  input::-webkit-outer-spin-button,
  input::-webkit-inner-spin-button {
    -webkit-appearance: none;
  }
  input[type="number"]{
    -moz-appearance: textfield;
  }
}

js:

import React, { PureComponent } from 'react';
import { Icon, Spin, Tooltip,Input } from 'antd';
import styles from './File.less';

import { Document, Page, pdfjs } from "react-pdf";
pdfjs.GlobalWorkerOptions.workerSrc = `//cdnjs.cloudflare.com/ajax/libs/pdf.js/${pdfjs.version}/pdf.worker.js`;

class File extends PureComponent {

  state = {
    pageNumber: 1,
    pageNumberInput: 1,
    pageNumberFocus: false,
    numPages: 1,
    pageWidth: 600,
    fullscreen: false
  };

  onDocumentLoadSuccess = ({ numPages }) => {
    this.setState({ numPages: numPages })
  }

  lastPage = () => {
    if (this.state.pageNumber == 1) {
      return
    }
    const page = this.state.pageNumber - 1
    this.setState({ pageNumber: page ,pageNumberInput:page})
  }
  nextPage = () => {
    if (this.state.pageNumber == this.state.numPages) {
      return
    }
    const page = this.state.pageNumber + 1
    this.setState({ pageNumber: page ,pageNumberInput:page})
  }
  onPageNumberFocus = e => {
    this.setState({ pageNumberFocus: true })
  };
  onPageNumberBlur = e => {
    this.setState({ pageNumberFocus: false ,pageNumberInput:this.state.pageNumber})
  };
  onPageNumberChange = e => {
    let value=e.target.value
    value=value<=0?1:value;
    value=value>=this.state.numPages?this.state.numPages:value;
    this.setState({ pageNumberInput: value })
  };
  toPage = e => {
    this.setState({ pageNumber: Number(e.target.value) })
  };

  pageZoomOut = () => {
    if (this.state.pageWidth <= 600) {
      return
    }
    const pageWidth = this.state.pageWidth * 0.8
    this.setState({ pageWidth: pageWidth })
  }
  pageZoomIn = () => {
    const pageWidth = this.state.pageWidth * 1.2
    this.setState({ pageWidth: pageWidth })
  }

  pageFullscreen = () => {
    if (this.state.fullscreen) {
      this.setState({ fullscreen: false, pageWidth: 600 })
    } else {
      this.setState({ fullscreen: true, pageWidth: window.screen.width - 40 })
    }
  }

  render() {
    const { pageNumber, pageNumberFocus, pageNumberInput,numPages, pageWidth, fullscreen } = this.state;
    return (
      
} > } />
/ {numPages}
); } } export default props => ( );

效果图

问题

1、请求pdf文件携带cookie

直接在 不行,要放到 state
见插件相关issues:
https://github.com/wojtekmaj/react-pdf/issues/308#issuecomment-443538284

你可能感兴趣的:(react-pdf 实现 pdf 在线预览(翻页、放大缩小等))