纯前度(vue)实现对pdf\mp4\png\jpg\jpegxls\doc\txt文件预览,无需要转化

发布于:2025-02-11 ⋅ 阅读:(104) ⋅ 点赞:(0)

我们知道要想在前端预览文件,可以通过浏览器自带的预览功能,我们只要window.open(ulr) 就可以实现对文件的预览,但是对于一些特殊的文件,目前很多浏览器的预览功能还是不支持的,今天我们就在纯前端来实现对这些文件的预览。

首先,我们需要使用到vue的两个组件:VueOfficeExcelVueOfficeDocx
下面直接看代码:

<template>
    <div class="container">
        <iframe v-if="currFileType==='pdf' || currFileType==='mp4'" class="file" :src="$utils.getFullFilePathHM(currentRow.attPath)" type="application/x-google-chrome-pdf" />
        <img v-else-if="['png','jpg','jpeg'].includes(currFileType)" class="file" :src="$utils.getFullFilePathHM(currentRow.attPath)" style="object-fit: contain;" alt="">
        <vue-office-docx v-else-if="currFileType==='docx'" :src="$utils.getFullFilePathHM(currentRow.attPath)" />
        <div v-else-if="currFileType==='txt'" ref="txt" class="txt" />
        <vue-office-excel v-else-if="currFileType==='xls' || currFileType==='xlsx'" :src="$utils.getFullFilePathHM(currentRow.attPath)" />
        <div v-else class="empty-content"><p>文件格式暂不支持预览</p></div>
    </div>
</template>

<script>
// 引入VueOfficeExcel组件
import VueOfficeExcel from '@vue-office/excel'
// 引入VueOfficeDocx组件
import VueOfficeDocx from '@vue-office/docx'
// 引入相关样式
import '@vue-office/excel/lib/index.css'
import '@vue-office/docx/lib/index.css'

import { downloadFileNew } from '@/api/sponge-control/common-hm'
export default {
    name: 'PreviewFile',
    components: {
        VueOfficeExcel,
        VueOfficeDocx
    },
    props: {
        currentRow: {
            type: Object,
            default: () => {}
        }
    },
    data() {
        return {
            
        }
    },
    computed: {
        currFileType() {
            const arr = this.currentRow.attPath?.split('.')
            return arr && arr[arr.length - 1] || ''
        }
    },
    watch: {
        'currentRow.attPath': {
            handler() {
                if (this.currFileType === 'txt') {
                    this.$nextTick(async() => {
                        const res = await downloadFileNew({ fileName: this.currentRow.attName, filePath: this.currentRow.attPath }, true)
                        const reader = new FileReader()
                        reader.readAsText(res, 'UTF-8')
                        reader.onload = e => {
                            this.$refs.txt.innerText = e.target.result
                        }
                    })
                }
            },
            immediate: true
        }
        
    }
}
</script>

<style lang="scss" scoped>
.container {
    width: 100%;
    height: 100%;

    .txt {
        width: 100%;
        height: 100%;
        overflow: auto;
        word-break: break-all;
        border: 0;
    }

    .file {
        width: 100%;
        height: 100%;
        overflow: auto;
        border: 0;
    }

    .file ::v-deep .docx-wrapper {
        height: 100%;
        padding: 20px 20px;
        background-color: #fff;
        border: 1px solid #eee;
    }

    .file ::v-deep .docx-wrapper > section.docx {
        width: 100% !important;
        height: 80%;
        min-height: auto !important;
        padding: 0 !important;
        margin-bottom: 0;
        overflow-y: scroll;
        box-shadow: none;
    }

    .file ::v-deep .docx-wrapper > section.docx::-webkit-scrollbar {
        display: none;
    }

    .empty-content {
        width: 100%;
        height: 100%;
        overflow: hidden;
        text-align: center;
        border: 1px solid #eee;

        p {
            position: relative;
            top: 40%;
            font-size: 16px;
            color: #666;
        }
    }
}
</style>


对于文本文件txt,我们需要下载下来,然后读取里面的内容
,最好通过innerText插入div回显出来。


下面是文件下载的接口(这个需要后端提供):
// 文件下载
export function downloadFile(data) {
    return request({
        url: '/common/downloadFile',
        method: 'post',
        responseType: 'blob',
        data
    })
}
// 文件下载
export function downloadFileNew(data, needBlob = false) {
    return request({
        url: '/common/downloadFileNew',
        meta: { needBlob },
        method: 'post',
        responseType: 'blob',
        data
    })
}