vue pdfjs canvas实现和svg实现

之前在后端搞过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>
原创文章 157 获赞 113 访问量 7万+

猜你喜欢

转载自blog.csdn.net/setlilei/article/details/104858550
今日推荐