博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
react下实现一个PDF展示组件
阅读量:6329 次
发布时间:2019-06-22

本文共 4005 字,大约阅读时间需要 13 分钟。

简介:在react的antd-pro的框架下展示本地的PDF文件

效果图:

clipboard.png

一、插件选取。

听说过大名鼎鼎的PDF.js,但是因为是在react框架下,所以选取了两个可行的插件

两个插件都是对PDF进行的封装。两个插件都进行了尝试,相对而言react-pdf功能更强大并且文档也比较清晰,但是使用也会相对复杂一点。最后使用的是react-pdf-js这个插件。

二、展示选择的文件。

react-pdf-js

第一步:展示一个本地文档。

按照官方的文档:

render() {  let pagination = null;  if (this.state.pages) {    pagination = this.renderPagination(this.state.page, this.state.pages);  }  return (    
{pagination}
)}

注意:官方文档没有任何说明。此处的file是一个require过来的文件。

例子:要加载一个'E:\1.pdf',那么应该那么配置:

const PDFTest = require('E:\\1.pdf');render() {  let pagination = null;  if (this.state.pages) {    pagination = this.renderPagination(this.state.page, this.state.pages);  }  return (    
{pagination}
)}

第二步:根据文件选择框更改文件。

这一步被卡住过,刚开始想的是根据选择的文件然后获取文件的实际地址然后运用require去获取文件,但是实现的时候发现浏览器的安全策略无法让浏览器获取文件的真实路径。

但是!我们可以通过创建一个对象去获取文件的一个blob。使用创建一个file文件,并且react-pdf-js可以直接接受一个这样子的文件。
部分代码如下:

handleButtonOnChange = e =>{  if (e.currentTarget.files.length === 0) return;  const url = window.URL.createObjectURL(e.currentTarget.files[0]);  this.setState({    pdfTest: {      key:url,      file:url,    },  })}createPDF = () =>{  const { pageNumber, numPages, pdfTest } = this.state;  if(!pdfTest) return;  return(    

第 {pageNumber} 页 共 {numPages} 页

)}render() { return (
{this.createPDF()}
);}

此处还有一个坑,就是key这个值。在文档中没有提到这个值,并且在源代码中也没有怎么出现这个值。这个key值应该是标识每个文件的一个唯一标识,当key值不同的时候会重新渲染canvas。

以下做法不推荐:

在之前我没发现这个之前,通过修改源码的改为:

componentWillReceiveProps(newProps) {  const {    page,    scale,    file:oldfile,    onDocumentComplete,    cMapUrl,    cMapPacked,  } = this.props;  const { pdf } = this.state;  const { file:newfile } = newProps;  if(newfile !== oldfile){    PdfJsLib.GlobalWorkerOptions.workerSrc = '//cdnjs.cloudflare.com/ajax/libs/pdf.js/2.0.943/pdf.worker.js';    PdfJsLib.getDocument({ url: newfile, cMapUrl, cMapPacked }).then((newPdf) => {      this.setState({ pdf:newPdf });      if (onDocumentComplete) {        onDocumentComplete(newPdf._pdfInfo.numPages); // eslint-disable-line      }      pdf.getPage(page).then(p => this.drawPDF(p));    });  }else{    if (newProps.page !== page) {      pdf.getPage(newProps.page).then(p => this.drawPDF(p));    }    if (newProps.scale !== scale) {      pdf.getPage(newProps.page).then(p => this.drawPDF(p));    }  }}

手动实现了这个功能,但是这个判定方法存在一些问题,只有再加入一个变量去判断才会完善,就完全和他的key这个值一样,但是知道key值之后就没有再对源码进行修改了。

第三笔:其他功能。

翻页以及跳页:

handleTurnPage = e =>{  const { pageNumber, numPages, turnPageNumber } = this.state;  if(!numPages){    message.warning('请先选择PDF文件');    return;  }  let newPageNumber = pageNumber;  switch (e.target.id) {    case 'pageUp':      newPageNumber -= 1;      if(newPageNumber <= 0){        message.warning('已经是第一页');        return;      }      break;    case 'pageDown':      newPageNumber += 1;      if(newPageNumber > numPages){        message.warning('已经是最后一页');        return;      }      break;    case 'numberPage':      if(!turnPageNumber){        message.warning('请先输入数字');        return;      }else if(turnPageNumber <= 0||turnPageNumber > numPages){        message.warning('请输入在页面范围内的数字');        return;      }      newPageNumber = turnPageNumber;      break;    default:      break;  }  this.setState({    pageNumber:newPageNumber,  })}render() {  return (    
{this.createPDF()}
);}

完整代码:。

react-pdf

这个插件的功能很强大,但是使用就相对而言比较复杂。官方的

由于最后使用的是另外的一个插件。这里就只写一下踩坑记录。

1、file参数。

在这里file这个参数和react-pdf-js的不一样,在require的时候都是一样的,但是在转换的时候不用创建URL对象,直接将input里面的file传过去即可。并且不需要key。

例子:

handleButtonOnChange = e =>{  if (e.currentTarget.files.length === 0) return;  this.setState({    pdfTest: {      file:e.currentTarget.files[0],    },  })}

2、不显示text layers

PDF存在一个问题无法选择里面的文字以及链接,但是PDF.js通过在里面添加一层文本层用于辅助选取,但是在这个插件里面会存在一个重影,导致文字显示效果不佳,如图:

clipboard.png

在官方文档中提到使用SVG可以解决这个问题,但是SVG选择出来是乱码。所以在使用的时候希望屏蔽掉text layer,在文档中也有提到,在page中设置。

以上是所有内容。

转载地址:http://fcwoa.baihongyu.com/

你可能感兴趣的文章
美国人的网站推广方式千奇百怪
查看>>
java web学习-1
查看>>
用maven+springMVC创建一个项目
查看>>
linux设备驱动第四篇:以oops信息定位代码行为例谈驱动调试方法
查看>>
redis知识点整理
查看>>
Hello World
查看>>
Spring3全注解配置
查看>>
ThreadLocal真会内存泄露?
查看>>
IntelliJ IDEA
查看>>
低版本mybatis不能用PageHeper插件的时候用这个分页
查看>>
javaweb使用自定义id,快速编码与生成ID
查看>>
[leetcode] Add Two Numbers
查看>>
elasticsearch suggest 的几种使用-completion 的基本 使用
查看>>
04-【MongoDB入门教程】mongo命令行
查看>>
Hadoop HA元数据备份
查看>>
字符串与整数之间的转换
查看>>
断点传输HTTP和URL协议
查看>>
redis 数据类型详解 以及 redis适用场景场合
查看>>
mysql服务器的主从配置
查看>>
巧用AJAX技术,通过updatePanel控件实现局部刷新
查看>>