React 前端导航

React 实现 PDF 预览

React 实现 PDF 预览

embed标签实现PDF预览

这种方式虽然简单但是不兼容移动端,实现如下:


<embed
    src="path/to/pdf"
    type="application/pdf"
    style={{ width: '100vw', height: '100vh' }}
></embed>

react-pdf组件

这种方式兼容PC和移动,但是移动端显示不好查看,样式调整比较麻烦。

分页只能自己实现,组件本身不提供分页。

注:如果您使用 Browserify 或打包工具,则必须自行确保将该pdf.worker.js文件pdfjs-dist/build复制到项目的输出文件夹中。

实现如下,示例代码中的pdf.worker.min.js使用的是CDN资源,生产环境可能出现加载不到导致预览失败的情况,所以最好下载到本地,从本地引用:

import { Document, Page, pdfjs } from 'react-pdf';

pdfjs.GlobalWorkerOptions.workerSrc = `//cdnjs.cloudflare.com/ajax/libs/pdf.js/${pdfjs.version}/pdf.worker.min.js`;

export default ()=>{   
    const [numPages, setNumPages] = useState(0);
    const [pageNumber, setPageNumber] = useState(1);

    const onDocumentLoadSuccess = ({ numPages }:any) => {
      setNumPages(numPages);
    }
    return <Document
        className="className"
        file="path/to/pdf"
        loading={<div className={styles.loading}><Spin size="large" /></div>}
        onLoadSuccess={onDocumentLoadSuccess}
    >
        <Page pageNumber={pageNumber} />
    </Document>
    {"自定义pagination分页,通过setPageNumber实现翻页"}
}

更详细的用法附上github地址: react-pdf

阿里云 IMM 服务实现文件在线预览,需要服务端配合(收费)

支持的文档格式

文档预览支持的文档类型和格式如下表所示。

文档类型 文件扩展名
文字 doc、dot、wps、wpt、docx、dotx、docm、dotm、rtf、txt
表格 xls、xlt、et、xlsx、xltx、csv、xlsm、xltm
演示
PDF pdf

准备工作

当访问的OSS Bucket域名与预览引擎的域名不同时,需要在OSS控制台将预览服务域名添加到存储转换后文档的OSS Bucket的跨域访问列表中。具体操作,请参见设置跨域访问

预览流程

上传原始文档到对象存储OSS中。具体操作,请参见上传文件

在服务端分别封装GetWebofficeURL和RefreshWebofficeToken接口。

通过JS-SDK将返回的预览地址挂载到HTML块状元素中并设置AccessToken。

服务端封装接口

在服务端需要分别封装GetWebofficeURL和RefreshWebofficeToken接口,用于获取编辑地址和AccessToken,方便前端直接调用。

1.调用GetWebofficeURL接口,获取协作地址。返回结果示例如下:

{
  "RefreshToken": "306ffe61897443c8909aaad325********",
  "RequestId": "D807F412-1EE0-44E0-A60F-47C27B4046CF",
  "AccessToken": "7f9b6ba5baef4c7d80f837d4c9********",
  "RefreshTokenExpiredTime": "2021-04-21T06:48:10.161355914Z",
  "WebofficeURL": "https://office-cn-shanghai.imm.aliyuncs.com/office/p/9eea88df758a75b6308358500a9e141ccf3b7629?_w_tokentype=1",
  "AccessTokenExpiredTime": "2021-04-20T07:18:10.161355914Z"
}

2.调用RefreshWebofficeToken接口,刷新AccessToken。
AccessToken具有时效性,当过期后前端需要调用服务端RefreshWebofficeToken接口重新刷新AccessToken,所以需要在服务端封装此接口。调用此接口的返回结果格式和调用GetWebofficeURL接口的相同。

前端JS-SDK使用

1.引入JS-SDK。

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=no">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Demo</title>
</head>
<body>
  <script src="https://g.alicdn.com/IMM/office-js/${x.y.z}/aliyun-web-office-sdk.min.js"></script>
  <script>
    console.log('引入后可以开始使用JS-SDK了!');
    console.log(aliyun); //全局变量名。
  </script>
</body>
</html>

以上示例中${x.y.z}表示最新版本号,请根据实际填写.

2.接入WebOffice。

通过在服务端封装的GetWebofficeURL接口获取tokenInfo对象。假设tokenInfo对象和调用GetWebofficeURL接口返回的结构一致。

如下示例以服务端封装的GetWebofficeURL接口为/getTokenInfo举例说明。

//获取协作地址和AccessToken。
var tokenInfo = await $.get('http://example.com/getTokenInfo')
 
let instance = aliyun.config({
  url: tokenInfo.WebofficeURL //设置文档协作URL地址。
})
//设置AccessToken。
instance.setToken({
  token: tokenInfo.AccessToken
})

3.自定义Office(iframe)挂载点。

说明 在DOMContentLoaded事件被触发后,请确保挂载节点存在再执行初始化操作。

iframe(#iframe)默认会挂载到body下,可根据需要自定义iframe(#iframe)的挂载点。

<div id="container"></div>
aliyun.config({
  mount: document.querySelector('#container'),
  url: '文档协作URL地址' //即步骤2示例中的文档协作URL地址(tokenInfo.WebofficeURL)。
})

如果需要对iframe对象做特殊处理,可以通过JS-SDK实例化对象快速获取到iframe的DOM(Document Object Model)对象。

var instance = aliyun.config({
    mount: document.querySelector('#container')
   //...
})
console.log(instance.iframe)

3.设置令牌(Token)。

  • 在获取协作地址后,需要设置令牌才能在线协作。
  • 每次刷新令牌后,也需要通过此方法设置令牌。
    //根据业务需求通过异步请求或者模板输出的方式获取token。
    var token = 'yourToken'; 
    //设置token。
    instance.setToken({
    token: token, 
    timeout: 10 * 60 * 1000, //必须设置。token的超时时间,单位为ms。以10分钟示例说明。
    }) 
    

5.超时更新令牌(Token)。
通过在服务端封装的RefreshWebofficeToken接口获取tokenInfo对象。假设tokenInfo对象和调用RefreshWebofficeToken接口返回的结构一致。

您可以通过传入获取Token的函数,在Token超时时,JS-SDK会自动调用传入的函数重新获取Token,返回一个promise或者object。

如下示例以服务端封装的GetWebofficeToken接口为/refreshTokenInfo举例说明。

//缓存上次的tokenInfo,用于刷新token。
  let lastTokenInfo = tokenInfo

//获取token函数。
  const refreshToken = async () => {
    //业务处理逻辑,调用服务端封装的refreshToken接口。
    let tokenInfo = await $.get('http://example.com/refreshTokenInfo',{
       RefreshToken: lastTokenInfo.RefreshToken,
       AccessToken: lastTokenInfo.AccessToken,
       //....
    })
    lastTokenInfo = tokenInfo
    return {
      token: tokenInfo.AccessToken, //必须设置。
      timeout: 10 * 60 * 1000, //必须设置。token超时时间,单位为ms。可配合refreshToken配置函数使用,在超时前调用refreshToken重新刷新token。
    }
  }
//配置超时获取token函数。
aliyun.config({
  //...
  refreshToken
})

参考文档:IMM 用户指南

声明:本网站发布的内容(图片、视频和文字)以原创、转载和分享网络内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。邮箱:farmerlzj@163.com。 本站原创内容未经允许不得转载,或转载时需注明出处: 内容转载自: React前端网:https://qianduan.shop/blogs/detail/21
想做或者在做副业的朋友欢迎加微信交流:farmerlzj,公众号:生财空间站。

#react#PDF 预览

相关推荐

react中实现markdown文件读取展示

react中实现markdown文件读取展示

umi实践问题汇总--持续更新

在使用umi的过程中所遇到问题的记录汇总