最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Vue項(xiàng)目pdf(base64)轉(zhuǎn)圖片遇到的問(wèn)題及解決方法

 更新時(shí)間:2018年10月19日 17:20:55   投稿:mrr  
這篇文章主要介紹了Vue項(xiàng)目pdf(base64)轉(zhuǎn)圖片遇到的問(wèn)題及解決方法,需要的朋友可以參考下

公司有個(gè)業(yè)務(wù)需求,要求后臺(tái)傳pdf的base64編碼給前端,前端顯示到界面上,后來(lái)在網(wǎng)上搜索了很多關(guān)于base64轉(zhuǎn)pdf的文章,都寫的不是非常的詳細(xì),在實(shí)現(xiàn)的過(guò)程中遇到很多坑,經(jīng)過(guò)一天的研究終于實(shí)現(xiàn)了這個(gè)功能,分享一下我在這個(gè)功能中遇到的問(wèn)題和解決方法

要注明的是這里用到的核心插件是pdf.js,原理是動(dòng)態(tài)生成canvas標(biāo)簽,然后通過(guò)pdf.js生成一個(gè)能渲染出pdf的對(duì)象,隨后渲染每個(gè)canvas,并且生成的pdf是畫面的形式,并沒(méi)有pdf之類的控件

引入插件

這里很多博客都是使用JavaScript原生的方法引入pdf.js,例如使用script標(biāo)簽引入外部的js腳本,或者直接把pdf.js的源碼復(fù)制到項(xiàng)目中,但是我嘗試這些方法的時(shí)候都不是特別好用,而且引入后導(dǎo)致項(xiàng)目體積過(guò)于龐大,

隨后我去github上尋找通過(guò)包管理器引入pdf.js的方法,在pdf.js的github上官方說(shuō)明的是用gulp如何使用pdf.js,但是對(duì)于npm來(lái)說(shuō)并沒(méi)有詳細(xì)說(shuō)明,終于我在字里行間發(fā)現(xiàn)了這么一句話

To use PDF.js in a web application you can choose to use a pre-built version of the library or to build it from source. We supply pre-built versions for usage with NPM and Bower under the pdfjs-dist name. For more information and examples please refer to the wiki page on this subject.

大致的意思就是如果使用npm包管理器或者bower的話,引入的名字為pdfjs-dist,那么我們使用npm的方法引入這個(gè)pdfjs-dist,引入的名字就隨意取名了這里我叫PDFJS

 import PDFJS from 'pdfjs-dist'

使用pdfjs-dist

這里后臺(tái)傳給我的是一個(gè)由pdf文件名字和pdf的base64編碼組成的對(duì)象的數(shù)組,我取名為pdfDataList

可以看到fileName是pdf的名字,fileVale是pdf文件的base64編碼,thumbnail是pdf縮略圖的base64編碼這里用不到先不管,之前說(shuō)到需要?jiǎng)討B(tài)生成canvas節(jié)點(diǎn)(這里不會(huì)canvas也不要緊,只需要根據(jù)代碼一步步做就能渲染canvas)

1.首先我們創(chuàng)建一個(gè)承載所有canvas節(jié)點(diǎn)的父節(jié)點(diǎn),取名為pdfList

2.然后創(chuàng)建一個(gè)異步函數(shù)showPdf(不懂什么是異步函數(shù)的可以去查一下async/await,這里不用異步函數(shù)也可以使用promise.then的方法,但是async/await作為異步操作的終極方案最好還是學(xué)習(xí)一下)

async showPdf() {   
  }

使用querySelector選擇類名為pdfList的dom節(jié)點(diǎn),隨后遍歷后臺(tái)傳過(guò)來(lái)的pdfDataList數(shù)組的每一項(xiàng),這里用到一個(gè)瀏覽器自帶的atob()方法解碼base64,MDN上是這么解釋的:

你可以使用 window.btoa() 方法來(lái)編碼一個(gè)可能在傳輸過(guò)程中出現(xiàn)問(wèn)題的數(shù)據(jù),并且在接受數(shù)據(jù)之后,使用 atob() 方法再將數(shù)據(jù)解碼。

語(yǔ)法: var decodedData = scope.atob(encodedData);

隨后調(diào)用pdf.js插件的getDocument方法,getDocument是一個(gè)promise,所以使用異步函數(shù)的話前面需要加await關(guān)鍵字(不使用異步函數(shù)的話在方法后面加.then((pdf)=>{.......}),這個(gè)pdf對(duì)象和我這個(gè)pdf對(duì)象是同一個(gè),同時(shí)這里暫時(shí)也沒(méi)考慮異步操作出錯(cuò)的情況,有要求的話可以在加個(gè)catch捕獲錯(cuò)誤)

getDocument方法的參數(shù)是一個(gè)對(duì)象,對(duì)象鍵名為data,值為base64解碼后的值,此方法返回一個(gè)pdf對(duì)象,這個(gè)對(duì)象有幾個(gè)屬性,可以打印出來(lái)觀察一下

這里我們先用到的是numPages屬性,它指的是當(dāng)前pdf文件有多少頁(yè)

async showPdf() {
    let pdfList = document.querySelector('.pdfList') //通過(guò)querySelector選擇DOM節(jié)點(diǎn),使用document.getElementById()也一樣
    for(let value of this.pdfDataList){ //遍歷后臺(tái)傳過(guò)來(lái)的pdfDataList
      let base64 = value.fileValue //獲得bas464編碼
      let decodedBase64 = atob(base64) //使用瀏覽器自帶的方法解碼
      let pdf = await PDFJS.getDocument({data: decodedBase64}) //返回一個(gè)pdf對(duì)象
      let pages = pdf.numPages //聲明一個(gè)pages變量等于當(dāng)前pdf文件的頁(yè)數(shù)
    }
  }

獲取當(dāng)前pdf文件的對(duì)象和當(dāng)前pdf文件的所有頁(yè)數(shù)后,循環(huán)遍歷每個(gè)頁(yè)數(shù),執(zhí)行如下操作:

1)動(dòng)態(tài)創(chuàng)建canvas節(jié)點(diǎn)
2)調(diào)用pdf對(duì)象原型上的getPage()方法和getViewport()方法,依次傳入當(dāng)前循環(huán)的頁(yè)數(shù)和canvas的縮放大小(這里不懂的可以直接復(fù)制黏貼)
3)渲染當(dāng)前的canvas節(jié)點(diǎn)
4)調(diào)用page對(duì)象的render()方法渲染當(dāng)前頁(yè),此方法也是一個(gè)promise,需要使用await關(guān)鍵字等到狀態(tài)為resolve后再執(zhí)行之后的代碼
5)給顯示當(dāng)前頁(yè)面的canvas節(jié)點(diǎn)一個(gè)className為canvas方便修改樣式,最后把這個(gè)canvas節(jié)點(diǎn)插入到pdfList節(jié)點(diǎn)中

async showPdf() {
    let pdfList = document.querySelector('.pdfList') //通過(guò)querySelector選擇DOM節(jié)點(diǎn),使用document.getElementById()也一樣
    for(let value of this.pdfDataList){ //遍歷后臺(tái)傳過(guò)來(lái)的pdfDataList
      let base64 = value.fileValue //獲得bas464編碼
      let decodedBase64 = atob(base64) //使用瀏覽器自帶的方法解碼
      let pdf = await PDFJS.getDocument({data: decodedBase64}) //返回一個(gè)pdf對(duì)象
      let pages = pdf.numPages //聲明一個(gè)pages變量等于當(dāng)前pdf文件的頁(yè)數(shù)
      for (let i = 1; i <= pages; i++) { //循環(huán)頁(yè)數(shù)
       let canvas = document.createElement('canvas') 
       let page = await pdf.getPage(i) //調(diào)用getPage方法傳入當(dāng)前循環(huán)的頁(yè)數(shù),返回一個(gè)page對(duì)象
       let scale = 1;//縮放倍數(shù),1表示原始大小
       let viewport = page.getViewport(scale); 
       let context = canvas.getContext('2d'); //創(chuàng)建繪制canvas的對(duì)象
       canvas.height = viewport.height; //定義canvas高和寬
       canvas.width = viewport.width;
       let renderContext = {
        canvasContext: context,
        viewport: viewport
       };
       await page.render(renderContext)

       canvas.className = 'canvas' //給canvas節(jié)點(diǎn)定義一個(gè)class名,這里我取名為canvas
       pdfList.appendChild(canvas) //插入到pdfList節(jié)點(diǎn)的最后
      }
    }
  } 

至此頁(yè)面上就會(huì)多出一個(gè)canvas節(jié)點(diǎn)并且顯示當(dāng)前pdf文件的第一頁(yè)的圖片,如果當(dāng)前pdf文件有多頁(yè)就會(huì)渲染出多個(gè)canvas節(jié)點(diǎn),有多個(gè)pdf文件就會(huì)先循環(huán)外層,然后再循環(huán)內(nèi)層,把每個(gè)pdf文件的每一頁(yè)都生成一個(gè)canvas節(jié)點(diǎn)

 

修改樣式

渲染出頁(yè)面后還有個(gè)要注意的點(diǎn),Vue框架會(huì)給每個(gè)組件的DOM節(jié)點(diǎn)生成一個(gè)自定義屬性,而節(jié)點(diǎn)動(dòng)態(tài)生成的canvas節(jié)點(diǎn),并沒(méi)有data-v-xxxxx這樣的自定義屬性

而Vue會(huì)給每個(gè)組件里面的樣式添加這個(gè)自定義屬性,Vue框架這樣做可以防止樣式的相互污染(也就是style旁邊的scoped屬性)

我們這里可以在這個(gè)style下面再創(chuàng)建一個(gè)style寫入樣式來(lái)達(dá)到修改canvas樣式的效果,但是記得這樣做你整個(gè)項(xiàng)目里面類名叫canvas的都會(huì)獲得這個(gè)樣式,需要注意

寫在最后

這里使用的是動(dòng)態(tài)生成canvas節(jié)點(diǎn)然后渲染這個(gè)節(jié)點(diǎn)生成的圖片,然而直接使用createElement生成一個(gè)節(jié)點(diǎn)并且頻繁操作DOM會(huì)對(duì)性能有一定的影響,如果有更好的方法歡迎留言交流,感謝觀看。希望對(duì)大家有所幫助,如果大家有任何疑問(wèn)請(qǐng)給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對(duì)腳本之家網(wǎng)站的支持!

相關(guān)文章

  • 如何解決sass-loader和node-sass版本沖突的問(wèn)題

    如何解決sass-loader和node-sass版本沖突的問(wèn)題

    這篇文章主要介紹了如何解決sass-loader和node-sass版本沖突的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-04-04
  • 通過(guò)html文件來(lái)使用Vue的單文件組件形式詳解

    通過(guò)html文件來(lái)使用Vue的單文件組件形式詳解

    這篇文章主要介紹了通過(guò)html文件來(lái)使用Vue的單文件組件形式詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-05-05
  • vue二次封裝一個(gè)高頻可復(fù)用組件的全過(guò)程

    vue二次封裝一個(gè)高頻可復(fù)用組件的全過(guò)程

    在開(kāi)發(fā)Vue項(xiàng)目我們一般使用第三方UI組件庫(kù)進(jìn)行開(kāi)發(fā),但是這些組件提供的接口并不一定滿足我們的需求,這時(shí)我們可以通過(guò)對(duì)組件庫(kù)組件的二次封裝,來(lái)滿足我們特殊的需求,這篇文章主要給大家介紹了關(guān)于vue二次封裝一個(gè)高頻可復(fù)用組件的相關(guān)資料,需要的朋友可以參考下
    2022-10-10
  • 基于mpvue搭建微信小程序項(xiàng)目框架的教程詳解

    基于mpvue搭建微信小程序項(xiàng)目框架的教程詳解

    mpvue從底層支持 Vue.js 語(yǔ)法和構(gòu)建工具體系,同時(shí)再結(jié)合相關(guān)UI組件庫(kù),便可以高效的實(shí)現(xiàn)小程序開(kāi)發(fā)。這篇文章主要介紹了基于mpvue搭建小程序項(xiàng)目框架 ,需要的朋友可以參考下
    2019-04-04
  • Element plus實(shí)現(xiàn)圖片手動(dòng)上傳與回顯的過(guò)程

    Element plus實(shí)現(xiàn)圖片手動(dòng)上傳與回顯的過(guò)程

    近期,發(fā)現(xiàn)點(diǎn)擊修改,element ui 的圖片沒(méi)有回顯到框中,所以本文給大家介紹了Element plus實(shí)現(xiàn)圖片手動(dòng)上傳與回顯的過(guò)程,文中通過(guò)代碼示例給大家介紹的非常詳細(xì),具有一定的參考價(jià)值,需要的朋友可以參考下
    2024-09-09
  • Vue實(shí)現(xiàn)數(shù)據(jù)導(dǎo)入的四種方法(resource、Axios、Fetch、Excel導(dǎo)入)

    Vue實(shí)現(xiàn)數(shù)據(jù)導(dǎo)入的四種方法(resource、Axios、Fetch、Excel導(dǎo)入)

    本文主要介紹了Vue實(shí)現(xiàn)數(shù)據(jù)導(dǎo)入的四種方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-07-07
  • Vue實(shí)現(xiàn)微信小程序中預(yù)覽文件的縮放功能

    Vue實(shí)現(xiàn)微信小程序中預(yù)覽文件的縮放功能

    在微信小程序中,默認(rèn)情況下,文件預(yù)覽功能不支持文檔縮放,導(dǎo)致用戶在遇到小字體時(shí)難以清晰閱讀,為了解決這一問(wèn)題并提升用戶體驗(yàn),實(shí)現(xiàn)文檔的縮放功能至關(guān)重要,所以本文
    2024-12-12
  • 一文詳解vue生命周期在uniapp中的用法

    一文詳解vue生命周期在uniapp中的用法

    在uniapp中,vue的生命周期的用法基本都得以保留,但是對(duì)于特殊的需求以及特殊的情況,uniapp還引入了一些特有的生命周期鉤子,本文給大家詳細(xì)介紹了vue生命周期在uniapp中的用法,感興趣的朋友可以參考下
    2024-01-01
  • Vue實(shí)現(xiàn)動(dòng)態(tài)控制表格列的顯示和隱藏

    Vue實(shí)現(xiàn)動(dòng)態(tài)控制表格列的顯示和隱藏

    這篇文章主要為大家詳細(xì)介紹了Vue實(shí)現(xiàn)動(dòng)態(tài)控制表格列的顯示和隱藏,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-04-04
  • Vue.config.productionTip?=?false?不起作用的問(wèn)題及解決

    Vue.config.productionTip?=?false?不起作用的問(wèn)題及解決

    這篇文章主要介紹了Vue.config.productionTip?=?false為什么不起作用,本文給大家分析問(wèn)題原因解析及解決方案,需要的朋友可以參考下
    2022-11-11

最新評(píng)論

天台县| 龙口市| 大田县| 清苑县| 读书| 曲周县| 墨脱县| 定西市| 东宁县| 磐石市| 哈密市| 九龙县| 盘山县| 玉龙| 曲周县| 射阳县| 德令哈市| 石景山区| 牙克石市| 普定县| 吉木乃县| 长沙市| 灯塔市| 甘孜| 饶河县| 获嘉县| 云阳县| 崇仁县| 罗平县| 祥云县| 正宁县| 惠东县| 胶州市| 武穴市| 闽侯县| 毕节市| 明水县| 壶关县| 宜兰县| 嵊州市| 敖汉旗|