记录一次pdf预览开发

74 阅读2分钟

el-drawer实现,问题cavans宽度设置不正确

<template>
    <el-container>
        <el-header>
            <span>
                机构名称:</span>
            <span> <el-input ref="checkUname" :disabled="true" size="small" placeholder="请填写医院名称"
                    v-model="user.hospitalName" />
            </span>
            <el-select v-model="messageType" size="small" class="msun-menu_all_select" placeholder="请选择类型" filterable
                @change="messageChange">
                <el-option v-for="item in messageList" :key="item.id" :label="item.value" :value="item.id" />
            </el-select>
            <el-button type="warning" size="small" icon="el-icon-search" @click="getfindbypage">
                查询
            </el-button>
            <!-- <input type="file" @change="uploadPdf($event)" /> -->
        </el-header>
        <el-main>
            <watermark :option='option'>
                <div class="containerCSS">
                    <el-drawer title="我是标题" :visible.sync="drawer" :with-header="false" :size="drawerWidth"
                        direction="ltr">
                        <div class="containerCSS1">
                            <div class="containerCSS1head">
                                <el-button type="primary" size="small" @click="getfindbypage">
                                    上一页
                                </el-button>
                                {{ pdfpage }} / {{ pdfPages }}
                                <el-button type="primary" size="small" @click="getfindbypage">
                                    下一页
                                </el-button>

                            </div>
                            <div class="containerCSS1main">
                                <div v-for="page in pdfList" :key="page">
                                    <watermark :option='option1'>
                                        <canvas :id="'pdfCanvas' + page"></canvas>
                                    </watermark>

                                </div>
                            </div>
                        </div>
                    </el-drawer>
                    <el-table ref="selecttable" :data="tableData" border stripe height="100%"
                        @selection-change="selectTable" :row-key="getRowKeys">
                        <el-table-column type="selection" width="50" align="center" :reserve-selection="true" />
                        <el-table-column label="文件名称" align="center" fixed>
                            <template slot-scope="scope">
                                <el-link type="primary" @click="csclick(scope.row)">{{ scope.row.messageTitle
                                    }}</el-link>
                            </template>
                        </el-table-column>
                        <el-table-column label="创建时间" align="center">
                            <template slot-scope="scope">
                                {{ scope.row.hisCreateTime }}
                            </template>
                        </el-table-column>
                        <el-table-column label="创建人名称" align="center">
                            <template slot-scope="scope">
                                {{ scope.row.hisCreaterName }}
                            </template>
                        </el-table-column>
                        <el-table-column align="center" label="操作" width="200" fixed="right">
                            <template slot-scope="scope">
                                <el-tooltip content="编辑" placement="top">
                                    <el-button icon="el-icon-edit" type="primary" size="small" circle
                                        @click="handleEdit(scope.row)" />
                                </el-tooltip>
                                <el-tooltip content="作废" placement="top">
                                    <el-button icon="el-icon-delete" type="danger" size="small" circle
                                        @click="handleRemove(scope.row)" />
                                </el-tooltip>
                            </template>
                        </el-table-column>
                    </el-table>
                </div>
            </watermark>
        </el-main>
        <el-footer>
            <el-pagination :current-page="currentPage" :page-sizes="[5, 10, 15]" :page-size="pageSize"
                layout="total, sizes, prev, pager, next, jumper" :total="total" background
                @size-change="handleSizeChange" @current-change="currentPagechange" />
        </el-footer>
    </el-container>
</template>
<script>
import watermark from 'watermark-vue2/packages/index.js'
import { materialpdfAPI } from '@/api/materialpdf'
import PDFJS from "pdfjs-dist";

export default {
    components: {
        watermark,
    },
    data() {
        return {
            pdfPages: null,
            pdfpage: 1,
            pdfjsLib: '',
            pdfList: [],
            pdfName: '',
            pdfUrl: '',
            messageType: "1",
            messageList: [{ id: '1', value: '公告' }, { id: '2', value: '材料' }, { id: '3', value: '政策解读' }, { id: '4', value: '上报材料模板' }, { id: '5', value: '其他' }],
            drawerWidth: '40%',
            drawer: false,
            tableData: [],
            selectiontable: [],
            user: {},
            total: 0,
            currentPage: 1,
            pageSize: 10,
            option: {
                width: 260,
                height: 120,
                text: '主标题',
                subtext: '2024-03-11',
                rotate: -25,
                color: "rgba(0,0,0,0.3)",
                textStyle: {
                    font: '18px SimHei',
                },
                subtextStyle: {
                    font: '12px SimHei',
                }
            },
            option1: {
                width: 260,
                height: 120,
                text: '主标题',
                subtext: '2024-03-11',
                rotate: -25,
                color: "rgba(0,0,0,0.3)",
                textStyle: {
                    font: '18px SimHei',
                },
                subtextStyle: {
                    font: '12px SimHei',
                }
            }
        }
    },

    async created() {
        this.pdfjsLib = require('pdfjs-dist');
        this.pdfjsLib.GlobalWorkerOptions.workerSrc = require('pdfjs-dist/build/pdf.worker.entry');
        // 获取用户ID
        this.user = JSON.parse(sessionStorage.getItem('currentUser'))
        console.log(this.user);
        this.option.text = this.user.userName
        this.option.subtext = this.user.hospitalName + this.user.accountName
        await this.getfindbypage()
    },
    methods: {
        async messageChange() {
            await this.getfindbypage()
            this.currentPage = 1
            this.pageSize = 10
        },
        //删除emrrmessage
        async handleRemove(row) {
            await materialpdfAPI.emrrMessagedeleteById(row.messageId)
            await this.getfindbypage()
        },
        //获取pdf材料信息
        async getfindbypage() {
            try {
                const res = await materialpdfAPI.emrrMessagefindByPage({
                    "hospitalId": this.user.hospitalId,
                    "messageType": this.messageType,
                    "orgId": this.user.orgId,
                    "pageNum": this.currentPage,
                    "pageSize": this.pageSize,
                    "searchKeyWord": ""
                })
                this.tableData = res.list
                this.total = Number(res.total)
            } catch (e) {
                console.error(e);
            }
        },
        // 分页改变
        async currentPagechange(val) {
            this.currentPage = val
            await this.getfindbypage()
        },
        async handleSizeChange(val) {
            this.pageSize = val
            this.currentPage = 1
            await this.getfindbypage()
        },
        //测试
        async csclick(row) {
            this.drawer = true
            //读取文件
            try {
                const res = await materialpdfAPI.emrrMessagereadFile(row.messageAnnex)
                //简单预览功能
                this.pdfUrl = window.URL.createObjectURL(new Blob([res], { type: 'application/pdf' }));
                console.log('getpdf', res, this.pdfUrl);
                this.getPdfFile(this.pdfUrl)
                // window.open(this.pdfUrl);
                // const blob = new Blob([res]) // type这里表示xlsx类型
                // const downloadElement = document.createElement('a')
                // const href = window.URL.createObjectURL(blob) // 创建下载的链接
                // downloadElement.href = href
                // downloadElement.download = '医院指导话术.pdf' // 下载后文件名
                // document.body.appendChild(downloadElement)
                // downloadElement.click() // 点击下载
                // document.body.removeChild(downloadElement) // 下载完成移除元素
                // window.URL.revokeObjectURL(href) // 释放掉blob对象
                // this.$message.success('下载成功')
            } catch (e) {
                this.$message.error('下载失败', e)
            }
        },
        //每条数据的唯一识别值
        getRowKeys(row) {
            return row.userId // 每条数据的唯一识别值
        },
        //选中的数据
        selectTable(selection) {
            this.selectiontable = selection
            console.log('selectiontable', this.selectiontable);
        },
        // 上传pdf
        uploadPdf(event) {
            console.log('1', event)
            if (event.target.files[0].type != 'application/pdf') {
                return this.$message.warning('请选择上传pdf文件')
            }
            //iE9及以下版本IE浏览器暂不支持该功能,请升级IE浏览器或者用其他浏览器操作。
            let inputDOM = event.target
            let _this = this
            var reader = new FileReader()
            reader.readAsDataURL(event.target.files[0])//读取文件
            reader.onload = function (e) {
                _this.getPdfUrl(event.target.files[0])//将得到的blob传出读取
                inputDOM.value = null //将input置空 否则上传相同文件无反应 (不过置空后28行的打印 就看不到 event.target.files 文件数据(可以先注释此行看下数据--就是pdf文件)   )
            }
        },
        //通过读取pdf得到url
        getPdfUrl(file) {

            let url = URL.createObjectURL(file) //将blob文件转化成url
            this.pdfUrl = url  //赋值给url
            this.pdfName = file.name
            console.log('2', this.pdfName, this.pdfUrl);
            this.gotoPdf(this.pdfUrl)
        },
        // 打开pdf
        async gotoPdf(pdfUrl) {
            window.open(pdfUrl)
            // const res = await materialpdfAPI.emrrMessagesaveOrUpdate({
            //     "hospitalId": "10033001",
            //     "messageType": "5",
            //     "orgId": "10033",
            //     "pageNum": 1,
            //     "pageSize": 10,
            //     "searchKeyWord": "",
            //     "version": 0,
            //     "invalidFlag": "0",
            //     "messageAnnex": "/msun/programs/msun-emrr-app-grade/emrrFile/messageWord/20245028135042_www.alltoall.net_主页面_ZNRabxMtCF.pdf",
            //     "messageTitle": "1主页面_ZNRabxMtCF.pdf"
            // })
            // console.log('emrrMessagesaveOrUpdate', res);

        },
        // 删除pdf
        delPdf() {
            this.pdfName = ''
            this.pdfUrl = ''
        },
        async getPdfFile(file) {
            this.pdfList = []
            this.pdfList.push(file);
            this._loadFile(file);
            console.log(this.pdfList);
            return;

        },
        _loadFile(url) {
            this.pdfjsLib.getDocument(url).promise.then(pdf => {
                this.pdfDoc = pdf;
                const pdfPages = this.pdfDoc.numPages;
                this.pdfList = pdfPages;
                this.pdfPages = pdfPages;
                console.log(pdfPages);
                this.$nextTick(() => {
                    this._renderPage(1);
                });
            });
        },
        _renderPage(num) {
            this.pdfDoc.getPage(num).then(page => {
                let canvas = document.getElementById("pdfCanvas" + num);
                var vp = page.getViewport({ scale: 1 });
                let ctx = canvas.getContext("2d");
                let dpr = window.devicePixelRatio || 1;
                let bsr =
                    ctx.webkitBackingStorePixelRatio ||
                    ctx.mozBackingStorePixelRatio ||
                    ctx.msBackingStorePixelRatio ||
                    ctx.oBackingStorePixelRatio ||
                    ctx.backingStorePixelRatio ||
                    1;
                let ratio = dpr / bsr;
                let viewport = page.getViewport({
                    scale: window.innerWidth / vp.width
                });
                canvas.width = viewport.width * ratio;
                canvas.height = viewport.height * ratio;

                canvas.style.width = viewport.width + "px";

                canvas.style.height = viewport.height + "px";

                ctx.setTransform(ratio, 0, 0, ratio, 0, 0);
                let renderContext = {
                    canvasContext: ctx,
                    viewport: viewport
                };
                console.log(canvas, "------");
                if (canvas) {
                    page.render(renderContext);
                }
                if (this.pdfList > num) {
                    this._renderPage(num + 1);
                }
            });
        }
    },
}
</script>
<style lang="scss" scoped>
/* 设置容器的高度和宽度 */
.containerCSS {
    height: calc(100vh - 240px);
    width: calc(100vw - 300px);
}

.containerCSS1 {
    background-color: rgb(187, 181, 181);
    height: 100vh;
    width: 40vw;
    display: flex;
    flex-direction: column;

    .containerCSS1head {
        display: flex;
        align-items: center;
        justify-content: center;
        gap: 20px;
        height: 10%;
        width: 40vw;
        ;
        background-color: rgb(255, 255, 255);
        border-bottom: 1px solid rgb(242, 242, 242);
        position: sticky;
        /* 新属性sticky */
        top: 0;
        /* 距离页面顶部距离 */
        z-index: 10000;
    }

    .containerCSS1main {
        height: 90%;
        width: 100%;
        background-color: rgb(187, 181, 181);
    }
}

.el-container {
    height: 100%;
    width: 100%;
    background-color: rgb(255, 255, 255);

    .el-header {
        display: flex;
        align-items: center;
        justify-content: right;
        gap: 20px;
        border-bottom: 1px solid rgb(242, 242, 242);

    }

    .el-main {
        height: 100%;
        width: 100%;
        background-color: rgb(255, 255, 255);
    }

    .el-footer {
        display: flex;
        justify-content: flex-end;
        align-items: center;
    }
}
</style>