vue 预览PDF、Docx、EXCEL文件

发布时间 2023-04-11 10:49:34作者: 不服憋着

 

 

<template>
    <div class="contentArea">
       <div class="fileContainer" ref="fileDiv" v-if="$route.query.fileName.indexOf('docx') !== -1"></div>
       <div class="fileContainer" v-html="tableau" id="excelView" v-else></div>
    </div>
</template>

<script>
import XLSX from 'xlsx';
let docx = require("docx-preview");
import {FileDownload, xlsxFileDownload} from '@/api/index'
export default {
    data(){
        return{
            vHtml: '',
            tableau: '',
            fileId: '',
        }
    },
    mounted () {
        this.fileId = this.$route.query.fileId
        const fileName = this.$route.query.fileName
        if(fileName.indexOf('xls') !== -1){
            this.previewData()
        } else {
            this.getFile()
        }
        window.document.title = fileName
    },
    methods: {
        // word文件预览
        getFile(){
            FileDownload(this.fileId).then((res) => {
              const content = res.data;
              docx.renderAsync(content, this.$refs.fileDiv);
            }).catch(() => {
              this.$message.error('下载失败!')
            });
        },
        async previewPdfFile(){
            const resCancel = await xlsxFileDownload(this.fileId);
            // const url = window.URL.createObjectURL(file.originFileObj);
            const url = window.URL.createObjectURL(resCancel.data);
            window.open(url, file.name);
        },
        // xlsx预览
        async previewData() {
                const resCancel = await xlsxFileDownload(this.fileId);
                if (resCancel) {
                    const data = new Uint8Array(resCancel.data);
                    const workbook = XLSX.read(data, {
                        type: 'array', cellDates: true, dateNF: "yyyy-MM-dd"
                    });
                    // 删除掉没有数据的sheet
                    Object.values(workbook.Sheets).forEach((sheet, index) => {
                        if (Object.keys(sheet).indexOf('!ref') === -1) {
                            delete workbook.Sheets[workbook.SheetNames[index]];
                        }
                        Object.values(sheet).forEach(sec=>{
                          if(sec.constructor === Object && sec.t=='d'){
                            sec.w = this.$moment(sec.v).format("YYYY/MM/DD")
                          }
                        })

                    });
                    var worksheet = workbook.Sheets[workbook.SheetNames[0]]; // workbook.SheetNames 下存的是该文件每个工作表名字,这里取出第一个工作表
                    this.tableau = XLSX.utils.sheet_to_html(worksheet); // 渲染
                    this.$nextTick(function () {
                        // DOM加载完毕后执行,解决HTMLConnection有内容但是length为0问题。
                        this.setStyle4ExcelHtml();
                    });
                } else {
                    this.$message.warn(resCancel.errorMessage);

                }
            },
            // 设置Excel转成HTML后的样式
            setStyle4ExcelHtml() {
                const excelViewDOM = document.getElementById("excelView");
                if (excelViewDOM) {
                    const excelViewTDNodes = excelViewDOM.getElementsByTagName("td"); // 获取的是HTMLConnection
                    if (excelViewTDNodes) {
                        const excelViewTDArr = Array.prototype.slice.call(excelViewTDNodes);
                        for (const i in excelViewTDArr) {
                            const id = excelViewTDArr[i].id; // 默认生成的id格式为sjs-A1、sjs-A2......
                            if (id) {
                                const idNum = id.replace(/[^0-9]/gi, ""); // 提取id中的数字,即行号
                                if (idNum && (idNum === "1" || idNum === 1)) {
                                    // 第一行标题行
                                    excelViewTDArr[i].classList.add("class4Title");
                                } else if ((idNum !== "1" || idNum !== 1)) {
                                    // 第二行表头行
                                    excelViewTDArr[i].classList.add("class4TableTh");
                                }
                            }
                        }
                    }
                }
            },
    },

}
</script>

<style lang="less" scoped>
.contentArea{
    height: 100%;
    width: 100%;
}
.fileContainer{
    height: 100%;
    width: 100%;
}

/deep/ .class4Title {
    font-size: 18px !important;
    font-weight: bold !important;
    padding: 10px !important;
    border: 1px solid #e8e8e8;
    text-align: center;
}

/deep/ .class4TableTh {
    font-size: 12px !important;
    font-weight: bold !important;
    padding: 10px !important;
    border: 1px solid #e8e8e8;
    text-align: center;
    white-space: break-spaces

}

</style>