从服务器请求pdf文件转成canvas进行前端展示
最近做一个vue项目,需要将pdf文件在页面展示,由于踩了两个坑,所以记录一下,供大家参考。
开始我用的是vue-pdf插件,但是遇到一个问题,不显示pdf上面的印章???,所以自己下载pdf.js和pdf.worker.js,然后修改了一行代码,再进行压缩引入。下面是将这个功能封装的一个组件:
/**
* @param {string} fileUrl 文件地址
*/
<template>
<div ref="parent">
</div>
</template>
<script>
export default {
name: 'pdf',
props: ['fileUrl'],
watch: {
fileUrl (val) {
if (this.$refs.parent) {
this.$refs.parent.innerHTML = ''
}
if (val) {
this.getPdfFile(val)
}
}
},
data () {
return {
xhr: new XMLHttpRequest()
}
},
methods: {
getPdfFile (url) {
const _this = this
this.xhr.abort() // 请求中止
this.xhr.open('get', url, true)
this.xhr.responseType = 'arraybuffer'
this.xhr.onload = function () {
if (this.status === 200) {
let typedarray = new Uint8Array(this.response)
_this.renderFile(typedarray)
// 如果父组件要使用下载下来的文件,可以返回出去
_this.$emit('onLoad', typedarray)
}
}
this.xhr.send()
},
renderFile (typedarray) {
// eslint-disable-next-line
let _PDFJS = PDFJS
// 加载字体文件,避免字体丢失,我不加这两行不显示日期
_PDFJS.cMapUrl = 'https://cdn.jsdelivr.net/npm/pdfjs-dist@2.0.288/cmaps/'
_PDFJS.cMapPacked = true
_PDFJS.getDocument(typedarray).then(pdf => {
if (pdf) {
let pageNum = pdf.numPages
for (let i = 1; i <= pageNum; i++) {
let canvas = document.createElement('canvas')
if (this.$refs.parent) {
this.$refs.parent.appendChild(canvas)
}
let context = canvas.getContext('2d')
this.openPage(pdf, i, context)
}
}
})
},
openPage (pdfFile, pageNumber, context) {
let scale = 8 // 这个数字是调清晰度的
pdfFile.getPage(pageNumber).then(page => {
let viewport = page.getViewport(scale)
let canvas = context.canvas
canvas.width = viewport.width
canvas.height = viewport.height
canvas.style.width = '100%'
canvas.style.height = '100%'
let renderContext = {
canvasContext: context,
viewport: viewport
}
page.render(renderContext).then(() => {
// 渲染完成
this.$emit('onRender')
})
})
}
}
}
</script>
<style lang="scss scoped>
</style>
组件和pdf.js、pdf.worker.js文件上传到github上了,可以直接使用。
本文介绍如何在Vue项目中将PDF文件转换为Canvas进行前端展示,详细记录了遇到的问题以及解决方法,包括使用vue-pdf插件的问题和自定义实现的解决方案,提供了一个已封装的组件及GitHub源码链接。
2303

被折叠的 条评论
为什么被折叠?



