最近做的项目要求实现预览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 上传组件
<el-upload
class="upload-demo"
action=""
:http-request="myUpload"
:show-file-list="false"
>
<span class = "uploadEnclosure">上传附件</span>
</el-upload>
选择文件以后
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 = downUrl
a.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转为buffer
let 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",
});
}
}
// 渲染docx
docxRender(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) {
// 看支持不支持FileReader
if (!file || !window.FileReader) return;
// console.log(/^image/.test(file.type), "---/^image/.test(file.type)")
if (/^image/.test(file.type)) {
// 创建一个reader
let 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/
最后是一个好友赠送的组件
<template>
<div class="docx-preview-wrap">
<h4>
<input type="file" id="file" accept=".docx" @change="getFile"/>
</h4>
<div id="bodyContainer"></div>
</div>
</template>
<script>
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.createObjectURL
useMathMLPolyfill: 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转为buffer
let fr = new FileReader();
fr.readAsArrayBuffer(file);
fr.addEventListener("loadend",(e) => {
console.log("loadend---->", e)
let buffer = e.target.result;
this.docxRender(buffer);
},false);
},
// 渲染docx
docxRender(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)
})
}
},
};
</script>
结束啦,每天进步一点点,早日成为大神。啦啦啦
我看到这个错误:translationmissing:da.datetime.distance_in_words.about_x_hours我的语言环境文件:http://pastie.org/2944890我的看法:我已将其添加到我的application.rb中:config.i18n.load_path+=Dir[Rails.root.join('my','locales','*.{rb,yml}').to_s]config.i18n.default_locale=:da如果我删除I18配置,帮助程序会处理英语。更新:我在config/enviorments/devolpment
项目介绍随着我国经济迅速发展,人们对手机的需求越来越大,各种手机软件也都在被广泛应用,但是对于手机进行数据信息管理,对于手机的各种软件也是备受用户的喜爱小学生兴趣延时班预约小程序的设计与开发被用户普遍使用,为方便用户能够可以随时进行小学生兴趣延时班预约小程序的设计与开发的数据信息管理,特开发了小程序的设计与开发的管理系统。小学生兴趣延时班预约小程序的设计与开发的开发利用现有的成熟技术参考,以源代码为模板,分析功能调整与小学生兴趣延时班预约小程序的设计与开发的实际需求相结合,讨论了小学生兴趣延时班预约小程序的设计与开发的使用。开发环境开发说明:前端使用微信微信小程序开发工具:后端使用ssm:VU
参考文章搭建文章gitte源码在线体验可以注册两个号来测试演示图:一.整体介绍 介绍SignalR一种通讯模型Hub(中心模型,或者叫集线器模型),调用这个模型写好的方法,去发送消息。 内容有: ①:Hub模型的方法介绍 ②:服务器端代码介绍 ③:前端vue3安装并调用后端方法 ④:聊天室样例整体流程:1、进入网站->调用连接SignalR的方法2、与好友发送消息->调用SignalR的自定义方法 前端通过,signalR内置方法.invoke() 去请求接口3、监听接受方法(渲染消息)通过new signalR.HubConnectionBuilder().on
我在我的机器上安装了ruby版本1.9.3,并且正在为我的个人网站开发一个octopress项目。我为我的gems使用了rvm,并遵循了octopress.org记录的所有步骤。但是我在我的rake服务器中发现了一些错误。这是我的命令日志。Tin-Aung-Linn:octopresstal$ruby--versionruby1.9.3p448(2013-06-27revision41675)[x86_64-darwin12.4.0]Tin-Aung-Linn:octopresstal$rakegenerate##GeneratingSitewithJekyllidenticals
我正在使用Rails5。我想从Word文档(.doc)中获取文本,所以我正在使用这段代码text=nilMSWordDoc::Extractor.load(file_location)do|ctl00_MainContent_List1_grdData|text=contents.whole_contentsend但我收到以下错误。我的Gemfile中有这个gemgem'msworddoc-extractor'我还需要做什么才能从Word文档中获取内容?如果我可以像对.doc文件一样对.docx文件应用相同的代码,那就太好了。/Users/davea/.rvm/gems/ruby-2.
平时开发中我们经常会遇到这样的需求,在一个不限高度的盒子中会有很多内容,如果全部显示用户体验会非常不好,所以可以先折叠起来,当内容达到一定高度时,显示展开更多按钮,点击即可显示全部内容,先来看看效果图: 这样做用户体验瞬间得到提升,接下来看看具体细节。0">主要操作在内容这里{{item.username}},……展开更多样式大家可依据自己项目需求进行设计,这里就不贴了,主要说几个关键的。1、在data中定义三个属性isShowMore:false, //控制展开更多的显示与隐藏textHeight:null, //框中内容的高度status:false, //内容状态是否打开2.计算内容是否
这里写自定义目录标题一、问题二、解决三、解决方案四、打包预览一、问题在使用vue3.2和vite2开发一个移动端或者钉钉端H5微服务iosapp内置浏览器打开没问题安卓app内置浏览器打开空白页面vconsole打印出现报错globalthisundefind二、解决内置浏览器版本比较低打印出来是63vue3代码不兼容低版本浏览器三、解决方案步骤一:vite.config.ts里build.target配置项指定构建目标为es2015或者步骤二:安装@vitejs/plugin-legacy安装完报错也还在指定版本可以解决“@vitejs/plugin-legacy”:“1.8.0”,步骤三:
我遵循了OctopressDocumentation中的所有说明:sddhrthrt@thinkpad:~/octopress$rakegenerate##GeneratingSitewithJekylldirectorysource/stylesheets/createsource/stylesheets/screen.cssConfigurationfrom/home/sddhrthrt/octopress/_config.yml/home/sddhrthrt/octopress/plugins/pygments_code.rb:5:warning:alreadyinitializ
我正在尝试将像Presentationabout"TestDrivenDevelopment"这样的字符串拆分成这样的数组:['Presentation','about','"BehaviorDrivenDevelopment"']我已经尝试过CSV::parse_line(string,col_sep:''),但这会导致['Presentation','about','BehaviorDrivenDevelopment']#I'mmissingthequoteshere我也尝试了一些正则表达式魔术,但我还是个初学者,没有成功。我想这对于专业人士来说很简单,所以也许有人可以指出我正确的
Vue3的新特性包括:CompositionAPI:一种新的API风格,可将有关组件功能的代码逻辑封装在单独的函数中,从而更好地管理和重用代码。Teleport:可以让组件在DOM层次结构中的任何位置渲染。Suspense:一种新的异步渲染模式,可以优化应用程序的性能。更快的渲染速度:Vue3使用了新的虚拟DOM算法,并且对渲染过程进行了优化,因此在渲染大型应用时性能更高。更小的包大小:Vue3的打包大小比Vue2更小,因为它不再需要依赖像vue-template-compiler这样的工具。其他改进:Vue3还具有其他一些改进,例如更好的TypeScript支持、更好的错误提示和更好的调试工