首页 > 其他分享 >前端实现预览PDF

前端实现预览PDF

时间:2023-08-01 15:47:35浏览次数:40  
标签:numPages const 预览 前端 react useState pdf PDF path

下载包 npm install react-pdf

我使用的是[email protected]版本

以下例子使用的是react创建的项目

 

直接上代码=>cv可用,保证高效

 

1.新增依赖

yarn add [email protected]

npm install [email protected]

 2.导出js

/*
  1.进入该组件时,通过路由传递path进来,形如:
    history.push({ pathname: '/pdfPreview', query: { path } })

  2.进入该组件时,通过props传递path进来,形如:
  { filePath :{ path :''} }
*/
import React, { useState } from 'react';
import { Spin, Tooltip, Input } from 'antd';
import {
  LeftOutlined,
  RightOutlined,
  PlusCircleOutlined,
  MinusCircleOutlined,
  FullscreenOutlined,
  FullscreenExitOutlined,
} 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`;

const PreviewPDF = (props: any) => {
  const { location, filePDF, filePath } = props;  // 方法1: 作为组件传入的值, 取出path(pdf地址)
  // const { path }: any = location.query; // 方法2: 作为路由跳转的传入的值, 取出path(pdf地址)
  const path = filePath;

  const [pageNumber, setPageNumber] = useState(1);
  const [pageNumberInput, setPageNumberInput] = useState(1);
  const [pageNumberFocus, setPageNumberFocus] = useState(false);
  const [numPages, setNumPages] = useState(1);
  const [pageWidth, setPageWidth] = useState(1200);
  const [fullscreen, setFullscreen] = useState(false);
  const onDocumentLoadSuccess = ({ numPages }: any) => {
    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 = () => {
    setPageNumberFocus(true);
  };
  const onPageNumberBlur = () => {
    setPageNumberFocus(false);
    setPageNumberInput(pageNumber);
  };
  const onPageNumberChange = (e: any) => {
    let { value } = e.target;
    value = value <= 0 ? 1 : value;
    value = value >= numPages ? numPages : value;
    setPageNumberInput(value);
  };
  const toPage = (e: any) => {
    setPageNumber(Number(e.target.value));
  };
  const pageZoomOut = () => {
    if (pageWidth <= 1200) return;
    const width = pageWidth * 0.8;
    setPageWidth(width);
  };
  const pageZoomIn = () => {
    const width = pageWidth * 1.2;
    setPageWidth(width);
  };
  const pageFullscreen = () => {
    if (fullscreen) {
      setFullscreen(false);
      setPageWidth(1200);
    } else {
      setFullscreen(true);
      setPageWidth(window.screen.width - 40);
    }
  };

  return (
    <div className={`${styles.view}`}>
      <div className={styles.pageContainer}>
        <Document
          file={path}
          onl oadSuccess={onDocumentLoadSuccess}
          loading={<Spin size="large" />}
          options={{
            cMapUrl: `https://cdn.jsdelivr.net/npm/pdfjs-dist@${pdfjs.version}/cmaps/`,  // 解决打印不显示的问题,必要的
            cMapPacked: true,
            // disableWorker: true
          }}
        >
          <Page pageNumber={pageNumber} width={pageWidth} loading={<Spin size="large" />} />
        </Document>
      </div>
      <div className={styles.pageTool}>
        <Tooltip title={pageNumber == 1 ? '已是第一页' : '上一页'}>
          <LeftOutlined className={styles.outlined} onClick={lastPage} />
        </Tooltip>
        <Input
          value={pageNumberFocus ? pageNumberInput : pageNumber}
          onFocus={onPageNumberFocus}
          onBlur={onPageNumberBlur}
          onChange={onPageNumberChange}
          onPressEnter={toPage}
          type="number"
        />
        / {numPages}
        <Tooltip title={pageNumber == numPages ? '已是最后一页' : '下一页'}>
          <RightOutlined className={styles.outlined} onClick={nextPage} />
        </Tooltip>
        <Tooltip title="放大">
          <PlusCircleOutlined className={styles.outlined} onClick={pageZoomIn} />
        </Tooltip>
        <Tooltip title="缩小">
          <MinusCircleOutlined className={styles.outlined} onClick={pageZoomOut} />
        </Tooltip>
        <Tooltip title={fullscreen ? '恢复默认' : '适合窗口'}>
          {fullscreen ? (
            <FullscreenExitOutlined className={styles.outlined} onClick={pageFullscreen} />
          ) : (
            <FullscreenOutlined className={styles.outlined} onClick={pageFullscreen} />
          )}
        </Tooltip>
      </div>
    </div>
  );
};

export default PreviewPDF;

3.cv  Css

.view {
  display: flex;
  justify-content: center;
  height: 100%;
  // height: 100vh;
  padding: 20px 0;
  // background: #444;
  .pageContainer {
    width: max-content;
    max-width: 100%;
    // overflow-y: scroll;
    box-shadow: rgba(0, 0, 0, 0.2) 0px 2px 4px 0px;
  }
  .pageTool {
    position: absolute;
    bottom: 60px;
    left: -20px;
    padding: 8px 15px;
    color: white;
    background: rgb(66, 66, 66);
    // background-color: #fff;
    border-radius: 15px;
    .outlined {
      margin: 0 10px;
      user-select: none;
    }
    input {
      display: inline-block;
      width: 50px;
      height: 24px;
      margin-right: 10px;
      text-align: center;
    }
    input::-webkit-outer-spin-button,
    input::-webkit-inner-spin-button {
      -webkit-appearance: none;
    }
    input[type='number'] {
      -moz-appearance: textfield;
    }
  }
}

4.引用组件

import PreviewPDF from './PreviewPDF';

  /**
   * 
   * @param file 数据返回的值,就是预览的pdf的path值
   * 此处写的一个方法调用,获取path值,进行操作
   */
  const handlePreview = async(file: any) => {
    await setFilePath(file.url);

    setVisiblePDF(true); // 组件方式预览
    // const prefix = `${window.location.protocol}//${window.location.host}`; 
    // window.open(`${prefix}/#/binjiang-publicpower/previewPDF?path=${file.url}`);  // 路由的方式预览, 新窗口打开
  };


<Modal width={1400} destroyOnClose footer={false} visible={visiblePDF} onCancel={() => setVisiblePDF(false)} title={''}>
    <PreviewPDF filePath={filePath} />
</Modal>

 

标签:numPages,const,预览,前端,react,useState,pdf,PDF,path
From: https://www.cnblogs.com/dreamtt/p/17596504.html

相关文章

  • 禁止别人调试自己的前端页面代码
    目录......
  • springboot 集成 onlyoffice 实现文档预览、编辑、pdf转化、缩略图生成
    开源地址https://gitee.com/lboot/lucy-onlyoffice介绍lucy-onlyoffice是依赖于onlyoffice的springboot文档预览编辑集成解决方案,该解决方案实现了了onlyoffice的访问使用,支持对常见文档类型的预览,编辑和转化。该解决方案提供了功能的拓展实现,用户可以基于拓展接口,实现业务系统......
  • 结合前端实现ORM对数据的增删改查、动静态网页,Django创建表关系、请求生命周期流程图
    通过结合前端页面实现ORM对数据的增删改查写一个页面,把数据库中的数据以表格的形式展示出来,然后在每一行的后面加两个按钮,分别是修改、删除的按钮。1.先创建一张UserInfo表格:在Django中没有提供tinyint、smallint,就只提供了int和bigint,如果想要写其他类型,需要自己定义......
  • 无障碍工具条在前端项目中的使用
    一、使用的工具https://gitee.com/tywAmblyopia/ToolsUI二、使用VUE中使用-1.拉取代码-2.将canyou文件夹放到public目录下-3.在public文件夹下的index.html文件中</head>标签前,引用v1.8以上的jquery.min.js(原网站已引用v1.8以上的jquery跳过此......
  • 视频直播网站源码,前端效果-css+javascript
    视频直播网站源码,前端效果-css+javascript <!DOCTYPEhtml><html><head>  <metacharset="UTF-8">  <metahttp-equiv="X-UA-Compatible"content="IE=edge">  <metaname="viewport"content="w......
  • 前端神器-神级代码编辑软件Sublime Text下载、使用教程、插件推荐说明、全套快捷键
    SublimeText是一个代码编辑器,也是HTML和散文先进的文本编辑器。SublimeText是由程序员JonSkinner于2008年1月份所开发出来,它最初被设计为一个具有丰富扩展功能的Vim。SublimeText具有漂亮的用户界面和强大的功能,例如代码缩略图,Python的插件,代码段等。还可自定义键绑定,菜单和......
  • 前端路由+原生JS实现SPA
    前端路由●路由:就是一一对应关系的集合●前端路由:就是一个url地址,对应哪个组件(页面)●前端路由的本质○根据地址栏变化(不重新想服务器发送请求),去局部更新不同的页面内容,完成前端业务场景切换●前端路由的思路○URL地址栏中的Hash值发生了变化○前端JS监听到H......
  • 前端Vue自定义精美商品分类组件category 可用于电商应用分类页面
    随着技术的不断发展,传统的开发方式使得系统的复杂度越来越高。在传统开发过程中,一个小小的改动或者一个小功能的增加可能会导致整体逻辑的修改,造成牵一发而动全身的情况。为了解决这个问题,我们采用了组件化的开发模式。通过组件化开发,可以有效地实现单独开发,单独维护,而且它们之间......
  • esXGray更新预览
    即将到来的更新:全新UI,类PS黑PDF全文处理功能优化,可以正确处理半透明图片及存在旋转的图片了添加了新功能:反相,用于漂白类似于黑底白字的,深色背景+浅色文字的图片 ......
  • Node.js 与前端开发实战
    0x1Node.js的应用场景前端工程化打包工具:webpack、vite、esbuild、parce代码压缩:uglifyjs语法转换:babeljs,typescript难以替代Web服务端应用学习曲线平缓,开发效率较高运行效率接近常见的编程语言社区生态丰富及工具链成熟(npm)与前端结合的场景会有优势(SSR)竞......