国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

Vue3實現(xiàn)PDF文件預(yù)覽 (低版本瀏覽器兼容)

這篇具有很好參考價值的文章主要介紹了Vue3實現(xiàn)PDF文件預(yù)覽 (低版本瀏覽器兼容)。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

前言:
????????最近和小伙伴們一起合作完成一個企業(yè)級知識庫項目,其中一個功能就是后端把所有格式的文件轉(zhuǎn)換為PDF,前端實現(xiàn)渲染PDF文件從而實現(xiàn)預(yù)覽,干了整整一周(考慮到低版本瀏覽器的兼容),試用了幾種方案(iframe預(yù)覽已被廢棄,不適用本項目,想了解的同學(xué)自行搜索),終于實現(xiàn)了這個功能。

方案:Vue3+pdfjs-dist+canvas?

1.pdfjs-dist展示PDF文件的原理解釋

pdfjs-dist展示pdf文檔的原理,實際上是將pdf中的內(nèi)容渲染到解析,然后渲染到?canvas?中進(jìn)行展示,因此我們使用pdfjs渲染出來的pdf文件,實際上是一張張canvas圖片。

2.安裝pdfjs-dist

pdfjs-dist下載官網(wǎng)

Vue3實現(xiàn)PDF文件預(yù)覽 (低版本瀏覽器兼容),JavaScript,vue,pdf

建議安裝:?"pdfjs-dist": "^2.12.313"

npm i pdfjs-dist@2.12.313

打開VScode,使用ctl+`打開控制臺,輸入:npm i pdfjs-dist 安裝pdfjs-dist 切記要指定版本

3.?搭建基礎(chǔ)的頁面代碼

話不多說,上代碼:

<template>
  <div class="pdf-preview-box">
    <!-- <div class="pdf_down">
          <div class="pdf_set_left" @click="scaleD()">放大</div>
          <div class="pdf_set_middle" @click="scaleX()">縮小</div>
          <div class="pdf-pre" @click="prePage">上一頁</div>
          <div class="pdf-next" @click="nextPage">下一頁</div>
      </div> -->
    <canvas class="pdf-viewer"
        v-for="i in pdfParams.pdfPageTotal"
        :key="i"
        :id="'pdf-render' + i">
    </canvas>
  </div>
</template>
4.使用Vue3語法實現(xiàn)PDF文件的多頁展示
4.1引入ref
import { onMounted, ref, reactive } from 'vue'
4.2將會用到的數(shù)據(jù)聲明為響應(yīng)式
const props = defineProps({
  pdfUrl: {
    type: String,
    default: '/testPdf.pdf',
    required: true,
  },
  containerWidth: {
    type: Number,
    default: 700,
    required: true,
  },
});

const pdfParams = reactive({
  currentPageNumber: 1,
  pdfScale: 1.0,
  pdfPageTotal: 0, // 總頁數(shù)
});

// 不要定義為ref或reactive格式,就定義為普通的變量
let pdfDoc = null;
4.3定義獲取pdf文檔流與pdf文件的頁數(shù)的方法:loadFile
// 這里必須使用異步去引用pdf文件,直接去import會報錯,也不知道為什么
const loadFile = async () => {
  let pdfjs = await import('pdfjs-dist/build/pdf')
  let pdfjsWorker = await import('pdfjs-dist/build/pdf.worker.entry')
  pdfjs.GlobalWorkerOptions.workerSrc = pdfjsWorker
  // 此文件位于public/testPdf.pdf
  pdfjs.getDocument(props.pdfUrl).promise.then(async doc => {
    pdfDoc = doc
    pdfParams.pdfPageTotal = doc.numPages
    // // 僅加載第一頁  注釋  取消頁碼切換
    // await getPdfPage(pdfParams.currentPageNumber)
    // 加載pdf所有頁
    for (let pageNum = 1; pageNum <= doc.numPages; pageNum++) {
      await getPdfPage(pageNum)
    }
  })
}
4.4定義渲染pdf文件的方法:renderPage
// 加載pdf的某一頁
const getPdfPage = (number) => {
  return new Promise((resolve, reject) => {
    pdfDoc.getPage(number).then(page => {
      const canvas = document.getElementById(`pdf-render${number}`)
      const context = canvas.getContext('2d')
      const scale = 1; // 縮放比例
      const dpr = window.devicePixelRatio || 1;
      const bsr =
        context.webkitBackingStorePixelRatio ||
        context.mozBackingStorePixelRatio ||
        context.msBackingStorePixelRatio ||
        context.oBackingStorePixelRatio ||
        context.backingStorePixelRatio ||
        1;
      const ratio = dpr / bsr;
      const viewport = page.getViewport({ scale: pdfParams.pdfScale }); // 獲取窗口大小
      const canvasWidth = Math.floor(viewport.width * ratio);
      const canvasHeight = Math.floor(viewport.height * ratio);
      // const canvasWidth = props.containerWidth;
      // const canvasHeight = Math.floor(viewport.height * ratio) * (props.containerWidth / Math.floor(viewport.width * ratio));
      canvas.width = canvasWidth;
      canvas.height = canvasHeight;
      // canvas.style.width = Math.floor(viewport.width) + 'px'
      // canvas.style.height = Math.floor(viewport.height) + 'px'
      canvas.style.width = Math.floor(props.containerWidth) + 'px'
      canvas.style.height = Math.floor(viewport.height * props.containerWidth / viewport.width) + 'px'

      let renderContext = {
        canvasContext: context,
        viewport: viewport,
        // 這里transform的六個參數(shù),使用的是transform中的Matrix(矩陣)
        // transform: [1, 0, 0, -1, 0, viewport.height]
        transform: [ratio, 0, 0, ratio, 0, 0]
      }

      // 進(jìn)行渲染
      page.render(renderContext).promise.then(() => {
        resolve();
      }).catch(error => {
        reject(error);
      });
    }).catch(error => {
      reject(error);
    });
  });
}
4.5在onMounted鉤子中調(diào)用loadFile方法
//調(diào)用loadFile方法
onMounted(async () => {
  await loadFile()
})
5完整代碼實現(xiàn):
<!--
 * @Author: 碼農(nóng)鍵盤上的夢
 * @Description:  pdf預(yù)覽插件    "pdfjs-dist": "^2.12.313",  指定版本 配合 canvas 實現(xiàn)一個組件
 * 
-->
<template>
  <div class="pdf-preview-box">
    <!-- <div class="pdf_down">
          <div class="pdf_set_left" @click="scaleD()">?</div>
          <div class="pdf_set_middle" @click="scaleX()">?</div>
          <div class="pdf-pre" @click="prePage">上一頁</div>
          <div class="pdf-next" @click="nextPage">下一頁</div>
      </div> -->
    <canvas class="pdf-viewer" v-for="i in pdfParams.pdfPageTotal" :key="i" :id="'pdf-render' + i"></canvas>
  </div>
</template>

<script setup>
import { onMounted, ref, reactive } from 'vue'

const props = defineProps({
  pdfUrl: {
    type: String,
    default: '/testPdf.pdf',
    required: true,
  },
  containerWidth: {
    type: Number,
    default: 700,
    required: true,
  },
});

const pdfParams = reactive({
  currentPageNumber: 1,
  pdfScale: 1.0,
  pdfPageTotal: 0, // 總頁數(shù)
});

// 不要定義為ref或reactive格式,就定義為普通的變量
let pdfDoc = null;

onMounted(async () => {
  await loadFile()
})

// 這里必須使用異步去引用pdf文件,直接去import會報錯,也不知道為什么
const loadFile = async () => {
  let pdfjs = await import('pdfjs-dist/build/pdf')
  let pdfjsWorker = await import('pdfjs-dist/build/pdf.worker.entry')
  pdfjs.GlobalWorkerOptions.workerSrc = pdfjsWorker
  // 此文件位于public/testPdf.pdf
  pdfjs.getDocument(props.pdfUrl).promise.then(async doc => {
    pdfDoc = doc
    pdfParams.pdfPageTotal = doc.numPages
    // // 僅加載第一頁  注釋  取消頁碼切換
    // await getPdfPage(pdfParams.currentPageNumber)
    // 加載pdf所有頁
    for (let pageNum = 1; pageNum <= doc.numPages; pageNum++) {
      await getPdfPage(pageNum)
    }
  })
}

// 加載pdf的某一頁
const getPdfPage = (number) => {
  return new Promise((resolve, reject) => {
    pdfDoc.getPage(number).then(page => {
      const canvas = document.getElementById(`pdf-render${number}`)
      const context = canvas.getContext('2d')
      const scale = 1; // 縮放比例
      const dpr = window.devicePixelRatio || 1;
      const bsr =
        context.webkitBackingStorePixelRatio ||
        context.mozBackingStorePixelRatio ||
        context.msBackingStorePixelRatio ||
        context.oBackingStorePixelRatio ||
        context.backingStorePixelRatio ||
        1;
      const ratio = dpr / bsr;
      const viewport = page.getViewport({ scale: pdfParams.pdfScale }); // 獲取窗口大小
      const canvasWidth = Math.floor(viewport.width * ratio);
      const canvasHeight = Math.floor(viewport.height * ratio);
      // const canvasWidth = props.containerWidth;
      // const canvasHeight = Math.floor(viewport.height * ratio) * (props.containerWidth / Math.floor(viewport.width * ratio));
      canvas.width = canvasWidth;
      canvas.height = canvasHeight;
      // canvas.style.width = Math.floor(viewport.width) + 'px'
      // canvas.style.height = Math.floor(viewport.height) + 'px'
      canvas.style.width = Math.floor(props.containerWidth) + 'px'
      canvas.style.height = Math.floor(viewport.height * props.containerWidth / viewport.width) + 'px'

      let renderContext = {
        canvasContext: context,
        viewport: viewport,
        // 這里transform的六個參數(shù),使用的是transform中的Matrix(矩陣)
        // transform: [1, 0, 0, -1, 0, viewport.height]
        transform: [ratio, 0, 0, ratio, 0, 0]
      }

      // 進(jìn)行渲染
      page.render(renderContext).promise.then(() => {
        resolve();
      }).catch(error => {
        reject(error);
      });
    }).catch(error => {
      reject(error);
    });
  });
}


// // 下一頁功能
// const prevPage = () => {
//     if (pdfParams.currentPageNumber > 1) {
//         pdfParams.currentPageNumber -= 1
//     } else {
//         pdfParams.currentPageNumber = 1
//     }
//     getPdfPage(pdfParams.currentPageNumber)
// }
// // 上一頁功能
// const nextPage = () => {
//     if (pdfParams.currentPageNumber < pdfParams.pdfPageTotal) {
//         pdfParams.currentPageNumber += 1
//     } else {
//         pdfParams.currentPageNumber = pdfParams.pdfPageTotal
//     }
//     getPdfPage(pdfParams.currentPageNumber)
// }

// //放大
// const scaleD = async () => {
//     let max = 0;
//     if (window.screen.width > 1440) {
//         max = 1.4;
//     } else {
//         max = 1.2;
//     }
//     if (pdfParams.pdfScale >= max) {
//         return;
//     }
//     pdfParams.pdfScale = pdfParams.pdfScale + 0.1;
//     await loadFile();
// }
// //縮小
// const scaleX = async () => {
//     let min = 1.0;
//     if (pdfParams.pdfScale <= min) {
//         return;
//     }
//     pdfParams.pdfScale = pdfParams.pdfScale - 0.1;
//     await loadFile();
// }

</script>

<style scoped lang="scss" >
.pdf-preview-box {
  width: 100%;
  position: relative;

  // .pdf_down {
  //     position: fixed;
  //     display: flex;
  //     z-index: 20;
  //     right: 26px;
  //     bottom: 7%;
  //     cursor: pointer;

  //     .pdf_set_left {
  //         width: 30px;
  //         height: 40px;
  //         color: #408fff;
  //         font-size: 15px;
  //         padding-top: 25px;
  //         text-align: center;
  //         margin-right: 5px;
  //         cursor: pointer;
  //     }

  //     .pdf_set_middle {
  //         width: 30px;
  //         height: 40px;
  //         color: #408fff;
  //         font-size: 15px;
  //         padding-top: 25px;
  //         text-align: center;
  //         margin-right: 5px;
  //         cursor: pointer;
  //     }

  //     .pdf-pre {
  //         position: fixed;
  //         display: flex;
  //         z-index: 20;
  //         right: 160px;
  //         bottom: 9%;
  //         cursor: pointer;
  //     }

  //     .pdf-next {
  //         position: fixed;
  //         display: flex;
  //         z-index: 20;
  //         right: 100px;
  //         bottom: 9%;
  //     }
  // }
}
</style>

以上就是實現(xiàn)PDF文件多頁展示的內(nèi)容了,如果其他的小伙伴有其他的方法或者思考請批評指正?文章來源地址http://www.zghlxwxcb.cn/news/detail-806839.html

到了這里,關(guān)于Vue3實現(xiàn)PDF文件預(yù)覽 (低版本瀏覽器兼容)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進(jìn)行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • Vue3 實現(xiàn)文件預(yù)覽 Word Excel pdf 圖片 視頻等格式 大全!!!!

    Vue3 實現(xiàn)文件預(yù)覽 Word Excel pdf 圖片 視頻等格式 大全!!!!

    先上效果圖 ? ?插件安裝 先說 word 文件是docx-preview插件 ? ? ? ? ? excel文件是用?xlsx 插件? ?? 介紹后端返回的數(shù)據(jù) 因為在攔截器處 做了對數(shù)據(jù)的處理 最后你調(diào)接口拿到的數(shù)據(jù)是 一個對象 里面包含: url :? blob對象轉(zhuǎn)換的用于訪問 Blob 數(shù)據(jù)的臨時鏈接。這個鏈接可以被用于

    2024年02月07日
    瀏覽(109)
  • 微信公眾號 - 實現(xiàn) H5 網(wǎng)頁在微信內(nèi)置瀏覽器中下載文件,可預(yù)覽和下載 office 文件(doc / xls / ppt / pdf 等)適用于任何前端技術(shù)棧網(wǎng)站,兼容安卓和蘋果系統(tǒng)!

    微信公眾號 - 實現(xiàn) H5 網(wǎng)頁在微信內(nèi)置瀏覽器中下載文件,可預(yù)覽和下載 office 文件(doc / xls / ppt / pdf 等)適用于任何前端技術(shù)棧網(wǎng)站,兼容安卓和蘋果系統(tǒng)!

    網(wǎng)上的教程都是讓你寫頁面 “引導(dǎo)” 右上角三個點里,讓用戶自己去瀏覽器打開,其實這樣用戶體驗并不好。 本文實現(xiàn)了 最新微信公眾號 H5 網(wǎng)頁(微信內(nèi)置瀏覽器中),預(yù)覽下載 office 文件,安卓和蘋果全都支持! 您可以直接復(fù)制代碼,移植到自己項目中去, 任何前端項

    2024年01月21日
    瀏覽(37)
  • 瀏覽器預(yù)覽pdf

    瀏覽器預(yù)覽pdf

    最近開發(fā)手機(jī)端的時候遇到安卓瀏覽器用a /標(biāo)簽href為pdf鏈接的時候 它不給我去預(yù)覽pdf而是要我下載,這可離了大普. 我想到的最快的解決方案就是把pdf轉(zhuǎn)換成html文件展示 PDF轉(zhuǎn)換為HTML - 迅捷,在線,免費(fèi) - PDF24 Tools 將pdf文件轉(zhuǎn)成html文件放在靜態(tài)目錄下 在用a標(biāo)簽跳轉(zhuǎn)就行

    2024年01月24日
    瀏覽(16)
  • 前端vue3實現(xiàn)本地及在線文件預(yù)覽(含pdf/txt/mp3/mp4/docx/xlsx/pptx)

    前端vue3實現(xiàn)本地及在線文件預(yù)覽(含pdf/txt/mp3/mp4/docx/xlsx/pptx)

    (一)微軟office免費(fèi)預(yù)覽( 推薦 ) 支持doc/docx/xls/xlsx/ppt/pptx等多種office文件格式的免費(fèi)預(yù)覽 (二)XDOC文檔預(yù)覽云服務(wù) ?移動端和PC端無插件預(yù)覽PDF、OFD、Word、WPS等多種格式文檔 本地或內(nèi)網(wǎng)預(yù)覽需要借助插件實現(xiàn),pdf、mp3、mp4等主要靠原生標(biāo)簽或瀏覽器自帶功能,盡量減少

    2024年02月05日
    瀏覽(63)
  • vue3移動端實現(xiàn)pdf預(yù)覽

    vue3移動端實現(xiàn)pdf預(yù)覽

    使用的插件有: html部分: js部分: 我一開始使用的時第一種方法,然后測試之后發(fā)現(xiàn) 蘋果手機(jī)會顯示pdf加載出錯了 ,安卓手機(jī)可以正常顯示,于是換成了第二種方法。 html部分: js部分: 用了第二種插件后,蘋果手機(jī)還是加載不出來,后面查到因為pdfjs-dist有時候會出現(xiàn)部

    2024年02月02日
    瀏覽(29)
  • pdfjs解決ie瀏覽器預(yù)覽pdf問題

    pdfjs解決ie瀏覽器預(yù)覽pdf問題

    pdfjs是一個js庫,可以將pdf文件用canvas重新繪制,從而無需借助pdf讀取插件就可以直接預(yù)覽。 目前chrome內(nèi)核的瀏覽器已內(nèi)置pdf讀取插件,但ie瀏覽器還沒有。而我們最近在做的一個項目使用對象是醫(yī)院,使用的瀏覽器竟然還是ie。所以我們只能把項目用js重寫(當(dāng)然也可以用j

    2024年02月07日
    瀏覽(26)
  • java實現(xiàn)pdf文件添加水印,下載到瀏覽器

    java實現(xiàn)pdf文件添加水印,下載到瀏覽器

    添加itextpdf依賴 根據(jù)需求,不需要指定路徑可以刪除對應(yīng)的輸出流 效果如下:代碼中的相對路徑在src平級目錄下,test.pdf是PdfStamper里面fileOutputStream生成的,test1.pdf是fos生成的 瀏覽器下載的如下: 生成的pdf內(nèi)容如下(紅框里面是pdf原來的內(nèi)容,可以自己調(diào)整代碼中注釋掉的設(shè)

    2024年02月05日
    瀏覽(21)
  • 在uniapp Vue3版本中如何解決web/H5網(wǎng)頁瀏覽器跨域的問題

    在uniapp Vue3版本中如何解決web/H5網(wǎng)頁瀏覽器跨域的問題

    uniapp項目在瀏覽器運(yùn)行,有可能調(diào)用某些接口會出現(xiàn)跨域問題,報錯如下圖所示: 存在跨域問題的原因是因為瀏覽器的同源策略,也就是說前端無法直接發(fā)起跨域請求。同源策略是一個基礎(chǔ)的安全策略,但是這也會給uniapp/Vue開發(fā)者在部署時帶來一定的麻煩。一般來說,瀏覽

    2024年01月21日
    瀏覽(84)
  • web瀏覽器在線預(yù)覽Excel,PDF,world文檔解決方案

    web瀏覽器在線預(yù)覽Excel,PDF,world文檔解決方案

    眾所周知啊,在web瀏覽器中是無法直接預(yù)覽Excel、world文檔等文件的,PDF有的瀏覽器是打開預(yù)覽,有的瀏覽器是跳轉(zhuǎn)到下載頁,行為不一致也是讓開發(fā)者頭疼的事情。 今天給大家提供一個解決方案,實現(xiàn)office文件在線預(yù)覽的解決方案,這個在開發(fā)OA,推送通知觸達(dá)的應(yīng)用非常有

    2024年02月17日
    瀏覽(93)
  • vue3 實現(xiàn)預(yù)覽pdf的幾種方式(vue3-pdf, iframe流展示,vue-office/pdf)

    功能描述: 要實現(xiàn)菜單(二級)綁定文件,并進(jìn)行預(yù)覽(點擊菜單即觸發(fā)),支持文件上傳下載(綁定菜單),文件以byte[]形式保存到數(shù)據(jù)庫(至于為什么不用文件存儲系統(tǒng),因為這是領(lǐng)導(dǎo)定的 =,= 而且這個功能比較小,數(shù)據(jù)也不多,成本有限),同時,要解析pdf文件里的內(nèi)

    2024年02月16日
    瀏覽(19)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包