原创文章,转载请注明出处,谢谢~
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、翻页、跳到指定页面
修改Page
的pageNumber
属性值,加一些特定约束,比如已经翻到了第一页或者最后一页,输入的数值最小为1,最大为pdf的总页数值
2、放大缩小、一键适应窗口
修改Page
的width
属性值,如果单纯放大缩小,也可以用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