您好,登錄后才能下訂單哦!
今天小編給大家分享一下vue項目怎么實現前端預覽word與pdf格式文件的相關知識點,內容詳細,邏輯清晰,相信大部分人都還太了解這方面的知識,所以分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后有所收獲,下面我們一起來了解一下吧。
頁面上傳pdf文件效果如下:
頁面預覽pdf文件效果如下:
頁面上傳word文件效果如下:
頁面預覽word文件效果如下:
這里先從上傳組件頁面說起,上傳頁面組件完整代碼如下,按鈕里面v-show=“$checkPermission([‘Register_tuotpUpload’])“都是給這個按鈕設置了按鈕權限的,我們只需要關注上傳那一部分的代碼即可,我們用了el-upload組件實現的手動上傳,由于需求要求只能上傳word和pdf,所以能看到屬性設置的有 accept=”.pdf, .doc, .docx”,然后不展示上傳成功的文件的列表設置的屬性有:show-file-list=“false”,而handleExceed回調函數和limit都是為了限制只能上傳一個文件,上傳前的回調鉤子函數beforeAvatarUpload里進行了文件類型判斷與提醒,手動上傳是通過UploadFile里進行完成的,需要注意的是由于docx-preview這個插件只能預覽后綴為docx的word文件,如果是doc后綴格式的word文件一定要讓后端強制將上傳doc格式的文件改為docx格式,目前對于doc格式的word文件實現網頁在線預覽我只想到了docx-preview這個插件和這個解決辦法:
<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="請輸入鏈路名稱" 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="請選擇鏈路類型" 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="請選擇" 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="請選擇" :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="請輸入鏈路物理位置" clearable ></el-input> </el-form-item> </el-col> <el-col :span="12"> <el-form-item label="所屬機構" 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="行政區編碼" prop="organCode"> <el-input v-model="ruleForm.organCode" placeholder="請輸入行政區編碼,例:027" clearable ></el-input> </el-form-item> </el-col> <el-col :span="12"> <el-form-item label="責任人" prop="dutyPerson"> <el-input v-model="ruleForm.dutyPerson" placeholder="請輸入鏈路責任人" clearable ></el-input> </el-form-item> </el-col> <el-col :span="12"> <el-form-item label="責任人電話" prop="dutyTel"> <el-input v-model="ruleForm.dutyTel" placeholder="請輸入鏈路責任人電話" clearable ></el-input> </el-form-item> </el-col> </el-row> <el-row> <el-col :span="12"> <el-form-item label="公安網郵箱" prop="dutyEmail"> <el-input v-model="ruleForm.dutyEmail" placeholder="請輸入負責人公安網郵箱" 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="請輸入鏈路IP地址" clearable ></el-input> </el-form-item> </el-col> <el-col :span="12"> <el-form-item label="鏈路端口" prop="port"> <el-input-number placeholder="請輸入鏈路端口" 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="管理頁面" prop="webUrl"> <el-input v-model="ruleForm.webUrl" placeholder="請輸入鏈路管理頁面" 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">鏈路拓撲圖</div> <el-form :model="tuopuForm" ref="tuopuForm" label-width="120px"> <el-row> <el-col :span="12"> <el-form-item label="拓撲圖" prop="fileName"> <el-input v-model="tuopuForm.fileName" placeholder="請選擇電腦中拓撲圖文件" 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'])" > 預覽 </el-button> </el-col> </el-row> </el-form> </div> <div class="itemBox"> <div class="headerTitle">設備信息列表</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">鏈路注冊</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">已注冊</el-tag> <el-tag type="success" v-if="scope.rows.status == 0" >未注冊</el-tag > <el-tag type="danger" v-if="scope.rows.status == 2" >注冊失敗</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)" >注冊</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> <!-- 添加和編輯設備彈窗 --> <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> <!-- 鏈路注冊彈窗 --> <el-dialog title="鏈路注冊" :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("請輸入平臺IP地址"); // } else { // let index = value.indexOf("/"); // let findHengT = value.indexOf("-"); // let findHengP = value.indexOf("——"); // if (index > -1 || findHengT > -1 || findHengP > -1) { // callback("請輸入正確格式的平臺IP地址"); // } else { // validator.IpArea(rule, value, callback); // } // } if (!this.ruleForm.srcNetwork || !this.ruleForm.dstNetwork) { callback("請選擇鏈路走向"); } else { callback(); } }; return { ruleForm: { name: "", linkType: "", srcNetwork: "", dstNetwork: "", physicalPosition: "", orangeName: "", organCode: "", dutyPerson: "", dutyTel: "", dutyEmail: "", ip: "", port: undefined, webUrl: "" }, rules: { name: [{ required: true, message: "請輸入鏈路名稱", trigger: "blur" }], linkType: [ { required: true, message: "請選擇鏈路類型", trigger: "blur" } ], go: [ { required: true, message: "請選擇鏈路走向", trigger: "blur", validator: validateGo } ], physicalPosition: [ { required: false, message: "請輸入鏈路物理位置", trigger: "blur" } ], orangeName: [ { required: true, message: "請輸入所屬機構", trigger: "blur" } ], organCode: [ { required: true, message: "請輸入行政區編碼", trigger: "blur" } ], dutyPerson: [ { required: true, message: "請輸入鏈路責任人", trigger: "blur" } ], dutyTel: [ { required: true, message: "請輸入鏈路責任人電話", trigger: "blur" } ], dutyEmail: [ { required: false, message: "請輸入負責人公安網郵箱", trigger: "blur" } ], ip: [{ required: false, message: "請輸入鏈路IP地址", trigger: "blur" }], port: [{ required: true, message: "請輸入鏈路端口", trigger: "blur" }], webUrl: [ { required: false, message: "請輸入鏈路管理頁面", trigger: "blur" } ] }, linkTypeList: [], scrList: [], dstList: [], tuopuForm: { fileName: "", fileUrl: "" }, tableHead: [ { label: "設備名稱", prop: "name", type: "normal", sortable: false }, { label: "設備類型", prop: "devType", type: "normal", sortable: false // width: 150 }, { label: "廠商", prop: "manufacturer", type: "normal", sortable: false // width: 150 }, { label: "型號", prop: "model", type: "normal", sortable: false // width: 150 }, { label: "設備IP", prop: "devIp", type: "normal", sortable: false }, { label: "子網掩碼", prop: "ipMask", type: "normal", sortable: false // width: 150 }, { label: "網關", prop: "ipGaway", type: "normal", sortable: false // width: 150 }, { label: "安裝時間", prop: "installTime", type: "normal", sortable: false, width: 180 }, { label: "操作", prop: "doSomething", type: "slot", sortable: false, slotName: "doSomething", width: 220 } // { // label: "任務詳情", // 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: "編輯設備", Edit: "編輯設備", edit: "編輯設備", create: "添加設備" }, tableData: [], tableLoading: false, Register_tableHead: [ { label: "平臺名稱", prop: "name", type: "normal", sortable: false }, { label: "平臺IP地址", prop: "ip", type: "normal", sortable: false }, { label: "平臺端口", prop: "port", type: "normal", sortable: false }, { label: "平臺唯一標識", prop: "uniquePlatformCode", type: "normal", sortable: false }, { label: "注冊時間", prop: "lastTime", type: "normal", sortable: false, width: 180 }, { label: "注冊狀態", prop: "status", type: "slot", slotName: "status", sortable: false }, { label: "操作", prop: "doSomething", type: "slot", sortable: false, slotName: "doSomething", width: 220 } // { // label: "任務詳情", // 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, //拓撲圖文件列表 tuotpData: null, EquipmentList: [], originalList: [] }; }, created() { this.getNews(); }, methods: { getNews() { //獲取邊界信息 this.getBoundaryDetail(); //獲取拓撲圖 this.getTuotp(); //獲取設備列表 this.fetchData(); //獲取鏈路注冊列表 this.Register_fetchData(); //獲取公共下拉 this.getSelect(); }, saveForm() { this.$refs["ruleForm"].validate(valid => { if (valid) { let params = { ...this.ruleForm }; console.log("修改入參", 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("預覽", this.fileList, this.tuopuForm); if (!this.fileList) { this.$message.error( "拓撲圖文件為空不能預覽,請先上傳拓撲圖文件后再預覽", 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("設備類型下拉", 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 => {}); }, //獲取拓撲圖 getTuotp() { api .boundaryTuopoDetail() .then(res => { // console.log("獲取拓撲圖成功", res); this.tuopuForm = res.data; this.tuopuPreview(); }) .catch(err => { // console.log("獲取拓撲圖失敗", err); }); }, //獲取設備列表 fetchData() { this.tableLoading = true; api .equipmentList({ page: 1, page_size: 99999, ip: "" }) .then(res => { // console.log("設備列表", res); if (res.code == 200) { this.tableData = res.data.list; this.tableLoading = false; } }) .catch(err => {}); }, //編輯 handlerUpdate(row) { // console.log("點了修改", 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("基本信息為空不能添加,請先補充基本信息", 6000); } }); }, Register_handleClose() { this.Register_dialogFormVisible = false; }, Register_submitForm() { this.$refs["RegisterAdd"].submitForm(); }, //獲取鏈路注冊列表 Register_fetchData() { this.Register_tableLoading = true; api .registerList({ page: 1, page_size: 99999, ip: "" }) .then(res => { console.log("注冊列表", 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( `當前限制最多選擇1個文件上傳,本次選擇了${files.length}個文件` ); } }, //文件上傳前的鉤子 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: "上傳的拓撲圖文件只能是word、pdf格式,請重新上傳!", type: "error", duration: 6000 }); this.fileList = null; return false; } else { this.fileList = file; } }, //自定義上傳 UploadFile() { // 參數拼接 let fileData = new FormData(); fileData.append("file", this.fileList); // 調用接口 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; //拓撲預覽 this.tuopuPreview(); } else { console.log("上傳失敗1"); this.$message({ message: "上傳拓撲圖文件失敗,請稍后重試!", type: "error", duration: 6000 }); } }) .catch(err => { console.log("上傳失敗2", err); this.$message({ message: "上傳拓撲圖文件失敗,請稍后重試!", 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("拓撲預覽獲取成功", res); if (res.status == 200) { this.fileList = res.data; } }) .catch(err => { console.log("拓撲預覽失敗失敗", 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>
上傳功能實現之后,我們再看預覽功能。我們需求是點擊預覽按鈕之后跳到一個新頁面進行預覽,我先是對文件是否為空是否沒上傳進行了一個判斷攔截,由于預覽頁面組件與當前頁面組件既非父子關系,又非爺孫關系,八竿子打不著的關系,我們就不能通過綁定和sessionStorage來進行流文件的傳遞,只能在預覽頁面再發一次請求獲取文件流,我們可以把參數通過路由帶上,預覽按鈕對應的方法代碼如下:
preview() { console.log("預覽", this.fileList, this.tuopuForm); if (!this.fileList) { this.$message.error( "拓撲圖文件為空不能預覽,請先上傳拓撲圖文件后再預覽", 6000 ); return false; } this.$router.push({ path: "TuotpPreview", query: { fileName: this.tuopuForm.fileName, fileUrl: this.tuopuForm.fileUrl } }); }
再來看預覽頁面,也就是TuotpPreview.vue組件。word預覽比較簡單,先通過命令cnpm i docx-preview --save安裝插件docx-preview,需要注意的是這個插件只能預覽后綴為docx的word文件,如果是doc后綴格式的word文件一定要讓后端強制將上傳doc格式的文件改為docx格式,然后當前頁面組件就直接import { defaultOptions, renderAsync } from “docx-preview”;引入,最后在data里進行docxOptions配置,然后在頁面上 要顯示的div上綁定一個 id="bodyContainer"的,因為下面要通過document.getElementById來獲取dom并操作dom,最后調用renderAsync方法即可。
cnpm i docx-preview --save //安裝word預覽插件docx-preview import { defaultOptions, renderAsync } from "docx-preview"; //引入docx-preview插件對應的方法 docxOptions: { className: "kaimo-docx-666", // string:默認和文檔樣式類的類名/前綴 inWrapper: true, // boolean:啟用圍繞文檔內容的包裝器渲染 ignoreWidth: false, // boolean:禁用頁面的渲染寬度 ignoreHeight: false, // boolean:禁止渲染頁面高度 ignoreFonts: false, // boolean:禁用字體渲染 breakPages: true, // boolean:在分頁符上啟用分頁 ignoreLastRenderedPageBreak: true, // boolean:在 lastRenderedPageBreak 元素上禁用分頁 experimental: false, // boolean:啟用實驗功能(制表符停止計算) trimXmlDeclaration: true, // boolean:如果為true,解析前會從 xml 文檔中移除 xml 聲明 useBase64URL: false, // boolean:如果為true,圖片、字體等會轉為base 64 URL,否則使用URL.createObjectURL useMathMLPolyfill: false, // boolean:包括用于 chrome、edge 等的 MathML polyfill。 showChanges: false, // boolean:啟用文檔更改的實驗性渲染(插入/刪除) debug: false // boolean:啟用額外的日志記錄 },
pdf文件的預覽是通過獲取到blob文件流之后,直接通過window.open打開新窗口,通過瀏覽器就能預覽pdf,還有一種就是我現在的這種需求,要在頁面上預覽pdf,那就需要通過iframe,然后把blob流對應的src地址賦值回顯即可。完整代碼如下:
<template> <div> <!-- 拓撲圖預覽 --> <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:默認和文檔樣式類的類名/前綴 inWrapper: true, // boolean:啟用圍繞文檔內容的包裝器渲染 ignoreWidth: false, // boolean:禁用頁面的渲染寬度 ignoreHeight: false, // boolean:禁止渲染頁面高度 ignoreFonts: false, // boolean:禁用字體渲染 breakPages: true, // boolean:在分頁符上啟用分頁 ignoreLastRenderedPageBreak: true, // boolean:在 lastRenderedPageBreak 元素上禁用分頁 experimental: false, // boolean:啟用實驗功能(制表符停止計算) trimXmlDeclaration: true, // boolean:如果為true,解析前會從 xml 文檔中移除 xml 聲明 useBase64URL: false, // boolean:如果為true,圖片、字體等會轉為base 64 URL,否則使用URL.createObjectURL useMathMLPolyfill: false, // boolean:包括用于 chrome、edge 等的 MathML polyfill。 showChanges: false, // boolean:啟用文檔更改的實驗性渲染(插入/刪除) debug: false // boolean:啟用額外的日志記錄 }, 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("獲取文件信息失敗,請稍后重試", 6000); }); }, //重置標題 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文檔預覽 wordPreview(buffer) { console.log("文檔buffer", buffer); let bodyContainer = document.getElementById("bodyContainer"); renderAsync( buffer, // Blob | ArrayBuffer | Uint8Array, 可以是 JSZip.loadAsync 支持的任何類型 bodyContainer, // HTMLElement 渲染文檔內容的元素, null, // HTMLElement, 用于呈現文檔樣式、數字、字體的元素。如果為 null,則將使用 bodyContainer。 this.docxOptions // 配置 ) .then(res => { console.log("res---->", res); }) .catch(err => { console.log("err---->", err); }); }, //pdf預覽 pdfPreview(data) { // data是一個ArrayBuffer格式,也是一個buffer流的數據 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); 這種方式是直接打開新瀏覽器窗口預覽 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項目怎么實現前端預覽word與pdf格式文件”這篇文章的所有內容,感謝各位的閱讀!相信大家閱讀完這篇文章都有很大的收獲,小編每天都會為大家更新不同的知識,如果還想學習更多的知識,請關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。