<template> <div> <!-- 项目手册报告 --> <!-- 表单查询项 --> <div v-if="!previewMode" class="headerbox"> <el-form size="small" :inline="true" label-width="200"> <el-row> <el-col :span="5"> <el-form-item label="文件标题" style="width: 100%;"> <el-input v-model="queryParams.title" placeholder="请输入模板标题" clearable /> </el-form-item> </el-col> <el-col :span="5"> <el-form-item label="发布时间"> <el-date-picker v-model="queryParams.startTime" type="date" placeholder="选择日期" style="width: 100%;"></el-date-picker> </el-form-item> </el-col> <el-col :span="8"> <el-form-item> <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">查询</el-button> <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button> </el-form-item> </el-col> </el-row> </el-form> </div> <!-- 表格内容区 --> <div v-if="!previewMode" class="tablebox"> <el-table v-loading="loading" :data="postList" @selection-change="handleSelectionChange"> <el-table-column type="selection" width="55" align="center" /> <el-table-column label="序号" align="center" prop="id" /> <el-table-column label="文件标题" align="center" prop="title" /> <el-table-column label="发布单位" align="center" prop="unit" /> <!-- <el-table-column label="发布人" align="center" prop="author" /> --> <el-table-column label="发布时间" align="center" prop="createTime" /> <el-table-column label="操作" align="center"> <template slot-scope="scope"> <el-button size="mini" type="text" style="color: gray;" @click="handlePreview(scope.row)">预览</el-button> </template> </el-table-column> </el-table> <pagination v-show="total > 0" :total="total" :page.sync="queryParams.current" :limit.sync="queryParams.size" @pagination="getList" /> </div> <!-- DOCX预览区域 --> <div v-if="previewMode" class="previewbox"> <div class="previewhead"> <h3>{{ previewData.title }}</h3> <div class="headtwo"> <el-button size="mini" @click="previewMode = false">返回</el-button> </div> </div> <div class="previewcontent"> <vue-office-docx :src="docxFileData" style="width: 100%; height: calc(100vh - 250px); border: 1px solid #eee;" @rendered="renderedHandler" /> </div> </div> </div> </template> <script> import VueOfficeDocx from '@vue-office/docx' import axios from 'axios' export default { components: { 'vue-office-docx': VueOfficeDocx }, data() { return { // 查询参数 queryParams: { current: 1, size: 10, title: undefined, startTime: undefined }, // 所有数据(模拟从后端获取) allPostList: [ { id: 1, title: '苏州工业园区总体报告模板', unit: '经发委', author: '', createTime: '2024-08-20', fileUrl: 'docx/苏州工业园区总体报告模板.docx' }, ], // 表格显示的数据 postList: [], // 加载状态 loading: false, // 总条数 total: 0, // 预览模式 previewMode: false, // 预览数据 previewData: {}, // DOCX文件数据 docxFileData: null } }, created() { this.getList() }, methods: { // 获取表格数据 getList() { this.loading = true; // 根据查询条件过滤数据 let filteredData = this.allPostList.filter(item => { if (this.queryParams.title && !item.title.includes(this.queryParams.title)) { return false; } if (this.queryParams.startTime && new Date(item.createTime) < new Date(this.queryParams.startTime)) { return false; } return true; }); // 分页处理 const start = (this.queryParams.current - 1) * this.queryParams.size; const end = start + this.queryParams.size; this.postList = filteredData.slice(start, end); this.total = filteredData.length; this.loading = false; }, // 查询 handleQuery() { this.queryParams.current = 1; this.getList(); }, // 重置查询 resetQuery() { this.queryParams = { current: 1, size: 10, title: undefined, startTime: undefined }; this.handleQuery(); }, // 表格选择变化 handleSelectionChange(selection) { this.ids = selection.map(item => item.id) this.single = selection.length !== 1 this.multiple = !selection.length }, // 预览文档 handlePreview(row) { this.previewMode = true this.previewData = row this.loadDocxFile(row.fileUrl) }, // 加载DOCX文件 loadDocxFile(url) { this.docxFileData = null axios.get(url, { responseType: 'arraybuffer' }) .then(response => { this.docxFileData = response.data }) .catch(error => { console.error('加载文档失败:', error) this.$message.error('文档加载失败') }) }, // 文档渲染完成回调 renderedHandler() { console.log('文档渲染完成') } } } </script> <style scoped> .headerbox { background-color: #fff; border-radius: .5rem; padding: 1rem; margin: .5rem; border: 1px solid #eee; } .tablebox { background-color: #fff; border-radius: .5rem; padding: 1rem; margin: .5rem; border: 1px solid #eee; } .tablebtntwo { width: 100%; display: flex; justify-content: space-between; margin-top: 1rem; margin-bottom: 1rem; } .previewbox { width: 99%; margin-left: 0.5%; height: 92rem; margin-top: .3rem; display: flex; flex-direction: column; padding: 1rem; background-color: #fff; box-shadow: 0 0 10px rgba(0, 0, 0, 0.1); } .previewhead { width: 100%; height: 2rem; display: flex; align-items: center; justify-content: space-between; } .headtwo { display: flex; gap: .5rem; } .previewinfo { display: flex; gap: 1rem; justify-content: flex-start; margin-top: 1rem; } .previewcontent { margin-top: 1rem; width: 100%; } </style>