当前位置:   article > 正文

Vue3实现pdf本地预览功能_vue3 根据pdf的url展示pdf

vue3 根据pdf的url展示pdf
一、先直接看看效果吧

放大后

缩小后

也可以分页显示

 二、选用vue-pdf-embed和vue3-pdfjs的原因
 

   选用这两个的插件是因为如果实现pdf预览其实使用iframe标签就可以的,但是使用iframe标签实现的比较臭,vue-pdf-embed是能够自定义样式的,更加灵活,我也是第一次尝试这个,也遇到了一些坑,后面会跟大家分享,反正按照这个来就能实现,源码我也放后面了。

三、注意点及踩坑
 

1、我这里项目搭建是用的Vite也不知道使用vue cli会不会有什么问题

2、vue-pdf-embed我开始是pnpm i vue-pdf-embed  安装了最新的,后面会发现pdf预览不出来,找了原因是版本的问题,我就pnpm i vue-pdf-embed@1.2.1 切换到1.2.1版本就好了

3、vue3-pdfjs在这是用来做监听pdf页数的当然还有别的用处。

4、当预览成果后会发现文字并未出来,f12会报这个

warning: error during font loading: the cmap "baseurl" parameter must be specified, ensure that the "cmapurl" and "cmappacked" api parameters are provided.

原因就是缺少中文包,加上下面这段就行了,这段代码在源码里面

5、还有个问题是scale缩放开始无效,原因大概是因为在使用 vue-pdf-embed 组件的 scale 参数时发现无法实现动态更改,且 width 参数无法设置成百分比的形式,所以采用修改父容器的方案实现。

四、直接上源码了

//父组件

  1. <template>
  2. <div class="main">
  3. <div class="home-box">
  4. <pdfView :pdfUrl="jsPdf"/>
  5. </div>
  6. </div>
  7. </template>
  8. <script lang="ts" setup>
  9. import { ref } from 'vue'
  10. import pdfView from '@/components/pdfView/index.vue';
  11. import jsPdf from './jsPdf.pdf';
  12. </script>
  13. <style lang="scss" scoped>
  14. .main {
  15. width: 100vw;
  16. height: 100vh;
  17. display: flex;
  18. align-items: center;
  19. justify-content: center;
  20. .home-box{
  21. width: 80%;
  22. }
  23. }
  24. </style>

子组件
 

  1. <template>
  2. <div class="pdf-preview">
  3. <div
  4. class="pdf-wrap"
  5. :style="{ transform: `translate(-50%,-50%) scale(${scaleData})` }"
  6. >
  7. <vue-pdf-embed
  8. :source="state.source"
  9. :style="state.scale"
  10. class="vue-pdf-embed"
  11. :page="state.pageNum"
  12. />
  13. </div>
  14. <div class="page-tool">
  15. <div class="page-tool-item" @click="lastPage">上一页</div>
  16. <div class="page-tool-item" @click="nextPage">下一页</div>
  17. <div class="page-tool-item">{{ state.pageNum }}/{{ state.numPages }}</div>
  18. <div class="page-tool-item" @click="zoomIn">放大</div>
  19. <div class="page-tool-item" @click="zoomOut">缩小</div>
  20. <div class="page-tool-item" @click="pageRest">重置缩放</div>
  21. </div>
  22. </div>
  23. </template>
  24. <script setup lang="ts">
  25. import { reactive, onMounted, computed, ref } from 'vue'
  26. import VuePdfEmbed from 'vue-pdf-embed'
  27. import { createLoadingTask } from 'vue3-pdfjs'
  28. const props = defineProps({
  29. pdfUrl: {
  30. type: String,
  31. required: true
  32. }
  33. })
  34. const state = reactive({
  35. source: {
  36. url: props.pdfUrl,
  37. cMapUrl: 'https://cdn.jsdelivr.net/npm/pdfjs-dist@2.9.359/cmaps/',
  38. cMapPacked: true
  39. }, //预览pdf文件地址
  40. pageNum: 1, //当前页面
  41. scale: 1, // 缩放比例
  42. numPages: 0 // 总页数
  43. })
  44. const scaleData = ref(1.0)
  45. const pageHeight = ref('100%')
  46. //上一页
  47. function lastPage() {
  48. if (state.pageNum > 1) {
  49. state.pageNum -= 1
  50. }
  51. }
  52. //下一页
  53. function nextPage() {
  54. if (state.pageNum < state.numPages) {
  55. state.pageNum += 1
  56. }
  57. }
  58. // 放大
  59. function zoomIn() {
  60. scaleData.value += 0.1
  61. pageHeight.value = parseInt(pageHeight.value) - 5.0 + '%'
  62. }
  63. // 缩小
  64. function zoomOut() {
  65. scaleData.value -= 0.1
  66. pageHeight.value = parseInt(pageHeight.value) + 5.0 + '%'
  67. }
  68. // 页面 放大/缩小 还原默认值
  69. function pageRest() {
  70. scaleData.value = 1.0
  71. pageHeight.value = '100%'
  72. }
  73. onMounted(() => {
  74. // debugger
  75. // console.log(props.pdfUrl)
  76. // debugger
  77. //获取pdf总页数
  78. const loadingTask = createLoadingTask(state.source)
  79. loadingTask.promise.then((pdf: { numPages: number }) => {
  80. // debugger
  81. state.numPages = pdf.numPages
  82. // debugger
  83. })
  84. })
  85. </script>
  86. <style lang="scss" scoped>
  87. .pdf-preview {
  88. position: relative;
  89. height: 100vh;
  90. padding: 20px 0;
  91. box-sizing: border-box;
  92. background-color: e9e9e9;
  93. .pdf-wrap {
  94. position: absolute;
  95. width: 100%;
  96. top: 50%;
  97. left: 50%;
  98. height: 100%;
  99. overflow-y: auto;
  100. .vue-pdf-embed {
  101. height: 100%;
  102. text-align: center;
  103. width: 80%;
  104. border: 1px solid #e5e5e5;
  105. margin: 0 auto;
  106. box-sizing: border-box;
  107. }
  108. }
  109. .page-tool {
  110. position: absolute;
  111. bottom: 35px;
  112. padding-left: 15px;
  113. padding-right: 15px;
  114. display: flex;
  115. align-items: center;
  116. background: rgb(66, 66, 66);
  117. color: white;
  118. border-radius: 19px;
  119. z-index: 100;
  120. cursor: pointer;
  121. margin-left: 50%;
  122. transform: translateX(-50%);
  123. .page-tool-item {
  124. padding: 8px 15px;
  125. padding-left: 10px;
  126. cursor: pointer;
  127. }
  128. }
  129. }
  130. </style>

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/酷酷是懒虫/article/detail/880380
推荐阅读
相关标签
  

闽ICP备14008679号