news 2026/9/10 16:49:10

vue 在线预览 word ,Excel,pdf,图片 数据流 内网文件流 亲测有效(word 目前支持docx文件以及doc文件(doc需要后端处理))

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
vue 在线预览 word ,Excel,pdf,图片 数据流 内网文件流 亲测有效(word 目前支持docx文件以及doc文件(doc需要后端处理))

注:doc转 docx后端转数据流 谷歌 114 版本以上会解析错误!

如果是需要更好的体验:可以使用 kkFileView - 在线文件预览

需要后端在服务器部署一个服务 之后返回地址前端进行直接在线访问;(支持内网哦)

需求:在线预览文件(doc,docx,xls,xlsx,img,pdf)其他类型下载

如果你要是公网 那直接参考在线office 引入url地址 直接预览(本文是返回数据流 不是公网)

效果图:

xls :代码效果

xls:office效果

doc :代码效果

doc :office效果

pdf 效果

图片效果

pdf 直接用的浏览器自带的

excel 插件 xlsx

docx 插件 docx-preview

npm install xlsx --save npm install docx-preview --save

也是查阅了好多东西也借鉴了许多人的代码,亲测有效! 拿过去换地址 直接就能用

html 代码

<template> <div class="viewItemFile"> <!-- 预览文件 --> <el-dialog width="100%" class="viewItemFileDialog" title="预 览" :visible.sync="dialogVisible" :before-close="innerhandleClose" :close-on-click-modal="false" :close-on-press-escape="false" > //判断类型 <div class="image" v-if="type == 'image'"> <div> <el-image :src="imgUrl" :preview-src-list="srcList"> </el-image> </div> </div> <div class="docWrap" v-if="type == 'doc'"> <!-- 预览文件的地方(用于渲染) --> <div ref="file"></div> </div> <div v-if="type == 'xls'"> <div class="excel-view-container"> <div id="excelView" v-html="excelView"></div> </div> </div> // pdf用嵌套的iframe <div v-if="type == 'pdf'"> <iframe :src="pdfurl" type="application/x-google-chrome-pdf" width="100%" height="100%" /> </div> </el-dialog> </div> </template>

script

methods:{ // 前一个页面调用的init 我在前一个页面根据文件名字后缀已经判断是什么类型的文件了 init(file, type) { this.type = type; if (type == "image") { axios .request({ method: "GET", //这个不解释了吧 url: '后端接口', //路径 responseType: "blob", //告诉服务器想到的响应格式 headers: { Accept: "application/octet-stream", }, }) .then((res) => { console.log(res); if (res) { let blob = new Blob([res.data], { type: "image/jpeg" }); const imageUrl = URL.createObjectURL(blob); this.imgUrl = imageUrl; this.srcList = [imageUrl],; that.loading = true; } else { that.$notify.error({ title: "失败", message: "接口请求失败" }); that.loading = false; } }) .catch(function (error) { that.$notify.error({ title: "失败", message: "接口请求失败" }); console.log(error); that.loading = false; }); } else if (type == "pdf") { axios .request({ method: "GET", //这个不解释了吧 url: '后端地址'//路径 responseType: "blob", //告诉服务器想到的响应格式 headers: { "Content-Type": "application/pdf;charset=UTF-8", }, }) .then((res) => { console.log(res); if (res) { let blob = new Blob([res.data], { type: "application/pdf" }); const url = URL.createObjectURL(blob); console.log(url); that.loading = false; this.pdfurl = url; } else { that.$notify.error({ title: "失败", message: "接口请求失败" }); that.loading = false; } }) .catch(function (error) { that.$notify.error({ title: "失败", message: "接口请求失败" }); console.log(error); that.loading = false; }); } else if (type == "xls") { //表格 var that = this; axios .request({ method: "GET", //这个不解释了吧 url: '后端地址', //路径 responseType: "arraybuffer", //告诉服务器想到的响应格式 headers: { "Content-Type": "application/vnd.ms-excel;application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", }, }) .then((res) => { console.log(res); if (res) { const workbook = XLSX.read(new Uint8Array(res.data), { type: "array", }); // 解析数据 const worksheet = workbook.Sheets[workbook.SheetNames[0]]; // workbook.SheetNames 下存的是该文件每个工作表名字,这里取出第一个工作表 this.excelView = XLSX.utils.sheet_to_html(worksheet); // 渲染 this.$nextTick(function () { // DOM加载完毕后执行,解决HTMLConnection有内容但是length为0问题。 this.setStyle4ExcelHtml(); }); } else { that.$notify.error({ title: "失败", message: "接口请求失败" }); that.loading = false; } }) .catch(function (error) { that.$notify.error({ title: "失败", message: "接口请求失败" }); console.log(error); that.loading = false; }); } else if (type == "doc") { // word var that = this; axios .request({ method: "GET", //这个不解释了吧 url: '后端地址' //路径 responseType: "blob", //告诉服务器想到的响应格式 }) .then((res) => { console.log(res); if (res) { let docx = require("docx-preview"); docx.renderAsync(res.data, this.$refs.file); } else { that.$notify.error({ title: "失败", message: "接口请求失败" }); that.loading = false; } }) .catch(function (error) { that.$notify.error({ title: "失败", message: "接口请求失败" }); console.log(error); that.loading = false; }); } this.dialogVisible = true; }, // 设置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"); } if (idNum && (idNum === "2" || idNum === 2)) { // 第二行表头行 excelViewTDArr[i].classList.add("class4TableTh"); } } } } } }, }

css 有需要的 自行添加

<style lang="scss" scoped> .viewItemFile { .image { width: 100%; height: 100%; display: flex; align-items: center; justify-content: center; div { height: 600px; width: 600px; } } .divContent { display: flex; align-items: center; justify-content: center; } /deep/ .el-dialog { margin: 0 !important; height: 100vh !important; .el-dialog__footer { margin-bottom: 30px; padding: 0px; } } /deep/ .el-dialog__body { height: 96%; width: 100%; padding: 0; overflow: auto; } } .viewItemFile { /deep/ table { width: 100% !important; border-collapse: collapse !important; border-spacing: 0 !important; text-align: center !important; border: 0px !important; overflow-x: auto !important; } /deep/ table tr td { /* border: 1px solid gray !important; */ border-right: 1px solid gray !important; border-bottom: 1px solid gray !important; width: 300px !important; height: 33px !important; } /**整体样式 */ /deep/ .excel-view-container { background-color: #ffffff; } /**标题样式 */ /deep/ .class4Title { font-size: 22px !important; font-weight: bold !important; padding: 10px !important; } /**表格表头样式 */ /deep/ .class4TableTh { /* font-size: 14px !important; */ font-weight: bold !important; padding: 2px !important; background-color: #ccc !important; } } </style> <style lang="scss"> .viewItemFileDialog { overflow: hidden; .el-dialog__header { padding: 10px 20px 10px; background-color: #19a199; } .el-dialog__header .el-dialog__title { font-size: 15px; color: #ffffff; font-weight: 700; } .dialog-footer { display: flex; justify-content: center; } .search-btn { background: #19a8a6; color: white; border: none; height: 30px; padding: 0px 20px; } .el-dialog__headerbtn .el-dialog__close { color: #ffffff; } .well { display: block; background-color: #f2f2f2; border: 1px solid #ccc; margin: 0px; width: 100%; height: 100%; overflow: auto; } } </style>

文件流

excel 文件流 其他的就不都发了

doc 文件需要后端转成docx文件流返回 之后直接用docx插件搞定!

参考地址:java doc转docx

xls 引用之处

doc 引用之处

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/10 16:48:25

【148+279+48+192倒计时8路抢答器2023年6月5日16:52:31】

缘由https://ask.csdn.net/questions/7957804/54226107 八路抢答器设计时&#xff0c;倒计时数字不动&#xff0c;只能显示0&#xff0c;无法自主变动。 看我的仿真运行图&#xff0c;图中各逻辑&#xff0c;不赘述。 須菩提白佛言&#xff1a;「世尊&#xff01;若一切法一切…

作者头像 李华
网站建设 2026/9/10 16:44:49

SEO优化常见误区与实战避坑指南

1. SEO优化中的常见误区与避坑指南 在互联网营销领域&#xff0c;SEO&#xff08;搜索引擎优化&#xff09;始终是获取自然流量的核心手段。从业15年来&#xff0c;我见证了无数网站因为基础SEO错误而浪费大量预算&#xff0c;也帮助不少企业通过纠正简单误区实现了流量翻倍。今…

作者头像 李华
网站建设 2026/9/10 16:43:52

Python处理TXT文件:从基础读写到高级应用

1. Python与TXT文件操作全指南作为一名长期使用Python处理文本数据的开发者&#xff0c;我经常需要与TXT文件打交道。无论是数据清洗、日志分析还是简单的文本处理&#xff0c;TXT文件都是最基础也最常用的格式之一。今天我就来分享Python处理TXT文件的完整方案&#xff0c;从基…

作者头像 李华