当前位置:   article > 正文

vue3+ts+pdfjs-dist查看pdf

vue3+ts+pdfjs-dist查看pdf

"pdfjs-dist": "^4.1.392",

"lodash-es": "^4.17.21",

"vite-plugin-top-level-await": "^1.4.1",

"vue": "^3.4.15",

  1. <template>
  2. <div class="pdf-container">
  3. <canvas :id="`pdf-canvas`" />
  4. </div>
  5. <div class="page-tool">
  6. <div class="page-tool-item" @click="lastPage">上一页</div>
  7. <div class="page-tool-item" @click="nextPage">下一页</div>
  8. <div class="page-tool-item">{{state.pageNum}}/{{state.numPages}}</div>
  9. <div class="page-tool-item" @click="pageZoomOut">放大</div>
  10. <div class="page-tool-item" @click="pageZoomIn">缩小</div>
  11. </div>
  12. </template>
  13. <script lang="ts" setup>
  14. import * as PDFJS from 'pdfjs-dist'
  15. import * as PdfWorker from 'pdfjs-dist/build/pdf.worker.mjs'
  16. import { nextTick, ref, Ref, watch, reactive, computed } from 'vue'
  17. import { isEmpty, debounce } from 'lodash-es'
  18. (window as any).PdfWorker = PdfWorker
  19. const props : any = defineProps({
  20. pdf: {
  21. required: true
  22. }
  23. })
  24. const state = reactive({
  25. source: "", //预览pdf文件地址
  26. pageNum: 1, //当前页面
  27. scale: 1, // 缩放比例
  28. numPages: 0, // 总页数
  29. showpdf: true,
  30. });
  31. const scaleFun = computed(() => 'transform:scale(${state.scale})')
  32. let pdfDoc : any = null
  33. const pdfPages : Ref = ref(0)
  34. const pdfScale : Ref = ref(1.3)
  35. const loadFile = async (url : any) => {
  36. // 设定pdfjs的 workerSrc 参数
  37. // PDFJS.GlobalWorkerOptions.workerSrc = PdfWorker
  38. const loadingTask = PDFJS.getDocument(url)
  39. loadingTask.promise.then(async (pdf : any) => {
  40. pdfDoc = pdf // 保存加载的pdf文件流
  41. state.numPages = pdfPages.value = pdfDoc.numPages // 获取pdf文件的总页数
  42. await nextTick(() => {
  43. renderPage(1) // 将pdf文件内容渲染到canvas
  44. })
  45. }).catch((error : any) => {
  46. //可以用自己组件库弹出提示框
  47. console.log(error)
  48. })
  49. }
  50. const renderPage = (num : any) => {
  51. pdfDoc.getPage(num).then((page : any) => {
  52. page.cleanup()
  53. const canvas : any = document.getElementById(`pdf-canvas`)
  54. if (canvas) {
  55. const ctx = canvas.getContext('2d')
  56. const dpr = window.devicePixelRatio || 1
  57. const bsr = ctx.webkitBackingStorePixelRatio ||
  58. ctx.mozBackingStorePixelRatio ||
  59. ctx.msBackingStorePixelRatio ||
  60. ctx.oBackingStorePixelRatio ||
  61. ctx.backingStorePixelRatio ||
  62. 1
  63. const ratio = dpr / bsr
  64. const viewport = page.getViewport({ scale: pdfScale.value })
  65. canvas.width = viewport.width * ratio
  66. canvas.height = viewport.height * ratio
  67. canvas.style.width = viewport.width + 'px'
  68. canvas.style.height = viewport.height + 'px'
  69. ctx.setTransform(ratio, 0, 0, ratio, 0, 0)
  70. const renderContext = {
  71. canvasContext: ctx,
  72. viewport: viewport
  73. }
  74. page.render(renderContext)
  75. state.pageNum = num;
  76. // if (num < pdfPages.value) {
  77. // renderPage(num + 1)
  78. // }
  79. }
  80. })
  81. }
  82. function lastPage() {
  83. if (state.pageNum > 1) {
  84. renderPage(state.pageNum - 1);
  85. }
  86. }
  87. function nextPage() {
  88. if (state.pageNum < state.numPages) {
  89. renderPage(state.pageNum + 1);
  90. }
  91. }
  92. function pageZoomOut() {
  93. if (pdfScale.value < 5) {
  94. pdfScale.value += 0.1;
  95. renderPage(state.pageNum);
  96. }
  97. }
  98. function pageZoomIn() {
  99. if (pdfScale.value > 0.5) {
  100. pdfScale.value -= 0.1;
  101. renderPage(state.pageNum);
  102. }
  103. }
  104. const debouncedLoadFile = debounce((pdf : any) => loadFile(pdf), 1000)
  105. watch(() => props.pdf, (newValue : any) => {
  106. !isEmpty(newValue) && debouncedLoadFile(newValue)
  107. }, {
  108. immediate: true
  109. })
  110. </script>
  111. <style scoped>
  112. .page-tool {
  113. position: absolute;
  114. bottom: 35px;
  115. padding-left: 15px;
  116. padding-right: 15px;
  117. display: flex;
  118. align-items: center;
  119. background: rgb(66, 66, 66);
  120. color: white;
  121. border-radius: 19px;
  122. z-index: 100;
  123. cursor: pointer;
  124. margin-left: 50%;
  125. transform: translateX(-50%);
  126. }
  127. .page-tool-item {
  128. padding: 8px 15px;
  129. padding-left: 10px;
  130. cursor: pointer;
  131. }
  132. .pdf-container {
  133. width: 1000px;
  134. height: 600px;
  135. resize: both;
  136. overflow: auto;
  137. /* 启用滚动条 */
  138. }
  139. canvas {
  140. width: 100%;
  141. pointer-events: none;
  142. max-height: 100vh;
  143. /* 设置最大高度为视口高度 */
  144. }
  145. </style>

效果:

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