1、在react项目中安装react-pdf依赖包

建议安装8.0.2版本的react-pdf,如果安装更高版本的可能出现一些浏览器的兼容性问题;

npm install react-pdf@8.0.2 -S

1、PC端的使用

1.1、封装一个组件:PdfViewModal.tsx

import React, { useState } from 'react'
import { Modal, Spin, Alert } from 'antd'
import { Document, Page, pdfjs } from 'react-pdf'
import 'react-pdf/dist/esm/Page/AnnotationLayer.css'
import 'react-pdf/dist/esm/Page/TextLayer.css'; // 配置 PDF.js 的 worker 文件
pdfjs.GlobalWorkerOptions.workerSrc = new URL('pdfjs-dist/build/pdf.worker.min.js', import.meta.url).toString() interface PDFPreviewModalProps {
fileName: string | null
fileUrl: string | null // 传入的 PDF 文件地址
onCancel: () => void // 关闭弹框的回调
} const PDFPreviewModal: React.FC<PDFPreviewModalProps> = ({ fileName, fileUrl, onCancel }) => {
const [numPages, setNumPages] = useState<number | null>(null)
const [pdfWidth, setPdfWidth] = useState<number>(600) // 默认宽度为 600px
const [loading, setLoading] = useState<boolean>(true) // 控制加载状态
const [error, setError] = useState<boolean>(false) // 控制加载错误状态 // 当 PDF 加载成功时,设置页面数量
const onDocumentLoadSuccess = ({ numPages }: { numPages: number }) => {
setNumPages(numPages)
setLoading(false) // 加载成功后,隐藏 loading
} // 加载失败时,设置错误状态
const onDocumentLoadError = () => {
setLoading(false)
setError(true) // 出错时显示错误提示
} // 获取 PDF 页面加载后的宽度
const onPageLoadSuccess = ({ width }: { width: number }) => {
setPdfWidth(width)
} return (
<Modal
title={`【${fileName}】预览`}
open
onCancel={onCancel}
footer={null}
width={pdfWidth + 100}
style={{ top: 20 }}
>
{error ? (
<Alert message="加载 PDF 文件失败" type="error" showIcon />
) : (
<>
{loading && (
<div style={{ display: 'flex', justifyContent: 'center', alignItems: 'center', height: '80vh' }}>
<Spin size="large" />
</div>
)}
{fileUrl && (
<>
<div style={{ height: '88vh', overflowY: 'auto', padding: '24px' }}>
<Document
//file={new URL('/public/temp/DXF文件要求.pdf',import.meta.url).toString()}
file={fileUrl}
onLoadSuccess={onDocumentLoadSuccess}
onLoadError={onDocumentLoadError}
>
{Array.from(new Array(numPages), (el, index) => (
<Page key={`page_${index + 1}`} pageNumber={index + 1} onLoadSuccess={onPageLoadSuccess} />
))}
</Document>
</div>
</>
)}
</>
)}
</Modal>
)
} export default PDFPreviewModal

1.2、业务代码中引入该组件

import React, { useState, useEffect, useCallback } from 'react'
import { Form } from 'antd'
import { List } from 'antd'
import PDFPreviewModal from '@/components/PdfViewModal.tsx' const PdfTest = (props: any) => {
const [previewFile, setPreviewFile] = useState<any>()

const onTestPdf = () => {
  setPreviewFile({
    fileName: 'abc.pdf',
    fileUrl: 'http://****/abc.pdf'
  })
}return (
<div className="mrUp mrLink">
   <div onClick={onTestPdf}>测试预览PDF</div>

{!!previewFile?.publicFileUrl && (
<PDFPreviewModal
fileName={previewFile?.fileName}
fileUrl={previewFile?.publicFileUrl}
onCancel={() => setPreviewFile('')}
/>
)}
</div>
)
} export default PdfTest

2、H5移动端的使用

移动端加入放大、缩小、上一页、下一页的功能;

2.1、封装一个组件:PDFViwer.tsx

import React, { useState } from 'react';
import { Button, Modal, Space, Toast, Divider } from 'antd-mobile'
import { UpOutline, DownOutline, AddCircleOutline, MinusCircleOutline } from 'antd-mobile-icons'
import { Document, Page, pdfjs } from 'react-pdf';
import 'react-pdf/dist/esm/Page/AnnotationLayer.css'; // 样式导入
import 'react-pdf/dist/esm/Page/TextLayer.css' // 配置 PDF.js 的 worker 文件
pdfjs.GlobalWorkerOptions.workerSrc = new URL('pdfjs-dist/build/pdf.worker.min.js', import.meta.url).toString() interface PDFPreviewModalProps {
fileUrl: string | null; // 传入的 PDF 文件地址
} const styleBtnDv = {
display: 'flex',
justifyContent: 'center',
height: '1rem',
alignItems: 'center',
gap: '0.4rem',
margin: '0.3rem 1rem',
padding: '0 0.6rem',
background: '#444',
borderRadius: '0.5rem'
} const styleBtn = {
flex: 1,
display: 'flex',
justifyContent: 'center',
height: '0.6rem',
alignItems: 'center',
} // PDF预览功能
const PDFViwer: React.FC<PDFPreviewModalProps> = ({ fileUrl }) => {
const [pageNumber, setPageNumber] = useState(1);
const [numPages, setNumPages] = useState(1);
const [scale, setScale] = useState(0.65); // 当 PDF 加载成功时,设置页面数量
const onDocumentLoadSuccess = ({ numPages }: { numPages: number }) => {
setNumPages(numPages);
}; //上一页
function lastPage() { if (pageNumber == 1) {
Toast.show({
content: '已是第一页'
})
return;
}
const page = pageNumber - 1;
setPageNumber(page);
}
//下一页
function nextPage() {
if (pageNumber == numPages) {
Toast.show("已是最后一页");
return;
}
const page = pageNumber + 1;
setPageNumber(page);
}
//缩小
function pageZoomOut() {
if (scale <= 0.3) {
Toast.show("已缩放至最小");
return;
}
const newScale = scale - 0.1;
setScale(newScale);
} //放大
function pageZoomIn() {
if (scale >= 5) {
Toast.show("已放大至最大");
return;
}
const newScale = scale + 0.1;
setScale(newScale);
} return (
<div>
{/* 预览 PDF 文件 */}
{fileUrl ? (
<div style={{ height: 'calc(100vh - 4.5rem)', overflowY: 'auto', padding: '24px' }}>
<Document
// 写死的pdf文件地址,用于本地测试使用,打包提交前需要注释掉
// file={new URL("/public/temp/AI销售助手-宽带&套餐&战新.pdf", import.meta.url).toString()}
// 真实传入的pdf地址
file={fileUrl}
onLoadSuccess={onDocumentLoadSuccess}
>
<Page pageNumber={pageNumber} scale={scale} />
</Document>
</div>
) : (
<p>没有选择文件</p>
)}
<div style={styleBtnDv}>
<div style={styleBtn} onClick={lastPage}><UpOutline color='#fff' fontSize={'0.6rem'} /></div>
<div style={{ color: '#fff', fontSize: '0.35rem', ...styleBtn }}>{pageNumber}/{numPages}</div>
<div style={styleBtn} onClick={nextPage}><DownOutline color='#fff' fontSize={'0.6rem'} /></div>
<div style={styleBtn} onClick={pageZoomIn}><AddCircleOutline color='#fff' fontSize={'0.6rem'} /></div>
<div style={styleBtn} onClick={pageZoomOut}><MinusCircleOutline color='#fff' fontSize={'0.6rem'} /></div>
</div>
</div>
);
}; export default PDFViwer;

2.2、业务代码中引入该组件

import React, { useMemo, useRef, useState } from 'react'
import { ErrorBlock, Swiper, SwiperRef, Popup, } from 'antd-mobile'
import PDFViwer from '@/components/PDFViwer'; const ellipsis1 = {
"white-space": "nowrap",
"overflow": "hidden",
"text-overflow": "ellipsis",
} const IntroduceDocList = (props: any) => {
const { loading, introduceDocList } = props
// const introduceDocList = [
// {publicFileUrl: '/public/temp/DXF文件要求.pdf', fileName:'DXF文件要求.pdf'},
// {publicFileUrl: '/public/temp/AI销售助手-宽带&套餐&战新.pdf', fileName:'AI销售助手-宽带&套餐&战新.pdf'},
// ]

const [introduceDocList, setIntroduceDocList] = useState({
  {publicFileUrl: 'http://****/abc.pdf', fileName:'abc.pdf'},
{publicFileUrl: 'http://****/def.pdf', fileName:'def.pdf'},
});

const [pdf, setPdf] = useState({ id: 1 });
const [showPdfViwer, setShowPdfViwer] = useState(false) const onOpenPdfViewer = (item) => {
console.log(item);
setPdf(item);
setShowPdfViwer(true);
} return (
<div>
{
introduceDocList?.map(item => (
<div data-url={item?.publicFileUrl} style={{ marginBottom: '0.3rem', fontSize: '0.4rem' }}>
<span style={{color:'#0B75FF'}} onClick={() => onOpenPdfViewer(item)}>{item.fileName}</span>
</div>
))
}
<Popup
position='right'
visible={showPdfViwer}
showCloseButton
bodyStyle={{ width: '100%' }}
destroyOnClose={true}
onClose={() => {
setShowPdfViwer(false)
setPdf({ id: 1 })
}}
>
<div style={{ padding: '0.3rem 1rem', fontSize: '0.35rem', fontWeight: 600, textAlign:'center', ...ellipsis1 }}>{pdf?.fileName}</div>
<div style={{ height: '100%' }} data-url={pdf?.publicFileUrl}>
<PDFViwer fileUrl={pdf?.publicFileUrl} />
</div>
</Popup>
</div>
)
}
export default IntroduceDocList

效果图:

注意:挡在本地开发时,如果预览的pdf文件地址是线上地址,则会报跨域的问题,需要服务端解决跨域问题。

react-pdf预览在线PDF的使用的更多相关文章

  1. axios 下载文件流或者预览在线pdf

    问题: 后端返回文件流,前端使用axios下载或者在线预览 下载文件流 import axios from 'axios' // 设置响应类型为blob axios.get('/api/app/xxx ...

  2. pdf预览(pdf.js)

    开门见山,pdf.js是Mozilla(缩写MF或MoFo)全称Mozilla基金会,下面的插件.现在社区非常活跃. Mozilla是为支持和领导开源的Mozilla项目而设立的一个非营利组织 下载地 ...

  3. Office在线预览及PDF在线预览的实现方式史上最全大集合

    Office在线预览及PDF在线预览的实现方式大集合 一.服务器先转换为PDF,再转换为SWF,最后通过网页加载Flash预览 微软方:利用Office2007以上版本的一个PDF插件SaveAsPD ...

  4. Office在线预览及PDF在线预览的实现方式大集合

    一.服务器先转换为PDF,再转换为SWF,最后通过网页加载Flash预览 微软方:利用Office2007以上版本的一个PDF插件SaveAsPDFandXPS.exe可以导出PDF文件,然后再利用免 ...

  5. Office在线预览及PDF在线预览的实现方式

    原文链接:http://www.officeweb365.com/officetoview.html 一.服务器先转换为PDF,再转换为SWF,最后通过网页加载Flash预览 微软方:利用Office ...

  6. java原装代码完成pdf在线预览和pdf打印及下载

    这是我在工作中,遇到这样需求,完成需求后,总结的成果,就当做是工作笔记,以免日后忘记,当然,能帮助到别人是最好的啦! 下面进入正题: 前提准备: 1. 项目中至少需要引入的jar包,注意版本: a)  ...

  7. 浏览器实现PDF预览

    1.使用jquery.media.js预览PDF <!DOCTYPE html> <html> <head> <meta charset="utf- ...

  8. Android原生PDF功能实现:PDF阅读、PDF页面跳转、PDF手势伸缩、PDF目录树、PDF预览缩略图

    1.背景 近期,公司希望实现安卓原生端的PDF功能,要求:高效.实用. 经过两天的调研.编码,实现了一个简单Demo,如上图所示. 关于安卓原生端的PDF功能实现,技术点还是很多的,为了咱们安卓开发的 ...

  9. PDF预览之PDFObject.js总结

    get from:PDF预览之PDFObject.js总结   PDFObject.js - 将PDF嵌入到一个div内,而不是占据整个页面(要求浏览器支持显示PDF,不支持,可配置PDF.js来实现 ...

  10. Pdf预览功能实现(asp.net)

    asp.net中使用 1.pdf预览功能实现的插件是pdfjs-1.5.188-dist //引入插件中相关的文件以及jquery文件 @section css{ <link rel=" ...

随机推荐

  1. [oeasy]python0016_编码_encode_编号_字节_计算机

    ​ 编码(encode) 回忆上次内容 上次找到了字符和字节状态之间的映射对应关系 字符对应着二进制字节 二进制字节也对应着字符 这种字节状态是用2位16进制数来表示的 hex(n)可以把数字转化为 ...

  2. C语言基础要点

    C语言基础 C语言基础 C程序编译过程 C程序编译步骤 汇编语言 32关键字 数据类型 常量 size程序 类型限定 goto语句 指针 指针和字符串 作用域 函数 内存 进程内存结构 可执行文件结构 ...

  3. 【Vue】Re11 Vue 与 Webpack

    一.案例环境前置准备: 创建一个空目录用于案例演示 mkdir vue-sample 初始化案例和安装webpack cd vue-sample npm install webpack@3.6.0 - ...

  4. AI实践者师生夏令营讲座视频:南京大学Lamda实验室(周志华 团队)讲座视频 —— 强化学习的局限性与展望

    视频地址: 周志华团队与Intel团队的讲座视频--强化学习的局限性与未来展望 视频链接地址: https://bizwebcast.smarket.com.cn/b975d6d9969a42cba9 ...

  5. NVIDIA H100 GPU:GPU的机密计算

    国内总结的资料: https://zhuanlan.zhihu.com/p/644717121 相关论文: https://ieeexplore.ieee.org/document/7163017 博 ...

  6. 英雄钢笔359色 EF尖 与 凌美(LAMY) 狩猎者 磨砂黑EF尖——长期使用对比

    首先说明一下,这两个钢笔我都是长期使用了,凌美用了两三年了,英雄的那个用了也快半年了. 两款钢笔细节: 英雄:https://item.jd.com/1002650.html 凌美钢笔:https:/ ...

  7. Ubuntu22.04下安装chrome浏览器

    Ubuntu下Chrome的下载: 地址: https://www.google.cn/intl/zh-CN/chrome/ 下载后的文件: 安装: 命令: sudo dpkg -i google-c ...

  8. 利用 Amazon EMR Serverless、Amazon Athena、Apache Dolphinscheduler 以及本地 TiDB 和 HDFS 在混合部署环境中构建无服务器数据仓库(一)云上云下数据同步方案设计

    引言 在数据驱动的世界中,企业正在寻求可靠且高性能的解决方案来管理其不断增长的数据需求.本系列博客从一个重视数据安全和合规性的 B2C 金融科技客户的角度来讨论云上云下混合部署的情况下如何利用亚马逊云 ...

  9. Spring AI 更新:支持OpenAI的结构化输出,增强对JSON响应的支持

    就在昨晚,Spring AI发了个比较重要的更新.由于最近OpenAI推出了结构化输出的功能,可确保 AI 生成的响应严格遵守预定义的 JSON 模式.此功能显着提高了人工智能生成内容在现实应用中的可 ...

  10. Python网页应用开发神器fac 0.3.0全新版本发布

    大家好我是费老师,在Python生态中,有很多以Python为主要开发语言,实现网页应用开发的框架,其中最为知名的有Dash.flet.streamlit.gradio.nicegui等. 如果综合考 ...