亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

文件預(yù)覽PDF.js使用技巧示例總結(jié)

 更新時(shí)間:2023年03月05日 15:29:33   作者:Jiaynn  
這篇文章主要為大家介紹了文件預(yù)覽PDF.js使用技巧示例總結(jié),有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

Pdf.js有兩種使用方式

在這次的項(xiàng)目中用到了pdf文件的預(yù)覽功能,選擇了pdf.js去預(yù)覽pdf文件,實(shí)現(xiàn)滑動(dòng)展示所有的pdf

  • 通過(guò) npm 下載
  • 直接下載 pdf.js 庫(kù),當(dāng)作靜態(tài)資源使用

把pdf.js當(dāng)作靜態(tài)資源使用

最開(kāi)始我采取的是把pdf.js當(dāng)作靜態(tài)資源使用,使用方法如下:

  • 官網(wǎng)下載后解壓項(xiàng)目得到 pdf.js
  • 放到項(xiàng)目文件夾 /public/static/ 下
  • 直接將 web/viewer.html 后面的 file 跟上自己自己的 pdf 文件即可
    contentUrl.current = content.includes("pdf")
    ? `/static/pdfjs-3.1.81-dist/web/viewer.html?file=${content}`
    : content;
    <iframe src={contentUrl.current}></iframe>

使用靜態(tài)資源時(shí),如果需要更改他的默認(rèn)樣式需要自己手動(dòng)改源代碼

同時(shí)可能我們遇到了跨域問(wèn)題,我們需要在源碼中的判斷跨域代碼注釋掉

使用靜態(tài)資源的問(wèn)題是在移動(dòng)端不能手勢(shì)放大縮小,需要我們自己編寫(xiě)代碼然后修改源代碼強(qiáng)制放大縮小

這種方式不細(xì)講,網(wǎng)上很多使用方式都是通過(guò)使用靜態(tài)資源,可以自行去查看,這里只講一個(gè)大概。

npm下載,通過(guò)import使用

方法如下:

npm install pdfjs-dist
const contentRef = useRef<HTMLDivElement | null>(null);
useEffect(() => {
//content就是 iframe 請(qǐng)求的url,這里是因?yàn)槲业捻?xiàng)目里面需要判斷下他url是否涵蓋了pdf
//如果涵蓋了才使用pdf.js
  content.includes('pdf')
  //重點(diǎn)是 loadPdf() 這個(gè)函數(shù),就是我們使用 pdf.js 的函數(shù)
    ? loadPdf(contentRef.current, content, loadingRef.current)
    : null;
}, [content]);
<div className="content-wrapper" ref={contentRef}>
  {content.includes('pdf') ? null : <iframe src={content}></iframe>}
  <div className="loading" ref={loadingRef} style={{ display: 'none' }}></div>
</div>
import * as pdf from 'pdfjs-dist';
import pdfWorker from 'pdfjs-dist/build/pdf.worker.js?url';
pdf.GlobalWorkerOptions.workerSrc = pdfWorker;
/**
 * @desc 使用pdf.js加載pdf
 * @param contentDom
 * @param url
 */
export const loadPdf = async (
  contentDom: HTMLDivElement | null,
  url: string,
  loadingDom: HTMLDivElement | null
) => {
//得到請(qǐng)求的 pdf 文件
  const loadingTask = pdf.getDocument({
    url: url,
    disableRange: true
  });
  //loading效果,下載pdf過(guò)程中展示loading
  loadingTask.onProgress = () => {
    if (loadingDom) {
      loadingDom.style.display = 'block';
    }
  };
  loadingTask.promise.then((pdfDoc) => {
  //下載完成時(shí),loading消失
    if (loadingDom) {
      loadingDom.style.display = 'none';
    }
    //得到 pdf 總頁(yè)數(shù)
    const totalPages = pdfDoc.numPages;
    for (let i = 1; i <= totalPages; i++) {
      pdfDoc.getPage(i).then((page) => {
        const canvas = document.createElement('canvas');
        canvas.setAttribute('id', `the-canvas${i}`);
        const ctx = canvas.getContext('2d') as CanvasRenderingContext2D;
        const dpr = window.devicePixelRatio || 1;
        const scaledViewport = page.getViewport({ scale: 1 });
        canvas.height = Math.floor(scaledViewport.height * dpr);
        canvas.width = Math.floor(scaledViewport.width * dpr);
        canvas.style.width = document.body.clientWidth + 'px';
        canvas.style.height =
          document.body.clientWidth / (canvas.width / canvas.height) + 'px';
        const transform = dpr !== 1 ? [dpr, 0, 0, dpr, 0, 0] : undefined;
        const renderContext = {
          canvasContext: ctx,
          viewport: scaledViewport,
          transform: transform
        };
        page.render(renderContext);
        contentDom?.appendChild(canvas);
      });
    }
  });
};

上面的代碼展示了我使用pdf.js的整個(gè)使用過(guò)程,主要思路是先獲取到pdf文件,然后得到總頁(yè)數(shù)后通過(guò)生成響應(yīng)頁(yè)數(shù)的canvas,然后再渲染到頁(yè)面上展示pdf

這里需要注意的是scaledViewport.height得到的是你的pdf文件本身的寬高,我們需要通過(guò)這個(gè)寬高進(jìn)行適配我們自己的屏幕,同時(shí)需要保證他的清晰度,所以我們需要保證canvas兩個(gè)寬高的尺寸是一致的。

canvas 本身有兩個(gè)寬高,標(biāo)簽的 width 和 height 是繪畫(huà)區(qū)域?qū)嶋H寬度和高度,繪制的圖形都是在這個(gè)上面。而 style 的 width 和 height 是 canvas 在瀏覽器中被渲染的高度和寬度,如果 canvas 標(biāo)簽中沒(méi)有定義 width 和 height 時(shí),默認(rèn)會(huì)給寬 300 高 150,所以就出現(xiàn)了拉伸的效果,不想用默認(rèn)的寬高的話(huà),盡量在標(biāo)簽中寫(xiě)上寬高的屬性。

所以,如上面的代碼一樣,寬度就是整個(gè)屏幕的寬度,但是每個(gè)pdf頁(yè)面的高度,需要保證和canvas.width/canvas.height的尺寸一致

canvas.style.height = document.body.clientWidth / (canvas.width / canvas.height) + 'px';

這樣就能展示pdf文件了

這里又存在一個(gè)問(wèn)題,文件過(guò)大,而pdf.js的渲染原理是需要將整個(gè)pdf文件下載下來(lái)后,再進(jìn)行展示,這就導(dǎo)致了白屏的時(shí)間過(guò)長(zhǎng),用戶(hù)體驗(yàn)感不好,然后我們就想到了分片下載

我們需要在 getDocument()這個(gè)api上增加一些配置

const loadingTask = pdf.getDocument({
		url: url,
		//disableRange: true,  
		rangeChunkSize: 65536 * 16,
		disableAutoFetch: true
	});

分片下載還有一個(gè)很重要的點(diǎn),就是需要判斷下你訪(fǎng)問(wèn)的pdf是否支持分片下載,使用了分片下載的請(qǐng)求是后續(xù)會(huì)通過(guò)你的分片大小發(fā)送206請(qǐng)求

HTTP206狀態(tài)碼代表的意思是 請(qǐng)求已成功處理,但僅返回了部分內(nèi)容,即 HTTP 206 Partial Content 響應(yīng)狀態(tài)。

HTTP 206 (Http Status Code 206) 狀態(tài)是HTTP協(xié)議的一種響應(yīng)碼,是我們請(qǐng)求訪(fǎng)問(wèn)網(wǎng)站時(shí),服務(wù)器端返回的2xx 成功狀態(tài)系列響應(yīng)碼之一。

查看是否支持分片下載

需要有這個(gè)響應(yīng)頭才是支持分片下載 accept-range:bytes

但后面我們遇到一個(gè)問(wèn)題:我們的pdf鏈接存在這個(gè)響應(yīng)頭,但卻不支持分片下載,后面通過(guò)對(duì)比發(fā)現(xiàn)是這個(gè)響應(yīng)頭 access-control-expose-headers 的問(wèn)題

響應(yīng)標(biāo)頭 Access-Control-Expose-Headers 允許服務(wù)器指示哪些響應(yīng)標(biāo)頭應(yīng)該對(duì)瀏覽器中運(yùn)行的腳本可用,以響應(yīng)跨源請(qǐng)求。

我們最開(kāi)始這個(gè)響應(yīng)頭里面的內(nèi)容沒(méi)有Access-Control-Expose-Headers,意味著就算存在 accept-range 這個(gè)響應(yīng)頭,瀏覽器也不可用,所以在后面我們添加上這個(gè)響應(yīng)頭的內(nèi)容后就可以使用分片下載了。

API(記錄一下,防止忘記)

這個(gè)api來(lái)源于掘金的某位大佬

屬性說(shuō)明類(lèi)型默認(rèn)值
屬性說(shuō)明類(lèi)型默認(rèn)值
worker用于加載和解析 PDF 數(shù)據(jù)的工作器PDFWorker-
withCredentials指示是否應(yīng)使用 cookie 或授權(quán)標(biāo)頭等憑據(jù)發(fā)出跨站點(diǎn)訪(fǎng)問(wèn)控制請(qǐng)求。Booleanfalse
verbosity控制日志記錄級(jí)別;應(yīng)該使用 VerbosityLevel 中的常量Number-
useWorkerFetch在讀取 CMap 和標(biāo)準(zhǔn)字體文件時(shí)啟用在工作線(xiàn)程中使用 Fetch API。當(dāng)為“true”時(shí),會(huì)忽略“CMapReaderFactory”和“StandardFontDataFactory”選項(xiàng)。 Web 環(huán)境中的默認(rèn)值為 true,Node.js 中的默認(rèn)值為 falseBoolean-
useSystemFonts是否使用系統(tǒng)字體Booleanfalse
urlPDF的url地址String  URL
stopAtErrors拒絕某些方法,例如getOperatorList、getTextContent 和 RenderTask,當(dāng)相關(guān)的 PDF 數(shù)據(jù)無(wú)法成功解析時(shí),而不是嘗試恢復(fù)任何可能的數(shù)據(jù)Booleanfalse
standardFontDataUrl標(biāo)準(zhǔn)字體文件所在的地址。包括尾部斜杠String-
StandardFontDataFactory讀取標(biāo)準(zhǔn)字體文件時(shí)將使用的工廠(chǎng)。提供自定義工廠(chǎng)對(duì)于沒(méi)有 Fetch API 或 XMLHttpRequest 支持的環(huán)境很有用,例如 Node.jsObject{DOMStandardFontDataFactory}
rangeChunkSize指定每個(gè)范圍請(qǐng)求獲取的最大字節(jié)數(shù)NumberDEFAULT_RANGE_CHUNK_SIZE
range允許使用自定義范圍PDFDataRangeTransport-
pdfBug啟用用于調(diào)試 PDF.js 的特殊鉤子(請(qǐng)參閱web / debugger.js)Objectfalse
password用于解密受密碼保護(hù)的 PDFString-
ownerDocument指定一個(gè)顯式的文檔上下文來(lái)創(chuàng)建元素并將資源(例如字體)加載到其中HTMLDocument-
maxImageSize總像素中允許的最大圖像大小,即寬 * 高。不會(huì)呈現(xiàn)高于此值的圖像。使用 -1 表示沒(méi)有限制,這也是默認(rèn)值Number-
lengthPDF 文件長(zhǎng)度。它用于進(jìn)度報(bào)告和范圍請(qǐng)求操作Number-
isEvalSupported確定我們是否可以將字符串評(píng)估為 JavaScript。主要用于提高字體渲染的性能,以及解析 PDF 函數(shù)時(shí)Booleantrue
initialData帶有第一部分或全部 pdf 數(shù)據(jù)的類(lèi)型化數(shù)組。由擴(kuò)展使用,因?yàn)樵谇袚Q到范圍請(qǐng)求之前已經(jīng)加載了一些數(shù)據(jù)。TypedArray-
httpHeaders基本身份驗(yàn)證請(qǐng)求頭Object-
fontExtraProperties從工作線(xiàn)程導(dǎo)出解析的字體數(shù)據(jù)時(shí),包括在渲染 PDF 文檔期間未使用的其他屬性,這對(duì)于調(diào)試目的(和向后兼容性)可能很有用,但請(qǐng)注意,它會(huì)導(dǎo)致內(nèi)存使用量增加Booleanfalse
enableXfa渲染 Xfa 表格Booleanfalse
docBaseUrl文檔的基本 URL,在嘗試恢復(fù)注釋和大綱項(xiàng)的有效絕對(duì) URL 時(shí)使用,(錯(cuò)誤地)僅指定了相對(duì) URLstring-
disableStream禁用 PDF 文件數(shù)據(jù)的流式傳輸。默認(rèn)情況下,PDF.js 嘗試分塊加載 PDF 文件Objectfalse
disableRange禁用 PDF 文件的范圍請(qǐng)求加載。啟用后,如果服務(wù)器支持部分內(nèi)容請(qǐng)求,則 PDF 將分塊獲取Booleanfalse
disableFontFace默認(rèn)情況下,字體會(huì)轉(zhuǎn)換為 OpenType 字體并通過(guò)字體加載 API 或@font-face 規(guī)則加載。如果禁用,字體將使用內(nèi)置字體渲染器渲染,該渲染器使用原始路徑命令構(gòu)建字形。Boolean-
disableAutoFetch禁用預(yù)取 PDF 文件數(shù)據(jù)。啟用范圍請(qǐng)求后,即使不需要顯示當(dāng)前頁(yè)面,PDF.js 也會(huì)自動(dòng)繼續(xù)獲取更多數(shù)據(jù)Objectfalse
data二進(jìn)制 PDF 數(shù)據(jù)。使用類(lèi)型化數(shù)組 (Uint8Array) 來(lái)提高內(nèi)存使用率。如果 PDF 數(shù)據(jù)是 BASE64 編碼的,請(qǐng)先使用 atob() 將其轉(zhuǎn)換為二進(jìn)制字符串。TypedArray、Array、String-
cMapUrl預(yù)定義 Adobe CMap 所在的 URL。包括尾部斜杠String-
CMapReaderFactory自定義工廠(chǎng)對(duì)于沒(méi)有 Fetch API 或 XMLHttpRequest 支持的環(huán)境很有用,例如 Node.jsObject{DOMCMapReaderFactory}
cMapPacked指定 Adobe CMap 是否是二進(jìn)制打包Boolean-

最后,發(fā)現(xiàn)可能是這個(gè)庫(kù)的問(wèn)題還是什么,目前不太清楚,他總是從13M以上才開(kāi)始快速渲染,而我們當(dāng)時(shí)的文件大小差不多也是13M,所以采用了分片下載后,還是存在一段比較長(zhǎng)的白屏?xí)r間,所以最后還是選用了將pdf轉(zhuǎn)成圖片再顯示的形式。

以上就是文件預(yù)覽PDF.js使用技巧示例總結(jié)的詳細(xì)內(nèi)容,更多關(guān)于文件預(yù)覽PDF.js的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • JS簡(jiǎn)單獲取當(dāng)前年月日星期的方法示例

    JS簡(jiǎn)單獲取當(dāng)前年月日星期的方法示例

    這篇文章主要介紹了JS簡(jiǎn)單獲取當(dāng)前年月日星期的方法,結(jié)合完整實(shí)例形式分析了javascript基于自定義函數(shù)獲取當(dāng)前日期時(shí)間的方法,涉及javascript中Date()類(lèi)的使用與日期相關(guān)運(yùn)算技巧,需要的朋友可以參考下
    2017-02-02
  • JavaScript判斷數(shù)據(jù)類(lèi)型有幾種方法及區(qū)別介紹

    JavaScript判斷數(shù)據(jù)類(lèi)型有幾種方法及區(qū)別介紹

    這篇文章主要介紹了JavaScript判斷數(shù)據(jù)類(lèi)型有幾種方法及區(qū)別介紹,本文給大家分享多種方法通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-09-09
  • jquery的$getjson調(diào)用并獲取遠(yuǎn)程的JSON字符串問(wèn)題

    jquery的$getjson調(diào)用并獲取遠(yuǎn)程的JSON字符串問(wèn)題

    jQuery中常用getJSON來(lái)調(diào)用并獲取遠(yuǎn)程的JSON字符串,將其轉(zhuǎn)換為JSON對(duì)象,如果成功,則執(zhí)行回調(diào)函數(shù),本文將詳細(xì)介紹,需要的朋友可以參考下
    2012-12-12
  • js隱式全局變量造成的bug示例代碼

    js隱式全局變量造成的bug示例代碼

    一段js代碼遇到一個(gè)bug,由于中間的隱式全局變量造成的,通過(guò)谷歌瀏覽器的js調(diào)試器才找到問(wèn)題所在,下面將代碼與大家分享下
    2014-04-04
  • 你不知道的前端console用法分享

    你不知道的前端console用法分享

    console一定是各位前端最熟悉的小伙伴了,有些網(wǎng)站還會(huì)在控制臺(tái)輸出一些有意思的東西,下面這篇文章主要給大家介紹了關(guān)于前端console用法的相關(guān)資料,文中通過(guò)代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2024-08-08
  • viewer.js實(shí)現(xiàn)圖片預(yù)覽功能

    viewer.js實(shí)現(xiàn)圖片預(yù)覽功能

    這篇文章主要為大家詳細(xì)介紹了viewer.js實(shí)現(xiàn)圖片預(yù)覽功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-06-06
  • JavaScript獲取服務(wù)器端時(shí)間的方法

    JavaScript獲取服務(wù)器端時(shí)間的方法

    這篇文章主要介紹了JavaScript獲取服務(wù)器端時(shí)間的方法,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下
    2016-11-11
  • JS中注入eval, Function等系統(tǒng)函數(shù)截獲動(dòng)態(tài)代碼

    JS中注入eval, Function等系統(tǒng)函數(shù)截獲動(dòng)態(tài)代碼

    這篇文章主要介紹了JS中注入eval, Function等系統(tǒng)函數(shù)截獲動(dòng)態(tài)代碼,非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2019-04-04
  • 原生js實(shí)現(xiàn)鼠標(biāo)跟隨效果

    原生js實(shí)現(xiàn)鼠標(biāo)跟隨效果

    本文主要分享了原生js實(shí)現(xiàn)鼠標(biāo)跟隨效果的實(shí)例,具有很好的參考價(jià)值,下面跟著小編一起來(lái)看下吧
    2017-02-02
  • 實(shí)現(xiàn)圖片首尾平滑輪播(JS原生方法—節(jié)流)

    實(shí)現(xiàn)圖片首尾平滑輪播(JS原生方法—節(jié)流)

    下面小編就為大家?guī)?lái)一篇實(shí)現(xiàn)圖片首尾平滑輪播(JS原生方法—節(jié)流)。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-10-10

最新評(píng)論