之前在后端搞过openoffice pdfjs显示office文档
时隔半年 今天在论坛上搜了一下 找到更好的pdfjs用法 但都是webpack环境 没有纯js环境
本文内容来自如下链接
- pdfjs canvas用法 https://gitee.com/mousetrip/mypdf
- pdfjs svg用法 https://blog.csdn.net/weixin_42298182/article/details/88893575
本文实例 https://gitee.com/tothis/vue-record/blob/master/client/src/views/pdfjs.vue
环境vue-cli 4.2.0
依赖 npm install pdfjs-dist 或 yarn add pdfjs-dist
<template>
<div class="container">
<div class="view" id="canvas-wrap"></div>
<div class="toolbar">
<el-button @click="onDownload" size="mini" type="primary">
下载
</el-button>
<el-button @click="onPrint" size="mini" type="primary">
打印
</el-button>
</div>
<!-- 打印使用 -->
<iframe class="print" name="printContainer"></iframe>
</div>
</template>
<script>
import { Loading, Message } from 'element-ui'
import { pdf as pdfApi } from '@/service/api'
import { fileDownload } from '@/util/file-util'
import PDFJS from 'pdfjs-dist'
export default {
name: 'pdfjs',
data() {
return {
pdfContent: null,
pdfPage: 0,
pdfScale: 1.5,
pdfName: 'test'
}
}, computed: { // computed监控自定义变量 该变量不在data中声明 直接在computed中定义
// 打印使用
printWindow() {
return window.frames['printContainer']
},
printBody() {
return this.printWindow.document.body
}
},
mounted() {
// 加载pdf文件
const loading = Loading.service({
target: 'body',
text: '加载pdf中...'
})
this.fetchPDFData()
.then(pdf => {
loading.close()
if (pdf) {
this.pdfContent = pdf
this.pdfPage = pdf.numPages
// 执行完 pdf => canvas 任务后 执行 canvas => image 任务
Promise.all(this.renderCanvas()).then(() => {
this.canvas2img()
})
} else {
Message.error({
message: '获取pdf失败'
})
}
})
.catch(error => {
loading.close()
console.error(error)
if (error)
Message.error({
message: error.toString()
})
})
},
methods: {
// 拉取pdf数据
async fetchPDFData() {
return pdfApi()
.then(async res => {
const { ret, data } = res
if (ret === 0) {
const { data: binaryData } = data
const loadingTask = PDFJS.getDocument({ data: binaryData })
return await loadingTask.promise
} else {
return Promise.resolve()
}
})
.catch(error => {
return Promise.reject(error)
})
},
// pdf => canvas
renderCanvas() {
const renderTasks = []
for (let i = 1; i <= this.pdfPage; i++) {
renderTasks.push(this.appendPage(i))
}
return renderTasks
},
// canvas => image
canvas2img() {
for (let i = 1; i <= this.pdfPage; i++) {
const target = document.getElementById('canvas_' + i)
const img = new Image()
img.src = target.toDataURL()
this.printBody.appendChild(img)
}
},
// 创建canvas容器 并将1页pdf渲染上去
appendPage(pageIndex) {
return this.pdfContent.getPage(pageIndex).then(page => {
/* canvas实现方式 */
// const viewport = page.getViewport(this.pdfScale)
// // 在页面中创建canvas
// const canvas = document.createElement('canvas')
// canvas.id = 'canvas_' + pageIndex
// document.getElementById('canvas-wrap').append(canvas)
// const context = canvas.getContext('2d')
// canvas.height = viewport.height
// canvas.width = viewport.width
// const renderContext = {
// canvasContext: context,
// viewport: viewport
// }
// return page.render(renderContext)
/* svg实现方式 */
let viewport = page.getViewport(this.pdfScale)
let container = document.createElement('div')
container.id = 'canvas_' + pageIndex
container.className = 'pageContainer'
container.style.width = viewport.width + 'px'
container.style.height = viewport.height + 'px'
document.getElementById('canvas-wrap').appendChild(container)
return page.getOperatorList().then(function(opList) {
let svgGfx = new PDFJS.SVGGraphics(page.commonObjs, page.objs)
return svgGfx.getSVG(opList, viewport).then(function(svg) {
container.appendChild(svg)
})
})
})
},
// 下载
onDownload() {
this.pdfContent.getData().then(data => {
const blob = new Blob([data], { type: 'application/pdf' })
fileDownload(blob, `${this.pdfName}.pdf`)
})
},
// 打印
onPrint() {
this.printWindow.print()
}
}
}
</script>
<style lang="stylus" scoped>
.container
position relative
width 100%
height 100%
.view
width 100%
padding-top 44px
text-align center
.toolbar
position fixed
top 16%
.print
display none
</style>