React项目中的PDF展示解决方案

本文将梳理两种方案,涉及两个库react-pdfpdf.js,使用环境为ant-design-pro脚手架创建的项目。

使用iframe标签

1、不需要任何依赖的两种方式为:

  1. 直接使用iframe标签展示pdf文件
    <iframe src={fileUrl} width={'100%'} height={'100%'} style={{ minHeight: '80vh' }} />
    
    其中fileUrl为需要展示pdf的文件地址,宽高和style均可自定义,下不赘述。
  2. 如果用户可以访问google,则可以使用如下地址:
    <iframe
            src={`http://docs.google.com/gview?url=${fileUrl}&embedded=true`}
            width={'100%'}
            height={'100%'}
            style={{ minHeight: '80vh' }}
          />
    
    其中fileUrl为需要展示pdf的文件地址,宽高和style均可自定义。

2、使用编译好的静态库pdf.js的viewer.html展示
编译好的pdfjs可直接下载,也可去官网下载
需要先将编译好的pdfjs版本放在react项目的public目录

├── config                   # umi 配置,包含路由,构建等配置
├── mock                     # 本地模拟数据
├── public                    # 将编译好的PDFJS放在这个目录下 
│   └── favicon.png          # Favicon
├── src
│   ├── assets               # 本地静态资源
│   ├── components           # 业务通用组件
│   ├── e2e                  # 集成测试用例
│   ├── layouts              # 通用布局
│   ├── models               # 全局 dva model
│   ├── pages                # 业务页面入口和常用模板
│   ├── services             # 后台接口服务
│   ├── utils                # 工具库
│   ├── locales              # 国际化资源
│   ├── global.less          # 全局样式
│   └── global.ts            # 全局 JS
├── tests                    # 测试工具
├── README.md
└── package.json

如下图所示
在这里插入图片描述
在需要展示PDF文件的地方,使用如下src即可。

<iframe
            src={`pdfjs-2.2.228-dist/web/viewer.html?file=${fileUrl}`}
            width={'100%'}
            height={'100%'}
            style={{ minHeight: '80vh' }}
          />

使用react-pdf展示

import { Pagination } from 'antd';
import React, { useState } from 'react';
import { Document, Page } from 'react-pdf/dist/esm/entry.webpack';
// @ts-ignore

const PdfViewer: React.FC<{ url: string }> = ({ url }) => {
  const [numPages, setNumPages] = useState(0);
  const [pageNumber, setPageNumber] = useState(1);

  // @ts-ignore
  const onDocumentLoadSuccess = (props: any) => {
    setNumPages(props?.numPages);
  };

  const onChangePage = (page: any) => {
    setPageNumber(page);
  };

  return (
    <div>
      <div style={{ marginBottom: 4 }}>
        <a href={url} target={'_blank'} rel="noreferrer">
          查看当前文件
        </a>
      </div>

      <Document file={url} onLoadSuccess={onDocumentLoadSuccess}>
        <Page pageNumber={pageNumber} />
      </Document>
      <Pagination
        style={{ marginTop: 4, display: 'flex', justifyContent: 'flex-end' }}
        total={numPages}
        simple
        hideOnSinglePage
        showTotal={(total) => `${total}`}
        current={pageNumber}
        pageSize={1}
        size="small"
        onChange={onChangePage}
      />
    </div>
  );
};

export default PdfViewer;

pdfjs的另一种使用方式

import { useEffect, useRef, useState } from 'react';

const PDFJsViewer = ({ pdfUrl }: any) => {
  const pdfjsLib = require('pdfjs-dist/build/pdf.js');
  const pdfjsWorker = require('pdfjs-dist/build/pdf.worker.entry.js');

  pdfjsLib.GlobalWorkerOptions.workerSrc = pdfjsWorker;

  const canvasRef = useRef(null);
  const [scale, setScale] = useState(1);
  const [offset, setOffset] = useState({ x: 0, y: 0 });

  const handleWheel = (e: any) => {
    if (e.deltaY < 0) {
      setScale((prevScale) => Math.min(prevScale + 0.1, 3));
    } else {
      setScale((prevScale) => Math.max(prevScale - 0.1, 0.5));
    }
  };

  const handleMouseDown = (e: any) => {
    const initialX = e.clientX - offset.x;
    const initialY = e.clientY - offset.y;

    const handleMouseMove = (e: any) => {
      const newX = e.clientX - initialX;
      const newY = e.clientY - initialY;

      setOffset({ x: newX, y: newY });
    };

    const handleMouseUp = () => {
      document.removeEventListener('mousemove', handleMouseMove);
      document.removeEventListener('mouseup', handleMouseUp);
    };

    document.addEventListener('mousemove', handleMouseMove);
    document.addEventListener('mouseup', handleMouseUp);
  };

  useEffect(() => {
    const canvas = canvasRef.current;
    //@ts-ignore
    const ctx = canvas.getContext('2d');

    const loadingTask = pdfjsLib.getDocument(pdfUrl);

    loadingTask.promise.then((pdf: any) => {
      pdf.getPage(1).then((page: any) => {
        const viewport = page.getViewport({ scale: scale });
        //@ts-ignore
        canvas.height = viewport.height;
        //@ts-ignore
        canvas.width = viewport.width;

        ctx.setTransform(1, 0, 0, 1, 0, 0);
        //@ts-ignore
        ctx.clearRect(0, 0, canvas.width, canvas.height);
        ctx.setTransform(scale, 0, 0, scale, offset.x, offset.y);

        const renderContext = {
          canvasContext: ctx,
          viewport: viewport,
        };

        page.render(renderContext);
      });
    });
  }, [pdfUrl, scale, offset]);

  return <canvas ref={canvasRef} onWheel={handleWheel} onMouseDown={handleMouseDown}></canvas>;
};

export default PDFJsViewer;

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要在React项目加载PDF文件并显示在Canvas,您需要使用以下步骤: 1. 安装pdfjs-dist库 使用npm或yarn安装pdfjs-dist库。 ``` npm install pdfjs-dist ``` 2. 加载PDF文件 使用pdfjs-dist库加载PDF文件。 ```javascript import pdfjsLib from 'pdfjs-dist'; pdfjsLib.getDocument(url).promise.then((pdf) => { // pdf对象包含了PDF文件的所有信息 }); ``` 3. 渲染PDF页面 使用pdfjs-dist库将PDF页面渲染到Canvas。 ```javascript pdf.getPage(pageNumber).then((page) => { const canvas = document.getElementById('canvas'); const context = canvas.getContext('2d'); const viewport = page.getViewport({ scale: 1 }); canvas.width = viewport.width; canvas.height = viewport.height; const renderContext = { canvasContext: context, viewport: viewport, }; page.render(renderContext); }); ``` 这个例子,`pageNumber`是要渲染的PDF页面的页码。`canvas`是渲染结果将要呈现的Canvas元素。`viewport`是PDF页面的大小和缩放比例。 4. 完整的React组件 ```javascript import React, { useEffect, useRef } from 'react'; import pdfjsLib from 'pdfjs-dist'; function PdfCanvas({ url, pageNumber }) { const canvasRef = useRef(null); useEffect(() => { const canvas = canvasRef.current; const context = canvas.getContext('2d'); pdfjsLib.getDocument(url).promise.then((pdf) => { pdf.getPage(pageNumber).then((page) => { const viewport = page.getViewport({ scale: 1 }); canvas.width = viewport.width; canvas.height = viewport.height; const renderContext = { canvasContext: context, viewport: viewport, }; page.render(renderContext); }); }); }, [url, pageNumber]); return ( <canvas ref={canvasRef} /> ); } export default PdfCanvas; ``` 这个组件将会渲染指定PDF文件的指定页面到一个Canvas元素

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值