您好,登錄后才能下訂單哦!
今天小編給大家分享一下vue項(xiàng)目怎么實(shí)現(xiàn)前端預(yù)覽word與pdf格式文件的相關(guān)知識(shí)點(diǎn),內(nèi)容詳細(xì),邏輯清晰,相信大部分人都還太了解這方面的知識(shí),所以分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后有所收獲,下面我們一起來了解一下吧。
頁(yè)面上傳pdf文件效果如下:
頁(yè)面預(yù)覽pdf文件效果如下:
頁(yè)面上傳word文件效果如下:
頁(yè)面預(yù)覽word文件效果如下:
這里先從上傳組件頁(yè)面說起,上傳頁(yè)面組件完整代碼如下,按鈕里面v-show=“$checkPermission([‘Register_tuotpUpload’])“都是給這個(gè)按鈕設(shè)置了按鈕權(quán)限的,我們只需要關(guān)注上傳那一部分的代碼即可,我們用了el-upload組件實(shí)現(xiàn)的手動(dòng)上傳,由于需求要求只能上傳word和pdf,所以能看到屬性設(shè)置的有 accept=”.pdf, .doc, .docx”,然后不展示上傳成功的文件的列表設(shè)置的屬性有:show-file-list=“false”,而handleExceed回調(diào)函數(shù)和limit都是為了限制只能上傳一個(gè)文件,上傳前的回調(diào)鉤子函數(shù)beforeAvatarUpload里進(jìn)行了文件類型判斷與提醒,手動(dòng)上傳是通過UploadFile里進(jìn)行完成的,需要注意的是由于docx-preview這個(gè)插件只能預(yù)覽后綴為docx的word文件,如果是doc后綴格式的word文件一定要讓后端強(qiáng)制將上傳doc格式的文件改為docx格式,目前對(duì)于doc格式的word文件實(shí)現(xiàn)網(wǎng)頁(yè)在線預(yù)覽我只想到了docx-preview這個(gè)插件和這個(gè)解決辦法:
<template> <div class="app-container"> <div class="cardWhite"> <div class="itemBox"> <div class="headerTitle">基本信息</div> <el-form :model="ruleForm" :rules="rules" ref="ruleForm" label-width="120px" class="demo-ruleForm" > <el-row> <el-col :span="12"> <el-form-item label="鏈路名稱" prop="name"> <el-input v-model="ruleForm.name" placeholder="請(qǐng)輸入鏈路名稱" clearable ></el-input> </el-form-item> </el-col> <el-col :span="12"> <el-form-item label="鏈路類型" prop="linkType"> <el-select v-model="ruleForm.linkType" placeholder="請(qǐng)選擇鏈路類型" clearable > <el-option v-for="item in linkTypeList" :key="item.val" :label="item.key" :value="item.val" ></el-option> </el-select> </el-form-item> </el-col> <el-col :span="12"> <el-form-item label="鏈路走向" prop="go"> <el-row> <el-col :span="10"> <el-select v-model="ruleForm.srcNetwork" placeholder="請(qǐng)選擇" clearable @clear="clearSrc" @change="srcChange" > <el-option v-for="item in scrList" :key="item.val" :label="item.key" :value="item.val" ></el-option> </el-select> </el-col> <el-col :span="4"> <div > <img src="@/assets/toRight.png" /> </div> </el-col> <el-col :span="10"> <el-select v-model="ruleForm.dstNetwork" placeholder="請(qǐng)選擇" :clearable="false" @clear="clearDst" @change="dstChange" > <el-option v-for="item in dstList" :key="item.val" :label="item.key" :value="item.val" ></el-option> </el-select> </el-col> </el-row> </el-form-item> </el-col> <el-col :span="12"> <el-form-item label="物理位置" prop="physicalPosition"> <el-input v-model="ruleForm.physicalPosition" placeholder="請(qǐng)輸入鏈路物理位置" clearable ></el-input> </el-form-item> </el-col> <el-col :span="12"> <el-form-item label="所屬機(jī)構(gòu)" prop="orangeName"> <el-input v-model="ruleForm.orangeName" placeholder="例:xx市公安局" clearable ></el-input> </el-form-item> </el-col> <el-col :span="12"> <el-form-item label="行政區(qū)編碼" prop="organCode"> <el-input v-model="ruleForm.organCode" placeholder="請(qǐng)輸入行政區(qū)編碼,例:027" clearable ></el-input> </el-form-item> </el-col> <el-col :span="12"> <el-form-item label="責(zé)任人" prop="dutyPerson"> <el-input v-model="ruleForm.dutyPerson" placeholder="請(qǐng)輸入鏈路責(zé)任人" clearable ></el-input> </el-form-item> </el-col> <el-col :span="12"> <el-form-item label="責(zé)任人電話" prop="dutyTel"> <el-input v-model="ruleForm.dutyTel" placeholder="請(qǐng)輸入鏈路責(zé)任人電話" clearable ></el-input> </el-form-item> </el-col> </el-row> <el-row> <el-col :span="12"> <el-form-item label="公安網(wǎng)郵箱" prop="dutyEmail"> <el-input v-model="ruleForm.dutyEmail" placeholder="請(qǐng)輸入負(fù)責(zé)人公安網(wǎng)郵箱" clearable ></el-input> </el-form-item> </el-col> </el-row> <el-row> <el-col :span="12"> <el-form-item label="鏈路IP地址" prop="ip"> <el-input v-model="ruleForm.ip" placeholder="請(qǐng)輸入鏈路IP地址" clearable ></el-input> </el-form-item> </el-col> <el-col :span="12"> <el-form-item label="鏈路端口" prop="port"> <el-input-number placeholder="請(qǐng)輸入鏈路端口" type="text" :min="0" :controls="false" v-model.trim="ruleForm.port" ></el-input-number> </el-form-item> </el-col> </el-row> <el-row> <el-col :span="12"> <el-form-item label="管理頁(yè)面" prop="webUrl"> <el-input v-model="ruleForm.webUrl" placeholder="請(qǐng)輸入鏈路管理頁(yè)面" clearable ></el-input> </el-form-item> </el-col> </el-row> <el-row> <el-col :push="2"> <el-button class="filter-item" type="primary" icon="el-icon-plus" @click="saveForm" v-show="$checkPermission(['Register_boundarySave'])" > 保存 </el-button> </el-col> </el-row> </el-form> </div> <div class="itemBox"> <div class="headerTitle">鏈路拓?fù)鋱D</div> <el-form :model="tuopuForm" ref="tuopuForm" label-width="120px"> <el-row> <el-col :span="12"> <el-form-item label="拓?fù)鋱D" prop="fileName"> <el-input v-model="tuopuForm.fileName" placeholder="請(qǐng)選擇電腦中拓?fù)鋱D文件" clearable disabled > <el-upload accept=".pdf, .doc, .docx" action="string" :limit="1" :on-exceed="handleExceed" :before-upload="beforeAvatarUpload" :http-request="UploadFile" slot="append" :show-file-list="false" > <el-button type="primary" v-show="$checkPermission(['Register_tuotpUpload'])" icon="el-icon-upload2" >上傳</el-button > </el-upload> </el-input> </el-form-item> </el-col> <el-col :span="3" :push="1"> <el-button class="filter-item" type="primary" icon="el-icon-view" @click="preview" v-show="$checkPermission(['Register_tuotpPreview'])" > 預(yù)覽 </el-button> </el-col> </el-row> </el-form> </div> <div class="itemBox"> <div class="headerTitle">設(shè)備信息列表</div> <el-row type="flex" justify="end" > <el-button class="filter-item" type="primary" icon="el-icon-plus" @click="addEquipment" v-show="$checkPermission(['Register_equipmentAdd'])" > 添加 </el-button> </el-row> <div> <commonTable :tableHead="tableHead" :tableData="tableData" :dataFiter="true" :selectionFlag="false" :dropdownList="[]" :resizable="true" :tableLoading="tableLoading" :showListD="showListD" :toolBoxFlag="false" @sortChange="() => {}" @selection-change="() => {}" @selectAction="() => {}" @addData="() => {}" :actionFlag="false" :actionList="[]" :freeElfFlag="false" :xuhaoFlag="true" :freeWidth="480" > <template slot-scope="scope" slot="doSomething" fixed="right" align="left" > <el-button icon="el-icon-edit" type="primary" @click="handlerUpdate(scope.rows)" v-show="$checkPermission(['Register_equipmentEdit'])" >編輯</el-button > <el-button icon="el-icon-delete" type="danger" @click="handlerDelete(scope.rows)" v-show="$checkPermission(['Register_equipmentDelete'])" >刪除</el-button > </template> </commonTable> </div> </div> <div class="itemBox"> <div class="headerTitle">鏈路注冊(cè)</div> <el-row type="flex" justify="end" > <el-button class="filter-item" type="primary" icon="el-icon-plus" @click="addRegister" v-show="$checkPermission(['Register_registerAdd'])" > 添加 </el-button> </el-row> <div> <commonTable :tableHead="Register_tableHead" :tableData="Register_tableData" :dataFiter="true" :selectionFlag="false" :dropdownList="[]" :resizable="true" :tableLoading="Register_tableLoading" :showListD="Register_showListD" :toolBoxFlag="false" @sortChange="() => {}" @selection-change="() => {}" @selectAction="() => {}" @addData="() => {}" :actionFlag="false" :actionList="[]" :freeElfFlag="false" :xuhaoFlag="true" :freeWidth="480" > <template slot-scope="scope" slot="status"> <el-tag v-if="scope.rows.status == 1">已注冊(cè)</el-tag> <el-tag type="success" v-if="scope.rows.status == 0" >未注冊(cè)</el-tag > <el-tag type="danger" v-if="scope.rows.status == 2" >注冊(cè)失敗</el-tag > </template> <template slot-scope="scope" slot="doSomething" fixed="right" align="left" > <el-button icon="el-icon-edit" type="primary" v-if=" scope.rows.status == 1 && $checkPermission(['Register_registerOff']) " @click="handlerLogoff(scope.rows)" >注銷</el-button > <el-button icon="el-icon-edit" type="primary" v-if=" ($checkPermission(['Register_registerGo']) && scope.rows.status == 0) || scope.rows.status == 2 " @click="handlerLogoff(scope.rows)" >注冊(cè)</el-button > <el-button icon="el-icon-delete" type="danger" v-if="$checkPermission(['Register_registerDelete'])" @click="Register_handlerDelete(scope.rows)" >刪除</el-button > </template> </commonTable> </div> </div> </div> <!-- 添加和編輯設(shè)備彈窗 --> <el-dialog :title="textMap[dialogStatus]" :visible.sync="dialogFormVisible" width="800px" :before-close="handleClose" :close-on-click-modal="false" > <add-edit @refresh="fetchData" @closeDialog="dialogFormVisible = false" class="AddEdit" ref="AddEdit" :devTypeList="EquipmentList" v-if="dialogFormVisible" /> <div slot="footer" class="dialog-footer"> <el-button @click="dialogFormVisible = false"> 取消 </el-button> <el-button type="primary" @click="submitForm()"> 確定 </el-button> </div> </el-dialog> <!-- 鏈路注冊(cè)彈窗 --> <el-dialog title="鏈路注冊(cè)" :visible.sync="Register_dialogFormVisible" width="800px" :before-close="Register_handleClose" :close-on-click-modal="false" > <register-add @reg_refresh="Register_fetchData" @reg_closeDialog="Register_dialogFormVisible = false" ref="RegisterAdd" v-if="Register_dialogFormVisible" /> <div slot="footer" class="dialog-footer"> <el-button @click="Register_dialogFormVisible = false"> 取消 </el-button> <el-button type="primary" @click="Register_submitForm()"> 確定 </el-button> </div> </el-dialog> </div> </template> <script> import commonTable from "@/components/common-table"; import Pagination from "@/components/Pagination"; import AddEdit from "./EquipmentAddEdit.vue"; import RegisterAdd from "./RegisterAdd.vue"; import * as api from "@/api/datax-register.js"; import axios from "axios"; import { getToken } from "@/utils/auth"; export default { components: { Pagination, commonTable, AddEdit, RegisterAdd }, data() { const validateGo = (rule, value, callback) => { // if (!value) { // callback("請(qǐng)輸入平臺(tái)IP地址"); // } else { // let index = value.indexOf("/"); // let findHengT = value.indexOf("-"); // let findHengP = value.indexOf("——"); // if (index > -1 || findHengT > -1 || findHengP > -1) { // callback("請(qǐng)輸入正確格式的平臺(tái)IP地址"); // } else { // validator.IpArea(rule, value, callback); // } // } if (!this.ruleForm.srcNetwork || !this.ruleForm.dstNetwork) { callback("請(qǐng)選擇鏈路走向"); } else { callback(); } }; return { ruleForm: { name: "", linkType: "", srcNetwork: "", dstNetwork: "", physicalPosition: "", orangeName: "", organCode: "", dutyPerson: "", dutyTel: "", dutyEmail: "", ip: "", port: undefined, webUrl: "" }, rules: { name: [{ required: true, message: "請(qǐng)輸入鏈路名稱", trigger: "blur" }], linkType: [ { required: true, message: "請(qǐng)選擇鏈路類型", trigger: "blur" } ], go: [ { required: true, message: "請(qǐng)選擇鏈路走向", trigger: "blur", validator: validateGo } ], physicalPosition: [ { required: false, message: "請(qǐng)輸入鏈路物理位置", trigger: "blur" } ], orangeName: [ { required: true, message: "請(qǐng)輸入所屬機(jī)構(gòu)", trigger: "blur" } ], organCode: [ { required: true, message: "請(qǐng)輸入行政區(qū)編碼", trigger: "blur" } ], dutyPerson: [ { required: true, message: "請(qǐng)輸入鏈路責(zé)任人", trigger: "blur" } ], dutyTel: [ { required: true, message: "請(qǐng)輸入鏈路責(zé)任人電話", trigger: "blur" } ], dutyEmail: [ { required: false, message: "請(qǐng)輸入負(fù)責(zé)人公安網(wǎng)郵箱", trigger: "blur" } ], ip: [{ required: false, message: "請(qǐng)輸入鏈路IP地址", trigger: "blur" }], port: [{ required: true, message: "請(qǐng)輸入鏈路端口", trigger: "blur" }], webUrl: [ { required: false, message: "請(qǐng)輸入鏈路管理頁(yè)面", trigger: "blur" } ] }, linkTypeList: [], scrList: [], dstList: [], tuopuForm: { fileName: "", fileUrl: "" }, tableHead: [ { label: "設(shè)備名稱", prop: "name", type: "normal", sortable: false }, { label: "設(shè)備類型", prop: "devType", type: "normal", sortable: false // width: 150 }, { label: "廠商", prop: "manufacturer", type: "normal", sortable: false // width: 150 }, { label: "型號(hào)", prop: "model", type: "normal", sortable: false // width: 150 }, { label: "設(shè)備IP", prop: "devIp", type: "normal", sortable: false }, { label: "子網(wǎng)掩碼", prop: "ipMask", type: "normal", sortable: false // width: 150 }, { label: "網(wǎng)關(guān)", prop: "ipGaway", type: "normal", sortable: false // width: 150 }, { label: "安裝時(shí)間", prop: "installTime", type: "normal", sortable: false, width: 180 }, { label: "操作", prop: "doSomething", type: "slot", sortable: false, slotName: "doSomething", width: 220 } // { // label: "任務(wù)詳情", // prop: "log_text", // type: "slot", // sortable: false, // slotName: "log_text", // width: 100 // } ], showListD: [ "name", "devType", "manufacturer", "model", "devIp", "ipMask", "ipGaway", "installTime", "doSomething" // "log_text" ], dialogStatus: "", dialogFormVisible: false, textMap: { update: "編輯設(shè)備", Edit: "編輯設(shè)備", edit: "編輯設(shè)備", create: "添加設(shè)備" }, tableData: [], tableLoading: false, Register_tableHead: [ { label: "平臺(tái)名稱", prop: "name", type: "normal", sortable: false }, { label: "平臺(tái)IP地址", prop: "ip", type: "normal", sortable: false }, { label: "平臺(tái)端口", prop: "port", type: "normal", sortable: false }, { label: "平臺(tái)唯一標(biāo)識(shí)", prop: "uniquePlatformCode", type: "normal", sortable: false }, { label: "注冊(cè)時(shí)間", prop: "lastTime", type: "normal", sortable: false, width: 180 }, { label: "注冊(cè)狀態(tài)", prop: "status", type: "slot", slotName: "status", sortable: false }, { label: "操作", prop: "doSomething", type: "slot", sortable: false, slotName: "doSomething", width: 220 } // { // label: "任務(wù)詳情", // prop: "log_text", // type: "slot", // sortable: false, // slotName: "log_text", // width: 100 // } ], Register_tableData: [], Register_tableLoading: false, Register_showListD: [ "name", "ip", "port", "uniquePlatformCode", "lastTime", "status", "doSomething" // "log_text" ], Register_dialogFormVisible: false, fileList: null, //拓?fù)鋱D文件列表 tuotpData: null, EquipmentList: [], originalList: [] }; }, created() { this.getNews(); }, methods: { getNews() { //獲取邊界信息 this.getBoundaryDetail(); //獲取拓?fù)鋱D this.getTuotp(); //獲取設(shè)備列表 this.fetchData(); //獲取鏈路注冊(cè)列表 this.Register_fetchData(); //獲取公共下拉 this.getSelect(); }, saveForm() { this.$refs["ruleForm"].validate(valid => { if (valid) { let params = { ...this.ruleForm }; console.log("修改入?yún)?quot;, params); //修改 api .boundaryEdit(params) .then(res => { console.log("修改", res); if (res.code == 200) { this.$notify({ title: "成功", message: "邊界信息修改成功", type: "success", duration: 2000 }); } }) .catch(err => {}); } }); }, preview() { console.log("預(yù)覽", this.fileList, this.tuopuForm); if (!this.fileList) { this.$message.error( "拓?fù)鋱D文件為空不能預(yù)覽,請(qǐng)先上傳拓?fù)鋱D文件后再預(yù)覽", 6000 ); return false; } this.$router.push({ path: "TuotpPreview", query: { fileName: this.tuopuForm.fileName, fileUrl: this.tuopuForm.fileUrl } }); }, addEquipment() { this.dialogStatus = "create"; this.dialogFormVisible = true; setTimeout(() => { this.$refs["AddEdit"].dialogStatus = "create"; // this.$refs.AddEdit.resetTransferDetail(); // this.getCommonData(); }, 1); }, //獲取公共下拉 getSelect() { api .getLinkEquimentSelect({ clsName: "link_direction" }) .then(res => { console.log("鏈路走向下拉", res); this.scrList = res.data; this.dstList = res.data; this.originalList = res.data; }) .catch(err => {}); api .getLinkEquimentSelect({ clsName: "link_type" }) .then(res => { console.log("鏈路類型下拉", res); this.linkTypeList = res.data; }) .catch(err => {}); api .getLinkEquimentSelect({ clsName: "dev_type" }) .then(res => { console.log("設(shè)備類型下拉", res); this.EquipmentList = res.data; }) .catch(err => {}); }, //獲取邊界信息 getBoundaryDetail() { api .boundaryDetail() .then(res => { // console.log("獲取邊界信息", res); this.ruleForm = res.data; this.ruleForm.port = res.data.port ? res.data.port : undefined; }) .catch(err => {}); }, //獲取拓?fù)鋱D getTuotp() { api .boundaryTuopoDetail() .then(res => { // console.log("獲取拓?fù)鋱D成功", res); this.tuopuForm = res.data; this.tuopuPreview(); }) .catch(err => { // console.log("獲取拓?fù)鋱D失敗", err); }); }, //獲取設(shè)備列表 fetchData() { this.tableLoading = true; api .equipmentList({ page: 1, page_size: 99999, ip: "" }) .then(res => { // console.log("設(shè)備列表", res); if (res.code == 200) { this.tableData = res.data.list; this.tableLoading = false; } }) .catch(err => {}); }, //編輯 handlerUpdate(row) { // console.log("點(diǎn)了修改", row); this.dialogStatus = "Edit"; this.dialogFormVisible = true; setTimeout(() => { this.$refs["AddEdit"].setData(row); this.$refs["AddEdit"].dialogStatus = "Edit"; }, 1); }, handleClose() { this.dialogFormVisible = false; }, submitForm() { this.$refs["AddEdit"].submitForm(); }, //刪除 handlerDelete(row) { this.$confirm("確定刪除嗎?", "提示", { confirmButtonText: "確定", cancelButtonText: "取消", type: "warning" }).then(() => { api .equipmentDelete(row) .then(response => { if (response.code == 200) { this.fetchData(); this.$notify({ title: "成功", message: "刪除成功", type: "success", duration: 2000 }); } }) .catch(err => {}); }); // const index = this.list.indexOf(row) }, //注銷 handlerLogoff(row) { api .registerStatusSwitch({ id: row.id, status: row.status == 1 ? 2 : 1 }) .then(res => { this.Register_fetchData(); }) .catch(err => {}); }, //鏈路刪除 Register_handlerDelete(row) { this.$confirm("確定刪除嗎?", "提示", { confirmButtonText: "確定", cancelButtonText: "取消", type: "warning" }).then(() => { let id = row.id; api.VideoTaskDelete(id).then(response => { if (response.code == 200) { this.fetchData(); this.$notify({ title: "成功", message: "刪除成功", type: "success", duration: 2000 }); } }); }); }, //鏈路添加 addRegister() { this.$refs["ruleForm"].validate(valid => { if (valid) { this.Register_dialogFormVisible = true; setTimeout(() => { // this.$refs["AddEdit"].dialogStatus = "create"; // this.$refs.AddEdit.resetTransferDetail(); // this.getCommonData(); }, 1); } else { this.$message.error("基本信息為空不能添加,請(qǐng)先補(bǔ)充基本信息", 6000); } }); }, Register_handleClose() { this.Register_dialogFormVisible = false; }, Register_submitForm() { this.$refs["RegisterAdd"].submitForm(); }, //獲取鏈路注冊(cè)列表 Register_fetchData() { this.Register_tableLoading = true; api .registerList({ page: 1, page_size: 99999, ip: "" }) .then(res => { console.log("注冊(cè)列表", res); if (res.code == 200) { this.Register_tableData = res.data.list; this.Register_tableLoading = false; } }) .catch(err => {}); }, handleExceed(files, fileList) { if (files.length > 1) { this.$message.warning( `當(dāng)前限制最多選擇1個(gè)文件上傳,本次選擇了${files.length}個(gè)文件` ); } }, //文件上傳前的鉤子 beforeAvatarUpload(file) { console.log("文件上傳前的鉤子", file); // 文件類型判斷 var testmsg = file.name.substring(file.name.lastIndexOf(".") + 1); const extension = testmsg === "doc"; const extension2 = testmsg === "pdf"; const extension3 = testmsg === "docx"; if (!extension && !extension2 && !extension3) { this.$message({ message: "上傳的拓?fù)鋱D文件只能是word、pdf格式,請(qǐng)重新上傳!", type: "error", duration: 6000 }); this.fileList = null; return false; } else { this.fileList = file; } }, //自定義上傳 UploadFile() { // 參數(shù)拼接 let fileData = new FormData(); fileData.append("file", this.fileList); // 調(diào)用接口 axios({ url: `${window.g.API_URL}/api/cascade/topo/upload`, method: "post", data: fileData, headers: { "Content-Type": "multipart/form-data", Authorization: getToken() } }) .then(res => { console.log("上傳成功", res); if (res.data.code == 200) { this.tuopuForm = res.data.data; //拓?fù)漕A(yù)覽 this.tuopuPreview(); } else { console.log("上傳失敗1"); this.$message({ message: "上傳拓?fù)鋱D文件失敗,請(qǐng)稍后重試!", type: "error", duration: 6000 }); } }) .catch(err => { console.log("上傳失敗2", err); this.$message({ message: "上傳拓?fù)鋱D文件失敗,請(qǐng)稍后重試!", type: "error", duration: 6000 }); }); }, tuopuPreview() { axios({ url: `${window.g.API_URL}/api/cascade/topo/preview`, method: "get", params: { fileUrl: this.tuopuForm.fileUrl }, headers: { Authorization: getToken() }, responseType: "arraybuffer" }) .then(res => { console.log("拓?fù)漕A(yù)覽獲取成功", res); if (res.status == 200) { this.fileList = res.data; } }) .catch(err => { console.log("拓?fù)漕A(yù)覽失敗失敗", err); }); }, srcChange(val) { console.log("srcChange", val); if (val == this.ruleForm.dstNetwork) { this.ruleForm.dstNetwork = ""; } this.dstList = this.originalList.filter(k => { return k.val != val; }); }, clearSrc() { this.scrList = JSON.parse(JSON.stringify(this.originalList)); }, dstChange(val) { console.log("dstChange", val); if (val == this.ruleForm.srcNetwork) { this.ruleForm.srcNetwork = ""; } this.scrList = this.originalList.filter(k => { return k.val != val; }); }, clearDst() { this.dstList = JSON.parse(JSON.stringify(this.originalList)); } } }; </script> <style lang="scss" scoped> .app-container { .cardWhite { .itemBox { margin-bottom: 1.5rem; .headerTitle { font-size: 1rem; font-weight: bold; } } } } ::v-deep .el-input-number .el-input__inner { text-align: left; } </style>
上傳功能實(shí)現(xiàn)之后,我們?cè)倏搭A(yù)覽功能。我們需求是點(diǎn)擊預(yù)覽按鈕之后跳到一個(gè)新頁(yè)面進(jìn)行預(yù)覽,我先是對(duì)文件是否為空是否沒上傳進(jìn)行了一個(gè)判斷攔截,由于預(yù)覽頁(yè)面組件與當(dāng)前頁(yè)面組件既非父子關(guān)系,又非爺孫關(guān)系,八竿子打不著的關(guān)系,我們就不能通過綁定和sessionStorage來進(jìn)行流文件的傳遞,只能在預(yù)覽頁(yè)面再發(fā)一次請(qǐng)求獲取文件流,我們可以把參數(shù)通過路由帶上,預(yù)覽按鈕對(duì)應(yīng)的方法代碼如下:
preview() { console.log("預(yù)覽", this.fileList, this.tuopuForm); if (!this.fileList) { this.$message.error( "拓?fù)鋱D文件為空不能預(yù)覽,請(qǐng)先上傳拓?fù)鋱D文件后再預(yù)覽", 6000 ); return false; } this.$router.push({ path: "TuotpPreview", query: { fileName: this.tuopuForm.fileName, fileUrl: this.tuopuForm.fileUrl } }); }
再來看預(yù)覽頁(yè)面,也就是TuotpPreview.vue組件。word預(yù)覽比較簡(jiǎn)單,先通過命令cnpm i docx-preview --save安裝插件docx-preview,需要注意的是這個(gè)插件只能預(yù)覽后綴為docx的word文件,如果是doc后綴格式的word文件一定要讓后端強(qiáng)制將上傳doc格式的文件改為docx格式,然后當(dāng)前頁(yè)面組件就直接import { defaultOptions, renderAsync } from “docx-preview”;引入,最后在data里進(jìn)行docxOptions配置,然后在頁(yè)面上 要顯示的div上綁定一個(gè) id="bodyContainer"的,因?yàn)橄旅嬉ㄟ^document.getElementById來獲取dom并操作dom,最后調(diào)用renderAsync方法即可。
cnpm i docx-preview --save //安裝word預(yù)覽插件docx-preview import { defaultOptions, renderAsync } from "docx-preview"; //引入docx-preview插件對(duì)應(yīng)的方法 docxOptions: { className: "kaimo-docx-666", // string:默認(rèn)和文檔樣式類的類名/前綴 inWrapper: true, // boolean:?jiǎn)⒂脟@文檔內(nèi)容的包裝器渲染 ignoreWidth: false, // boolean:禁用頁(yè)面的渲染寬度 ignoreHeight: false, // boolean:禁止渲染頁(yè)面高度 ignoreFonts: false, // boolean:禁用字體渲染 breakPages: true, // boolean:在分頁(yè)符上啟用分頁(yè) ignoreLastRenderedPageBreak: true, // boolean:在 lastRenderedPageBreak 元素上禁用分頁(yè) experimental: false, // boolean:?jiǎn)⒂脤?shí)驗(yàn)功能(制表符停止計(jì)算) trimXmlDeclaration: true, // boolean:如果為true,解析前會(huì)從 xml 文檔中移除 xml 聲明 useBase64URL: false, // boolean:如果為true,圖片、字體等會(huì)轉(zhuǎn)為base 64 URL,否則使用URL.createObjectURL useMathMLPolyfill: false, // boolean:包括用于 chrome、edge 等的 MathML polyfill。 showChanges: false, // boolean:?jiǎn)⒂梦臋n更改的實(shí)驗(yàn)性渲染(插入/刪除) debug: false // boolean:?jiǎn)⒂妙~外的日志記錄 },
pdf文件的預(yù)覽是通過獲取到blob文件流之后,直接通過window.open打開新窗口,通過瀏覽器就能預(yù)覽pdf,還有一種就是我現(xiàn)在的這種需求,要在頁(yè)面上預(yù)覽pdf,那就需要通過iframe,然后把blob流對(duì)應(yīng)的src地址賦值回顯即可。完整代碼如下:
<template> <div> <!-- 拓?fù)鋱D預(yù)覽 --> <div class="app-container"> <div class="cardWhite"> <div class="topArea"> <div class="backBox"> <img src="@/assets/goBack.png" @click="goBack" alt="" /> </div> <div class="titleBox"> {{ myTitle }} </div> </div> <div class="previewBox"> <div id="bodyContainer"> <iframe :src="pdfUrl" width="100%" height="750px" /> </div> </div> </div> </div> </div> </template> <script> import axios from "axios"; import { getToken } from "@/utils/auth"; import { defaultOptions, renderAsync } from "docx-preview"; export default { data() { return { myTitle: "", previewData: null, docxOptions: { className: "kaimo-docx-666", // string:默認(rèn)和文檔樣式類的類名/前綴 inWrapper: true, // boolean:?jiǎn)⒂脟@文檔內(nèi)容的包裝器渲染 ignoreWidth: false, // boolean:禁用頁(yè)面的渲染寬度 ignoreHeight: false, // boolean:禁止渲染頁(yè)面高度 ignoreFonts: false, // boolean:禁用字體渲染 breakPages: true, // boolean:在分頁(yè)符上啟用分頁(yè) ignoreLastRenderedPageBreak: true, // boolean:在 lastRenderedPageBreak 元素上禁用分頁(yè) experimental: false, // boolean:?jiǎn)⒂脤?shí)驗(yàn)功能(制表符停止計(jì)算) trimXmlDeclaration: true, // boolean:如果為true,解析前會(huì)從 xml 文檔中移除 xml 聲明 useBase64URL: false, // boolean:如果為true,圖片、字體等會(huì)轉(zhuǎn)為base 64 URL,否則使用URL.createObjectURL useMathMLPolyfill: false, // boolean:包括用于 chrome、edge 等的 MathML polyfill。 showChanges: false, // boolean:?jiǎn)⒂梦臋n更改的實(shí)驗(yàn)性渲染(插入/刪除) debug: false // boolean:?jiǎn)⒂妙~外的日志記錄 }, num: 1, numPages: 0, pdfUrl: "" }; }, created() { console.log("接收", this.$route.query); this.resetTitle(); this.getFile(); }, methods: { goBack() { this.$router.go(-1); }, //獲取文件流 getFile() { axios({ url: `${window.g.API_URL}/api/cascade/topo/preview`, method: "get", params: { fileUrl: this.$route.query.fileUrl }, headers: { Authorization: getToken() }, responseType: "arraybuffer" }) .then(res => { console.log("文件流獲取成功", res); if (res.status == 200) { this.previewData = res.data; if ( this.$route.query.fileName && this.$route.query.fileName.indexOf(".docx") && this.$route.query.fileName.indexOf(".pdf") == -1 ) { //word--docx格式 this.wordPreview(res.data); } else if ( this.$route.query.fileName && this.$route.query.fileName.indexOf(".doc") && this.$route.query.fileName.indexOf(".pdf") == -1 ) { //word--doc格式 this.wordPreview(res.data); } else if ( this.$route.query.fileName && this.$route.query.fileName.indexOf(".pdf") ) { //pdf this.pdfPreview(res.data); } } }) .catch(err => { console.log("文件流獲取失敗", err); this.$message.error("獲取文件信息失敗,請(qǐng)稍后重試", 6000); }); }, //重置標(biāo)題 resetTitle() { let fileName = this.$route.query.fileName; console.log("fileName", fileName); if ( fileName && fileName.indexOf(".docx") && fileName.indexOf(".pdf") == -1 ) { //word--docx格式 let wordDocxArr = fileName.split(".docx"); console.log("wordDocxArr", wordDocxArr); this.myTitle = wordDocxArr[0]; } else if ( fileName && fileName.indexOf(".doc") && fileName.indexOf(".pdf") == -1 ) { //word--doc格式 let wordDocArr = fileName.split(".docx"); console.log("wordDocArr", wordDocArr); this.myTitle = wordDocArr[0]; } else if (fileName && fileName.indexOf(".pdf")) { //pdf let pdfArr = fileName.split(".pdf"); console.log("pdfArr", pdfArr); this.myTitle = pdfArr[0]; } }, // word文檔預(yù)覽 wordPreview(buffer) { console.log("文檔buffer", buffer); let bodyContainer = document.getElementById("bodyContainer"); renderAsync( buffer, // Blob | ArrayBuffer | Uint8Array, 可以是 JSZip.loadAsync 支持的任何類型 bodyContainer, // HTMLElement 渲染文檔內(nèi)容的元素, null, // HTMLElement, 用于呈現(xiàn)文檔樣式、數(shù)字、字體的元素。如果為 null,則將使用 bodyContainer。 this.docxOptions // 配置 ) .then(res => { console.log("res---->", res); }) .catch(err => { console.log("err---->", err); }); }, //pdf預(yù)覽 pdfPreview(data) { // data是一個(gè)ArrayBuffer格式,也是一個(gè)buffer流的數(shù)據(jù) console.log("pdf流", data); const binaryData = []; binaryData.push(data); //獲取blob鏈接 let pdfUrl = window.URL.createObjectURL( new Blob(binaryData, { type: "application/pdf" }) ); console.log("pdfUrl", pdfUrl); // window.open(pdfUrl); 這種方式是直接打開新瀏覽器窗口預(yù)覽 this.pdfUrl = pdfUrl; } } }; </script> <style lang="scss" scoped> .app-container { .cardWhite { display: flex; flex-direction: column; .topArea { display: flex; position: relative; .backBox { margin-bottom: 1rem; img { cursor: pointer; } } .titleBox { text-align: center; background: #fff; color: #000000; position: absolute; top: 0; left: 50%; width: auto; } } } } </style>
以上就是“vue項(xiàng)目怎么實(shí)現(xiàn)前端預(yù)覽word與pdf格式文件”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家閱讀完這篇文章都有很大的收獲,小編每天都會(huì)為大家更新不同的知識(shí),如果還想學(xué)習(xí)更多的知識(shí),請(qǐng)關(guān)注億速云行業(yè)資訊頻道。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。