移动端H5的PDF文件在线预览

4,197 阅读3分钟

目前市面上有很多pdf在浏览器的在线预览和操作,这里选取三种进行说明:

1、react-pdf-js

使用react-pdf-js实现H5段的在线预览关键代码如下:

  // 1、安装react-pdf-js
  npm install react-pdf-js或yarn add react-pdf-js // 使用的版本是5.1.0
  // 2、在react中引入并实现
  ...
  import PDF from "react-pdf-js;
  ...
  
  export default function (){
      ...
      const [page, setPage] = useState(1); //pdf当前页数
      const [pageTotal, setPageTotal] = useState(0); //pdf总页数
      
      return(
          <div>
              <PDF 
                file={pdfUrl} // pdf的文件路径
                page={1} 
                onDocumentComplete={(pages) => {
                  setPage(1);
                  setPageTotal(pages);
                }}
              />
              {
                pageTotal
                  ? new Array(pageTotal).fill('').map((_, index) => {
                    return index + 1 !== 1 ? <PDF key={index} file={pdfUrl} page={index + 1} /> : '';
                  })
                : 
                ''
              }
          </div>
      );
  }

2、react-pdf

网上有很多关于react-pdf实现在预览pdf的方法【也可以参考github上的说明:github.com/wojtekmaj/r… 】,此处就不多赘述,关键代码如下:

  // 1、安装react-pdf
  npm install react-pdf或yarn add react-pdf // 使用的版本是7.1.2
  // 2、react中导入并实现
  ...
  import { Document, Page, pdfjs } from 'react-pdf';
  ...
  
  import 'react-pdf/dist/esm/Page/AnnotationLayer.css';
  import 'react-pdf/dist/esm/Page/TextLayer.css';
  import 'xxx.less'; // 自己的样式文件
  
  // 重点注意,需要引入这一行
  pdfjs.GlobalWorkerOptions.workerSrc = `//unpkg.com/pdfjs-dist@2.4.456/build/pdf.worker.min.js`;
  const options = {
    cMapUrl: 'cmaps/',
    standardFontDataUrl: 'standard_fonts/',
  };
  
  export default function (){
      ...
      const [numPages, setNumPages] = useState(0); // pdf的页数
      
      return (
          <div>
              ...
             <Document 
               className={"pdfViewer"}
               file={{url: pdfUrl}}
               onLoadSuccess={(res) => {
                 // console.log(res?.numPages, "res");
                 setNumPages(res?.numPages);
               }}
               onLoadError={(err) => {
                 console.log(err, "err");
               }}
               options={options}
             >
               {Array.from(new Array(numPages), (_, index) => (
                 <Page key={`page_${index + 1}`} pageNumber={index + 1} width={337}/>
               ))}
             </Document>
          </div>
      );
  }

3、@react-pdf-viewer/core

使用@react-pdf-viewer/core实现在线pdf预览的关键代码如下,具体可参考github或官网上的使用说明。github:github.com/react-pdf-v… ,官网:react-pdf-viewer.dev/

// 1、安装@react-pdf-viewer/core和@react-pdf-viewer/default-layout
npm install @react-pdf-viewer/core @react-pdf-viewer/default-layout或yarn add @react-pdf-viewer/core @react-pdf-viewer/default-layout // 使用的版本是3.12.0
// 2、react中导入并实现
...
import { Viewer, Worker, SpecialZoomLevel } from '@react-pdf-viewer/core';
import { defaultLayoutPlugin } from "@react-pdf-viewer/default-layout";
...

import '@react-pdf-viewer/core/lib/styles/index.css';
import '@react-pdf-viewer/default-layout/lib/styles/index.css';
import 'xxx.less'; // 自己的样式文件

...

// 使用插件的方式,包括放大缩小,pdf翻页等,下面是以全屏插件为例说明,如果只是简单的预览则可以不用插件
const defaultLayoutPluginInstance = defaultLayoutPlugin({
    toolbarPlugin: {
      fullScreenPlugin: {
        // Zoom to fit the screen after entering and exiting the full screen mode
        onEnterFullScreen: (zoom) => {
          zoom(SpecialZoomLevel.PageFit);
        },
        onExitFullScreen: (zoom) => {
          zoom(SpecialZoomLevel.PageFit);
        },
      },
    },
});

return (
   <div>
       ...
       <Worker workerUrl="https://unpkg.com/pdfjs-dist@2.4.456/build/pdf.worker.min.js"> // 换成了2.x的版本
          <Viewer
            fileUrl={pdfUrl}
            // plugins={[defaultLayoutPluginInstance]} // 使用上述插件的方式
          />
      </Worker>
       ...
   </div>
);

【额外拓展】小程序端实现pdf在线预览

微信小程序官网已有下载和打开pdf的功能,但是在小程序中浏览pdf是将文件下载到本地并打开,并且无论如何都会新打开一个窗口,如果需要再已有的窗口上实现pdf的预览,则需要在小程序中使用webview组件来嵌入一个H5界面。经过个人实践上述三种方式均可以实现小程序的pdf在线预览,具体的问题如下:

1、react-pdf-js:无法对容器进行自适应匹配,在模拟机上浏览的话,会出现pdf文件或页面的内容超出容器的情况;

2、react-pdf:当使用webview嵌入到小程序中会出现错误(如果是以H5来展示就不会出现此问题):key.split(...).at is not a function。网上说这是由于pdfjs版本问题导致,需要降级版本,但是研究了一阵还是未找到合适的版本;

3、@react-pdf-viewer/core:最开始嵌入到小程序中出现了和react-pdf同样的问题(如果是以H5来展示就不会出现此问题),因此在上述第33行讲pdfjs换成了2.4.456的老版本。后在小程序中可实现pdf的在线预览

image.png