首页 > 其他分享 >react-pdf实现pdf预览

react-pdf实现pdf预览

时间:2022-12-14 11:13:54浏览次数:56  
标签:numPages const 预览 react import pdf page

实现了pdf翻页,放大,缩小,全屏展示,右键打印。

实现代码:
js:

import React, { useState, useEffect } from 'react';
import PropTypes from 'prop-types';
import { Spin, Tooltip, Input } from 'antd';
import { LeftOutlined, RightOutlined, PlusCircleOutlined, MinusCircleOutlined, FullscreenExitOutlined, FullscreenOutlined } from '@ant-design/icons';
import styles from './index.less';
import { Document, Page, pdfjs } from 'react-pdf';
pdfjs.GlobalWorkerOptions.workerSrc = `//cdnjs.cloudflare.com/ajax/libs/pdf.js/${pdfjs.version}/pdf.worker.js`;
import stateStorage from '@/storage/stateStorage';

export default function PdfView({ file }) {
    console.log(file)
    const [pageNumber, setPageNumber] = useState(1)
    const [pageNumberInput, setPageNumberInput] = useState(1)
    const [pageNumberFocus, setPageNumberFocus] = useState(false)
    const [numPages, setNumPages] = useState(1)
    const [pageWidth, setPageWidth] = useState(600)
    const [fullscreen, setFullscreen] = useState(false)
    const onDocumentLoadSuccess = ({ numPages }) => {
        setNumPages(numPages)
    }

    const lastPage = () => {
        if (pageNumber == 1) {
            return
        }
        const page = pageNumber - 1
        setPageNumber(page)
        setPageNumberInput(page)
    }
    const nextPage = () => {
        if (pageNumber == numPages) {
            return
        }
        const page = pageNumber + 1
        setPageNumber(page)
        setPageNumberInput(page)
    }
    const onPageNumberFocus = e => {
        setPageNumberFocus(true)
    };
    const onPageNumberBlur = e => {
        setPageNumberFocus(false)
        setPageNumberInput(pageNumber)
    };
    const onPageNumberChange = e => {
        let value = e.target.value
        value = value <= 0 ? 1 : value;
        value = value >= numPages ? numPages : value;
        setPageNumberInput(value)
    };
    const toPage = e => {
        setPageNumber(Number(e.target.value))
    };

    const pageZoomOut = () => {
        if (pageWidth <= 600) {
            return
        }
        const pageWidths = pageWidth * 0.8
        setPageWidth(pageWidths)
    }
    const pageZoomIn = () => {
        const pageWidths = pageWidth * 2.5
        setPageWidth(pageWidths)

    }

    const pageFullscreen = () => {
        if (fullscreen) {
            setFullscreen(false)
            setPageWidth(600)
        } else {
            setFullscreen(true)
            setPageWidth(window.screen.width - 40)
        }
    }

    const getPrintRender = () => {
        return new Array(numPages || []).fill(0).map((ele, i) => {
            return (
                <Page key={i + 1} pageNumber={i + 1} width={750} loading={<Spin size="large" />} />
            )
        })
    }

    return (
        <div className={styles.view}>
            <div className={`${styles.pageContainer} ${styles.noPrint}`}>
                <Document
                    file={stateStorage.get('pdf')}
                    onl oadSuccess={onDocumentLoadSuccess}
                    loading={<Spin size="large" />}
                >
                    <Page pageNumber={pageNumber} width={pageWidth} loading={<Spin size="large" />} />
                </Document>
            </div>

            <div className={styles.canPrint}>
                <Document
                    file={stateStorage.get('pdf')}
                    onl oadSuccess={onDocumentLoadSuccess}
                    loading={<Spin size="large" />}
                >
                    {getPrintRender()}
                </Document>
            </div>

            <div className={`${styles.pageTool} ${styles.noPrint}`}>
                <Tooltip title={pageNumber == 1 ? '已是第一页' : '上一页'}>
                    <LeftOutlined onClick={lastPage} />
                </Tooltip>
                <Input value={pageNumberFocus ? pageNumberInput : pageNumber}
                    onFocus={onPageNumberFocus}
                    onBlur={onPageNumberBlur}
                    onChange={onPageNumberChange}
                    onPressEnter={toPage} type="number" /> / {numPages}
                <Tooltip title={pageNumber == numPages ? '已是最后一页' : '下一页'}>
                    <RightOutlined onClick={nextPage} />
                </Tooltip>
                <Tooltip title="放大">
                    <PlusCircleOutlined onClick={pageZoomIn} />
                </Tooltip>
                <Tooltip title="缩小">
                    <MinusCircleOutlined onClick={pageZoomOut} />
                </Tooltip>
                <Tooltip title={fullscreen ? '恢复默认' : '适合窗口'}>
                    {fullscreen ? <FullscreenExitOutlined onClick={pageFullscreen} /> : <FullscreenOutlined onClick={pageFullscreen} />}
                </Tooltip>
            </div>
        </div>
    )
}
PdfView.propTypes = {
    params: PropTypes.object.isRequired,
    file: PropTypes.any
};

css:

.view {
  background: #444;
  display: flex;
  justify-content: center;
  min-height: 100vh;
  padding: 50px 0;
  box-sizing: border-box;
}

.pageContainer {
  box-shadow: rgba(0, 0, 0, 0.2) 0px 2px 4px 0px;
  width: max-content;
  max-width: 100vw;
}

.pageTool {
  position: fixed;
  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;
  }
}

.view {
  .canPrint {
    display: none;
  }

  @media print {
    .canPrint {
      display: block;
    }

    & {
      padding: 0;
    }

    &::-webkit-scrollbar {
      display: none;
    }

    .noPrint {
      display: none;
      height: 0;
    }

    :global {

      // react-pdf__Page__textContent隐藏 为了解决打印时会出现多一张空白页的情况
      .react-pdf__Page__textContent {
        display: none;
      }

      .react-pdf__Page:not(:last-child) {
        page-break-after: always;
      }
    }
  }
}

附:
react-pdf

标签:numPages,const,预览,react,import,pdf,page
From: https://www.cnblogs.com/ZerlinM/p/16981524.html

相关文章

  • Linux系统Word转换PDF,文档字体乱码不显示问题解决
    Linux系统Word转换PDF,文档字体乱码不显示问题解决1、在windows目录C:\Windows\Fonts下找到字体文件。2、在linux上寻找Linux/usr/share/fonts/my_fonts目录,如果没有......
  • 社招前端二面react面试题集锦
    在哪个生命周期中你会发出Ajax请求?为什么?Ajax请求应该写在组件创建期的第五个阶段,即componentDidMount生命周期方法中。原因如下。在创建期的其他阶段,组件尚未渲染完成......
  • react的jsx和React.createElement是什么关系?面试常问
    1、JSX在React17之前,我们写React代码的时候都会去引入React,并且自己的代码中没有用到,这是为什么呢?这是因为我们的JSX代码会被Babel编译为React.createElement,我们来......
  • React报错之Too many re-renders
    总览产生"Toomanyre-renders.Reactlimitsthenumberofrenderstopreventaninfiniteloop"错误有多方面的原因:在一个组件的渲染方法中调用一个设置状态的函数......
  • Java 使用 wkhtmltopdf 生成 PDF 遇到的几个坑
    wkhtmltopdf使用本地文件生成PDF一般使用命令wkhtmltopdfURLpdfPath生成PDF文件,其中URL为GET请求地址。但是笔者在做的项目是一个模板中心服务(后续代码整理......
  • antd 配置了@craco/craco后react-scripts报错问题
    react安装了antd配置了@craco/craco后运行yarnstart后直接报错:Cannotfindmodule'react-scripts\package.json'Requirestack:/*package.json*/"scripts":{-......
  • 如何通过Java应用程序压缩PDF文档
     PDF文档是我们日常办公中使用最频繁的文档格式。但因为大多数PDF文档都包含很多页面图像或大量图片,这就导致PDF文档过大,处理起来较为麻烦。PDF文件过大,就会导致传输或者......
  • react-native init DemoApp --version 0.44.3 解决 CFBundleIdentifier
    查看版本:react-native --version升级:npmupdate -greact-native-clipackage.json中可以查看对应reactnative版本,推荐45以下创建,比如:1、新建项目指定版本:用​​--ver......
  • React StrictMode 生命周期为什么会执行两次?
    什么是React.StrictMode?React.StrictMode是在2018年的16.3.0版本中引入的组件。一开始,它只用在类组件中,而在16.8.0中,它对hook同样适用。就像在版本说明中提及......
  • JAVA操作PDF实现简单盖章功能(未签字)
    默认再第一页签章:https://www.cnblogs.com/wolf-shuai/p/16977802.html摘要:jar包准备:bcpkix-jdk15on-1.70.jarbcprov-jdk15on-1.70.jariTextAsian.jaritextpdf-5.5.1......