最近做的项目要求实现预览word, pdf,png等文件功能,pdf以及png都很简单,轻松百度搞定,但是word预览研究了好久,所以特此记录分享。

前端实现预览word分为两种,一种是上传前预览(也就是前端使用input或者组件等选择文件后直接预览,此时还没有上传给后端,我定义为纯前端预览),一种是上传后预览(就是文档已经上传到后端,通过后端给的文件流实现预览)

一、先说第一种的实现方式:

首先下载安装docx-preview,引入

npm install xlsx docx-preview --save
import { defaultOptions, renderAsync } from "docx-preview";var docxx = require("docx-preview");

我这里使用的是element ui 上传组件

 上传附件

选择文件以后

myUpload(content){console.log(content);const downUrl = URL.createObjectURL(content.file)const a = document.createElement('a');this.$refs.selectFileNameBox.innerHTML = "";this.$refs.selectFileNameBox.append(a);a.innerHTML = content.file.name;a.href = downUrla.download = content.file.name;a.target = '_blank';const addTypeArray = content.file.name.split(".");const addType = addTypeArray[addTypeArray.length - 1];console.log(addType);this.uploadFileName = content.file.name;this.uploadFileObj = content.file;if (addType === "pdf") {const url = URL.createObjectURL(content.file);console.log(url);this.xzbjPreviewIframeSrc = url;this.xzbjIframeIsShow = true;this.xzbjDialogPreviewDiv = false;this.xzbjPreviewImgUrl = "";this.xzbjDocPreviewFlag = false; this.previewBoxStyle = "height:400px;position: relative;overflow:hidden;"}else if(addType === "doc" || addType === "docx" || addType === "word"){console.log("word文件预览")this.xzbjPreviewImgUrl = "";this.xzbjPreviewIframeSrc = "";this.xzbjDialogPreviewDiv = false;this.xzbjDocPreviewFlag = true;this.xzbjIframeIsShow = false;// 将file转为bufferlet fr = new FileReader();fr.readAsArrayBuffer(content.file);fr.addEventListener("loadend",(e) => {console.log("loadend---->", e)let buffer = e.target.result;this.docxRender(buffer);},false);}//".rar, .zip, .doc, .docx, .xls, .txt, .pdf, .jpg,.png, .jpeg,"else if (["png", "jpg", "jpeg","bmp"].includes(addType)) {this.xzbjPreviewIframeSrc = "";this.xzbjIframeIsShow = false;this.xzbjDocPreviewFlag = false;this.imgPreview(content.file);this.previewBoxStyle = "height:400px;position: relative;overflow:auto;"} else if (addType === "rar" || addType === "zip" || addType === "7z") {this.filePreviewInfo = "请下载附件进行查看"this.xzbjPreviewImgUrl = "";this.xzbjPreviewIframeSrc = "";this.xzbjDocPreviewFlag = false;this.xzbjDialogPreviewDiv = true;this.$message({message: "该文件类型暂不支持预览",type: "warning",});return false;}else{this.filePreviewInfo = "该文件类型暂不支持预览"this.xzbjPreviewIframeSrc = "";this.xzbjIframeIsShow = false;this.xzbjDialogPreviewDiv = true;this.xzbjPreviewImgUrl = "";this.xzbjDocPreviewFlag = false;this.$message({message: "请仅允许上传后缀为pdf、doc、docx、word、jpg、png、bmp、rar、zip、7z的附件",type: "warning",});}}
// 渲染docxdocxRender(buffer) {let bodyContainer = document.getElementById("demoDocContainer");renderAsync(buffer, // Blob | ArrayBuffer | Uint8Array, 可以是 JSZip.loadAsync 支持的任何类型bodyContainer, // HTMLElement 渲染文档内容的元素,null, // HTMLElement, 用于呈现文档样式、数字、字体的元素。如果为 null,则将使用 bodyContainer。this.docxOptions // 配置).then(res => {console.log("res---->", res)})},

下面是图片预览核心代码

 imgPreview(file) {// 看支持不支持FileReaderif (!file || !window.FileReader) return;// console.log(/^image/.test(file.type), "---/^image/.test(file.type)")if (/^image/.test(file.type)) {// 创建一个readerlet reader = new FileReader();// 将图片将转成 base64 格式reader.readAsDataURL(file);// 读取成功后的回调reader.onload = ({ target }) => {this.xzbjDialogPreviewDiv = false;this.xzbjPreviewImgUrl = target.result; //将img转化为二进制数据// console.log("target:", target);};}},

这样就实现了纯前端预览word功能

二、接下来实现 配合后端预览word

根据后端返回的流预览word

request({method: "get",url: "/notice/noticeFileView",responseType: 'blob',params:{id:row.id},headers: {"Content-Type": 'application/json'},}).then(res=>{console.log(res,"---文件预览");if(row.suffix.includes("pdf")){this.previewPdfFn(res);// let blob = new Blob([res],{// type: 'application/pdf'// })// let url = window.URL.createObjectURL(blob);this.xqPreviewImgUrl ="";this.xqPreviewPdfUrl = this.previewPdfFn(res);this.xqPdfPreviewFlag = true; this.xqDocPreviewFlag = false;this.xqPerviewStyle = "height:600px;position: relative;overflow:hidden"}else if(row.suffix.includes("docx") || row.suffix.includes("doc")|| row.suffix.includes("word")){console.log("预览word")this.xqDocPreviewFlag = true;let blob = new Blob([res],{type: 'application/pdf'})this.$nextTick(()=>{console.log(this.$refs.xqDocContainer,"---this.$refs.xqDocContainer")docxx.renderAsync(blob, this.$refs.xqDocContainer)})} else if (row.suffix === ".rar" || row.suffix === ".zip" || row.suffix === "7z") {this.xqDocPreviewFlag = false;this.xzbjPreviewImgUrl = "";this.xzbjPreviewIframeSrc = "";this.$message({message: "该文件类型暂不支持预览",type: "warning",});return false;}else if([".png", ".jpg", ".jpeg",".bmp"].includes(row.suffix)){let blob = new Blob([res],{type: 'application/pdf'})console.log(blob,"---blob")let url = window.URL.createObjectURL(blob);this.xqPreviewImgUrl =url; this.xqPdfPreviewFlag = false; this.xqDocPreviewFlag = false;this.xqPreviewPdfUrl = "";this.xqPerviewStyle = "height:600px;position: relative;overflow:auto"}this.xqDialogPreviewDiv = false;}).catch(err=>{console.log(err,"--文件预览失败")})

完毕

下面是参考链接:

https://www.jianshu.com/p/8e1e90570c52 预览word excel

https://blog.csdn.net/kaimo313/article/details/127012225 vue里使用docx-preview预览docx文件

https://volodymyrbaydalka.github.io/docxjs/

最后是一个好友赠送的组件

import { defaultOptions, renderAsync } from "docx-preview";console.log(defaultOptions);export default {name: 'DocxPreview',data () {return {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.createObjectURLuseMathMLPolyfill: false, // boolean:包括用于 chrome、edge 等的 MathML polyfill。showChanges: false, // boolean:启用文档更改的实验性渲染(插入/删除)debug: false, // boolean:启用额外的日志记录}};},methods: {getFile(){this.handlePreview()},handlePreview() {let file = document.getElementById("file").files[0];console.log(file);// 将file转为bufferlet fr = new FileReader();fr.readAsArrayBuffer(file);fr.addEventListener("loadend",(e) => {console.log("loadend---->", e)let buffer = e.target.result;this.docxRender(buffer);},false);},// 渲染docxdocxRender(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)})}},};

结束啦,每天进步一点点,早日成为大神。啦啦啦