• React 中使用 pdf.js 将 pdf 转换成图片


    pdf.js 主要用于在网页上展示 pdf 文档,是一个用户解析和渲染 pdf 文件的开源库。本文主要介绍如何在 react 中使用 pdf.js 解析 pdf 文件,并最终转换成图片形式。

    一、 安装 pdf.js 库文件

    要在 react 中使用 pdf.js,首先需要安装对应的依赖。对此 pdf.js 提供了 pdfjs-dist 库,我们可以通过 npm 进行下载.

    npm install pdfjs-dist --save

    二、 在组件中使用。

    在 pdf.js 的 issues 中找到 pdf.js 在 react 中的使用方法,参考 issue:Using pdf.js in React】 

    1. 引入 pdf.js 文件

    2. 编写文件上传组件

    3. 编写上传属性和方法

    4. pdf 解析

    5. canvas 设置

    6. 生成图片

    从上面的代码可以看出,由 pdf 生成图片主要需要经历以下几个过程:

    上传 pdf 文件 -> 解析 pdf -> 生成 canvas 对象 -> 转换成图片 -> (插入页面或导出文件)

    三、在项目中查看效果

    导入后查看

    完整的 jsx 代码如下:

      1 import React from 'react';
      2 import { Modal } from 'antd'
      3 import * as PDFJS from "pdfjs-dist";
      4 import pdfjsWorker from 'pdfjs-dist/build/pdf.worker.entry';
      5 
      6 const Dragger = Upload.Dragger;
      7 
      8 PDFJS.GlobalWorkerOptions.workerSrc = pdfjsWorker;
      9 
     10 export default class ImportPdf extends React.Component {
     11     state = {
     12         pdf: '',
     13     }
     14 
     15     openPage(pdfFile, pageNumber, context) {
     16         var scale = 2;
     17         pdfFile.getPage(pageNumber).then(function (page) {
     18             // reference canvas via context
     19             const viewport = page.getViewport(scale);
     20             var canvas = context.canvas;
     21             canvas.width = viewport.width;
     22             canvas.height = viewport.height;
     23             canvas.style.width = "100%";
     24             canvas.style.height = "100%";
     25             var renderContext = {
     26                 canvasContext: context,
     27                 viewport: viewport
     28             };
     29             page.render(renderContext);
     30         });
     31         return;
     32     }
     33 
     34     exportImg(self) {
     35         // 将 canvas 导出成 img
     36         $('#pdf-container canvas').each(function (index, ele) {
     37             var canvas = document.getElementById("pageNum" + (index + 1));
     38             // 将 canvas 转成 base64 格式的图片
     39             let base64ImgSrc = canvas.toDataURL("image/png")
     40             const img = document.createElement("img")
     41             img.setAttribute('class', 'pdf-img');
     42             img.src = base64ImgSrc
     43             img.style.width = '100%';
     44             // 将图片挂载到 dom 中
     45             $('#pdf-container').append(img);
     46         });
     47     }
     48 
     49     readPdf(file) { 
     50         // pdf.js无法直接打开本地文件,所以利用FileReader转换
     51         const reader = new FileReader();
     52         reader.readAsArrayBuffer(file);
     53         reader.onload = function (e) {
     54             const typedarray = new Uint8Array(this.result);
     55             const loadingTask = PDFJS.getDocument(typedarray);
     56             loadingTask.promise.then(function (pdf) {
     57                 if (pdf) {
     58                     // pdf 总页数
     59                     const pageNum = pdf.numPages;
     60                     for (let i = 1; i <= pageNum; i++) {
     61                         // 生成每页 pdf 的 canvas
     62                         const canvas = document.createElement('canvas');
     63                         canvas.id = "pageNum" + i;
     64                         // 将 canvas 添加到 dom 中
     65                         $('#pdf-container').append(canvas);
     66                         const context = canvas.getContext('2d');
     67                         self.openPage(pdf, i, context);
     68                     }
     69                     setTimeout(() => {
     70                         self.exportImg(self)
     71                     }, 1000);
     72                 }
     73             }).catch(function (reason) {
     74                 console.error("Error: " + reason);
     75             });
     76         };
     77     }
     78 
     79     render() {
     80         const self = this;
     81         const uploadProps = {
     82             name: 'file',
     83             accept: '.pdf',
     84             action: '',
     85             onChange(info) {
     86                 const status = info.file.status;
     87                 if (status != 'done') {
     88                     self.setState({ loading: true });
     89                 }
     90                 if (status !== 'uploading') {
     91                     console.log(info.file, info.fileList);
     92                 }
     93                 if (status === 'done') {
     94                     self.setState({ loading: false });
     95                     message.success(`${info.file.name} 导入成功`);
     96                     // 解析 pdf 文件
     97                     self.readPdf(info.file.originFileObj);
     98                 } else if (status === 'error') {
     99                     console.log(`${info.file.name} 导入失败`);
    100                 }
    101             },
    102         };
    103         return (
    104             <Modal
    105                 title="导入pdf"
    106                 width={480}
    107                 className="import-pdf-modal"
    108                 footer={null}
    109             >
    110                 <Spin tip="导入中" spinning={this.state.loading}>
    111                     <Dragger {...uploadProps} id="document">
    112                         <p className="ant-upload-drag-icon">
    113                             <Icon type="inbox" />
    114                         </p>
    115                         <p className="ant-upload-text">点击或将文件拖拽到这里上传</p>
    116                         <p className="ant-upload-hint">支持扩展名:.pdf</p>
    117                         <div id='pdf-container' style={{ height: 0, overflow: 'hidden' }}></div>
    118                     </Dragger>
    119                 </Spin>
    120             </Modal>
    121         )
    122     }
    123 }

    【参考】

    pdf.js

    Is there a pre-built version PDF.js available?

    pdf2img

  • 相关阅读:
    Windows10 下Apache服务器搭建
    Visual Studio 2019及其注册码
    清理300多台MySQL数据库的过期binlog日志
    JS获取和设置光标的位置
    在android客户端加载html源代码总结
    OpenGL ES2学习笔记(9)-- 转换矩阵
    可行性研究报告 之机房收费系统的可行性研究报告
    eclipse 配置Maven问题解决办法:新建maven工程时报错:Could not resolve archetype org.apache.maven.archetypes .
    常见的证书格式和相互转换
    九度OJ 题目1384:二维数组中的查找
  • 原文地址:https://www.cnblogs.com/wx1993/p/12533899.html
Copyright © 2020-2023  润新知