React

关注公众号 jb51net

关闭
首页 > 网络编程 > JavaScript > javascript类库 > React > React项目中的PDF展示解决

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

作者:草晚晴

这篇文章主要介绍了关于React项目中的PDF展示解决方案,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教

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

使用iframe标签

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

直接使用iframe标签展示pdf文件

<iframe src={fileUrl} width={'100%'} height={'100%'} style={{ minHeight: '80vh' }} />

其中fileUrl为需要展示pdf的文件地址,宽高和style均可自定义,下不赘述。

如果用户可以访问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展示

├── 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;

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

您可能感兴趣的文章:
阅读全文