欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

前端實(shí)現(xiàn)PDF預(yù)覽的三種方法介紹

 更新時(shí)間:2025年03月11日 08:52:05   作者:JinSoooo  
這篇文章主要為大家詳細(xì)介紹了前端實(shí)現(xiàn)PDF預(yù)覽的三種方法,包括pdfjs-dist,react-pdf和pdf-viewer,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下

PDF預(yù)覽的選型

對于瀏覽器自帶的PDF預(yù)覽

如果能直接使用,那自然最好不過了,但考慮多種因素,比如權(quán)限問題,禁止用戶去下載PDF、預(yù)覽樣式不統(tǒng)一(不同瀏覽器PDF預(yù)覽的實(shí)現(xiàn)不同),所有最終放棄了該方式

看了很多例子,大部分都是圍繞pdf.js這個(gè)庫展開的,所以我的選項(xiàng)也是圍繞它去找的

最終找到幾個(gè)不錯(cuò)的

  • pdfjs-dist
  • react-pdf
  • pdf-viewer

接下來我會依次介紹一下三個(gè)庫的使用

pdfjs-dist

其實(shí)就是pdfjs庫,只是對其進(jìn)行打包發(fā)布到npm了

直接根據(jù)官方文檔的案例對比進(jìn)行操作就行了

Examples

import { useEffect, useRef } from 'react'
import * as PDFJS from 'pdfjs-dist'

PDFJS.GlobalWorkerOptions.workerSrc = `//unpkg.com/pdfjs-dist@${pdfjs.version}/legacy/build/pdf.worker.min.js`

interface Props {
  fileUrl: string
}

const FilePDF = ({ fileUrl }: Props) => {
  const pdfContainer = useRef<HTMLCanvasElement>(null)
  const pdfCtx = useRef<CanvasRenderingContext2D | null>(null)
  const pdfDoc = useRef<any>()
  const pdfNumPages = useRef(0)

	// 依次渲染所有頁面
  const renderPage = num => {
    pdfDoc.current!.getPage(num).then(page => {
      const viewport = page.getViewport({ scale: 1 })
      pdfContainer.current!.width = viewport.width
      pdfContainer.current!.height = viewport.height

      page
        .render({
          viewport,
          canvasContext: pdfCtx.current!
        })
        .promise.then(() => {
          if (num < pdfNumPages.current) {
            renderPage(num + 1)
          }
        })
    })
  }

  useEffect(() => {
    pdfCtx.current = pdfContainer.current!.getContext('2d')

    PDFJS.getDocument(fileUrl).promise.then(pdfDoc_ => {
      pdfDoc.current = pdfDoc_
      pdfNumPages.current = pdfDoc_.numPages
      renderPage(1)
    })
  }, [])

  return (
    <div className={'flex h-full w-full items-center justify-center rounded-lg'}>
      <canvas ref={pdfContainer}></canvas>
    </div>
  )
}

export default FilePDF

這種實(shí)現(xiàn)比較繁瑣,所以也就有了react-pdf,對pdfjs-dist進(jìn)行了一層封裝

效果展示

react-pdf

這種相對于原生pdfjs,簡單了很多

import { useRef, useState } from 'react'
import { Document, Page, pdfjs } from 'react-pdf'
import 'react-pdf/dist/Page/AnnotationLayer.css'
import 'react-pdf/dist/Page/TextLayer.css'

pdfjs.GlobalWorkerOptions.workerSrc = `//unpkg.com/pdfjs-dist@${pdfjs.version}/legacy/build/pdf.worker.min.js`

interface Props {
  fileUrl: string
}

const FilePDF = ({ fileUrl }: Props) => {
  const documentRef = useRef<HTMLDivElement>()
  const scale = useRef(1)
  const [pageNumber, setPageNumber] = useState<number>(1)

  const renderDocumentPage = (num: number, total: number) => {
    if (num <= total) {
      setPageNumber(num)
      requestIdleCallback(() => renderDocumentPage(num + 1, total))
    }
  }

  const onDocumentLoadSuccess = ({ numPages, ...rest }: { numPages: number }) => {
    requestIdleCallback(() => renderDocumentPage(1, numPages))
  }

  return (
    <div
      className={
        'flex h-full w-full justify-center overflow-auto rounded-lg bg-[#525659]'
      }
    >
      <Document
        ref={documentRef}
        file={fileUrl}
        onLoadSuccess={onDocumentLoadSuccess}
        loading="努力加載中..."
        renderMode="canvas"
      >
        {Array.from({ length: pageNumber }).map((_, i) => (
          <Page pageNumber={i + 1} className="mt-6" loading="努力加載中..." />
        ))}
      </Document>
    </div>
  )
}

export default FilePDF

但是,功能太少了,如果需要添加都要自己實(shí)現(xiàn)一遍,也很繁瑣,所以還是用了pdfjs提供的viewer來實(shí)現(xiàn)這個(gè)效果的

這邊的效果和pdfjs-dist呈現(xiàn)的是一樣的

pdf-viewer

提示:使用的環(huán)境是 Vite + React

首先先根據(jù)自己的需求下載對應(yīng)的build包

Getting Started

解壓后,將其中的buildweb文件夾移入public中,也便后續(xù)能夠直接在線上進(jìn)行訪問

這樣就將 pdfjs 和 viewer 加載進(jìn)來了,你可以啟動項(xiàng)目到 /web/viewer.html 路徑下訪問,測試是否生效

接下來,我們對其進(jìn)行封裝,我通過的方式是iframe去訪問 viewer 來展示pdf的

interface Props {
  fileUrl: string
}

const FilePDF = ({ fileUrl }: Props) => {
  return (
    <div className={'h-full w-full overflow-hidden rounded-lg'}>
      <iframe
        className="border-0"
        title="預(yù)覽文檔"
        src={`/graphicPlatform/web/viewer.html?file=${encodeURIComponent(fileUrl)}`}
        width="100%"
        height="100%"
      ></iframe>
    </div>
  )
}

export default FilePDF

注意:

因?yàn)槲募窂绞且粋€(gè)url鏈接,不能直接當(dāng)作鏈接,需要對其特殊字符進(jìn)行轉(zhuǎn)義,不然 viewer 沒辦法識別到真正的url

接著,我們還要到viewer里去修改一下接收到的file字符串,進(jìn)行還原

這樣 viewer 才能真正接收到fileUrl

最終呈現(xiàn)

encodeURI 和 encodeURIComponent 的區(qū)別

encodeURIComponent() 函數(shù) 與 encodeURI() 函數(shù)的區(qū)別之處,前者假定它的參數(shù)是 URI 的一部分(比如協(xié)議、主機(jī)名、路徑或查詢字符串)。因此 encodeURIComponent() 函數(shù)將轉(zhuǎn)義用于分隔 URI 各個(gè)部分的標(biāo)點(diǎn)符號。

Viewer

再回到一開始的問題,我們需要禁用用戶下載、打印等等功能,所以我們需要進(jìn)入到 viewer 代碼里進(jìn)行刪除對應(yīng)的功能

首先在 viewer 中刪除相關(guān)元素

viewer.html

viewer.mjs

刪除無用文件

/web/locale

最終呈現(xiàn)

以上就是前端實(shí)現(xiàn)PDF預(yù)覽的三種方法介紹的詳細(xì)內(nèi)容,更多關(guān)于前端預(yù)覽PDF的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • 使用百度地圖實(shí)現(xiàn)地圖網(wǎng)格的示例

    使用百度地圖實(shí)現(xiàn)地圖網(wǎng)格的示例

    下面小編就為大家分享一篇使用百度地圖實(shí)現(xiàn)地圖網(wǎng)格的示例,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-02-02
  • canvas實(shí)現(xiàn)弧形可拖動進(jìn)度條效果

    canvas實(shí)現(xiàn)弧形可拖動進(jìn)度條效果

    本篇文章主要介紹了canvas實(shí)現(xiàn)弧形可拖動進(jìn)度條的實(shí)例方法,具有很好的參考價(jià)值。下面跟著小編一起來看下吧
    2017-05-05
  • 在線演示常用javascript特效

    在線演示常用javascript特效

    圖形顯示特效鼠標(biāo)驅(qū)動圖片變化隨機(jī)顯示banner圖片隨意移動圖片定期消失字符連續(xù)消隱文字不停變色JavaScript容錯(cuò)...圖片循環(huán)顯現(xiàn)QQ菜單生成器圖形顯示特效連續(xù)滾動的圖片圖片水中倒影純JavaScript時(shí)鐘圖片翻滾導(dǎo)航星星滿天閃爍左側(cè)的極酷...
    2008-04-04
  • javascript css在IE和Firefox中區(qū)別分析

    javascript css在IE和Firefox中區(qū)別分析

    我們討論的主題CSS網(wǎng)頁布局,最令大家頭疼的問題就是瀏覽器兼容性,雖然52CSS.com介紹過很多這方向的知識,但依然讓很多開發(fā)人員暈頭轉(zhuǎn)向,今天的這篇文章,將列出css和javascript在IE和Firefox中二十三個(gè)不同點(diǎn),希望對大家的學(xué)習(xí)有所幫助。
    2009-02-02
  • 圖片輪換效果實(shí)現(xiàn)代碼(點(diǎn)擊按鈕停止執(zhí)行)

    圖片輪換效果實(shí)現(xiàn)代碼(點(diǎn)擊按鈕停止執(zhí)行)

    在這個(gè)實(shí)例中需要注意的是,要把images文件夾下圖片的命名設(shè)置為有順序的,1、2、3..才可以,感興趣的朋友可以參考下
    2013-04-04
  • js監(jiān)聽鼠標(biāo)事件控制textarea輸入字符串的個(gè)數(shù)

    js監(jiān)聽鼠標(biāo)事件控制textarea輸入字符串的個(gè)數(shù)

    一個(gè)js控制textarea輸入字符串的個(gè)數(shù)的腳本,當(dāng)鼠標(biāo)按下抬起時(shí)判斷輸入字符數(shù),很簡單,但很實(shí)用
    2014-09-09
  • JavaScript 輪播圖和自定義滾動條配合鼠標(biāo)滾輪分享代碼貼

    JavaScript 輪播圖和自定義滾動條配合鼠標(biāo)滾輪分享代碼貼

    本文給大家分享一段js輪播圖和自定義滾動條的代碼片段,布局和樣式小編沒給大家多介紹,大家可以根據(jù)個(gè)人需求優(yōu)化,具體實(shí)現(xiàn)代碼,大家可以參考下面代碼片段
    2016-10-10
  • ES6學(xué)習(xí)筆記之map、set與數(shù)組、對象的對比

    ES6學(xué)習(xí)筆記之map、set與數(shù)組、對象的對比

    這篇文章主要給大家介紹了關(guān)于ES6學(xué)習(xí)筆記之map、set與數(shù)組、對象對比的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧。
    2018-03-03
  • javascript跑馬燈抽獎實(shí)例講解

    javascript跑馬燈抽獎實(shí)例講解

    這篇文章主要為大家介紹了javascript跑馬燈抽獎特效,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2016-01-01
  • 小程序自定義tabBar組件封裝

    小程序自定義tabBar組件封裝

    這篇文章主要為大家詳細(xì)介紹了小程序自定義tabBar組件封裝,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-11-11

最新評論