vue项目中实现doc/excel/pdf/txt/图片等文件的预览
word预览
1. 使用vue-office-docx(只支持docx文件预览,不支持doc文件)
支持文档网络地址(https://***.docx)。
文件上传时预览,此时可以获取文件的ArrayBuffer或二进制文件预览Blob。
javascript
// docx文档预览组件
npm install @vue-office/docx vue-demi@0.13.11
// 如果是vue2.6版本或以下还需要额外安装 @vue/composition-api
npm install @vue/composition-api/
<template>
<vue-office-docx :src="docx" style="height: 100vh;" @rendered="rendered" />
</template>
<script>
//引入VueOfficeDocx组件
import VueOfficeDocx from '@vue-office/docx'
//引入相关样式
import '@vue-office/docx/lib/index.css'
export default {
components:{
VueOfficeDocx
},
data(){
return {
docx: 'http://static.shanhuxueyuan.com/test6.docx' //设置文档网络地址,可以是相对地址
}
},
methods:{
rendered(){
console.log("渲染完成")
}
}
}
</script>
2. 使用docx-preview
javascript
npm install docx-preview
import { renderAsync } from 'docx-preview';
// 调用函数,解析docx文件
renderAsync(res.data, document.getElementById("preload_box"), null, {
className: "docx", // 默认和文档样式类的类名/前缀
inWrapper: true, // 启用围绕文档内容渲染包装器
ignoreWidth: false, // 禁止页面渲染宽度
ignoreHeight: false, // 禁止页面渲染高度
ignoreFonts: false, // 禁止字体渲染
breakPages: true, // 在分页符上启用分页
ignoreLastRenderedPageBreak: true, //禁用lastRenderedPageBreak元素的分页
experimental: false, //启用实验性功能(制表符停止计算)
trimXmlDeclaration: true, //如果为真,xml声明将在解析之前从xml文档中删除
debug: false, // 启用额外的日志记录
})
3. 使用mammoth.js
javascript
npm install --save mammoth
import mammoth from "mammoth";
<div ref='docpreview'></div>
mammoth.convertToHtml({path: "path/to/document.docx"})
.then(function(result){
var html = result.value; // The generated HTML
this.$refs.docpreview.innerHTML = html
})
.catch(function(error) {
console.error(error);
});
4. 使用微软的Office Web Viewer
使用iframe作为载体。
文件会传输到微软的服务器上,因此可能会涉及到文件隐私。
不需要安装 Office 软件,直接通过浏览器在线预览 docx、xlsx、pptx 文件。
不支持 pdf 预览。
javascript
<iframe class="previewOffice" :src="officeUrl"></iframe>
const url = 'https:***/demo.pdf'
this.officeUrl = `https://view.officeapps.live.com/op/view.aspx?src=${url}`
5. 第三方服务接口地址:XDOC文档预览服务(需要windows的部署环境,且预览效果不是很美观)
excel预览
1. 使用vue-office-excel(只支持xlsx文件预览,不支持xls文件)
支持文档网络地址(https://***.xlsx)。
文件上传时预览,此时可以获取文件的ArrayBuffer或二进制文件预览Blob。
javascript
// excel文档预览组件
npm install @vue-office/excel vue-demi@0.13.11
// 如果是vue2.6版本或以下还需要额外安装 @vue/composition-api
npm install @vue/composition-api/
<template>
<vue-office-excel :src="excel" style="height: 100vh;" @rendered="renderedHandler" @error="errorHandler" />
</template>
<script>
//引入VueOfficeExcel组件
import VueOfficeExcel from '@vue-office/excel'
//引入相关样式
import '@vue-office/excel/lib/index.css'
export default {
components: {
VueOfficeExcel
},
data() {
return {
excel: 'http://static.shanhuxueyuan.com/demo/excel.xlsx'//设置文档地址
}
},
methods: {
renderedHandler() {
console.log("渲染完成")
},
errorHandler() {
console.log("渲染失败")
}
}
}
</script>
2. 使用xlsx/sheetjs(需要自己排版)
xlsx插件只是帮助解析excel表中的数据,并不会进行排版,所以需要自己写样式重新排列数据。
javascript
npm install xlsx
import * as XLSX from 'xlsx/xlsx.mjs'
<el-table :data="excelData" style="width: 100%">
<el-table-column
v-for="(value, key, index) in excelData[0]"
:key="index"
:prop="key"
:label="key"
></el-table-column>
</el-table>
const xlsx_data = await res.data.arrayBuffer()
let tem_workbook = XLSX.read(xlsx_data, {type:"array"}); // 解析数据
workbook.value = tem_workbook
getTable(tem_workbook.SheetNames[0]); // 读取第一张表数据
// 解析xlsx数据为table
function getTable(sheetName) {
let worksheet = workbook.value.Sheets[sheetName];
excelData.value = XLSX.utils.sheet_to_json(worksheet);
}
3. 使用SpreadJS
4.使用luckysheet(支持在线编辑,目前只支持xlsx格式)
javascript
// 在inde.html文件中引入
<link rel='stylesheet' href='https://cdn.jsdelivr.net/npm/luckysheet@latest/dist/plugins/css/pluginsCss.css' />
<link rel='stylesheet' href='https://cdn.jsdelivr.net/npm/luckysheet@latest/dist/plugins/plugins.css' />
<link rel='stylesheet' href='https://cdn.jsdelivr.net/npm/luckysheet@latest/dist/css/luckysheet.css' />
<link rel='stylesheet' href='https://cdn.jsdelivr.net/npm/luckysheet@latest/dist/assets/iconfont/iconfont.css' />
<script src="https://cdn.jsdelivr.net/npm/luckysheet@latest/dist/plugins/js/plugin.js"></script>
<script src="https://cdn.jsdelivr.net/npm/luckysheet@latest/dist/luckysheet.umd.js"></script>
<div id="luckysheet" style="margin:0px;padding:0px;position:absolute;width:100%;height:100%;left: 0px;top: 0px;"></div>
mounted() {
this.initLuckysheet()
},
methods: {
initLuckysheet() {
$(function() {
// 配置项
var options = {
container: 'luckysheet', // luckysheet为容器id
showinfobar: false, // 信息栏
lang: 'zh'// 设定表格语言
// loadUrl:''
}
luckysheet.create(options)
})
},
}
pdf预览
1. 使用vue-office-pdf
支持文档网络地址(https://***.docx)。
文件上传时预览,此时可以获取文件的ArrayBuffer或二进制文件预览Blob。
javascript
// pdf文档预览组件
npm install @vue-office/pdf vue-demi@0.13.11
// 如果是vue2.6版本或以下还需要额外安装 @vue/composition-api
npm install @vue/composition-api/
<template>
<vue-office-pdf :src="pdf" @rendered="renderedHandler" @error="errorHandler" />
</template>
<script>
//引入VueOfficePdf组件
import VueOfficePdf from '@vue-office/pdf'
export default {
components: {
VueOfficePdf
},
data() {
return {
pdf: 'http://static.shanhuxueyuan.com/test.pdf' //设置文档地址
}
},
methods: {
renderedHandler() {
console.log("渲染完成")
},
errorHandler() {
console.log("渲染失败")
}
}
}
</script>
2. 使用pdf-dist
为了正确解析pdf,将pdf文件流转化为一个blob的地址去被解析器读取。由于插件每次只能查询pdf文件一页数据,所以需要额外编写翻页的逻辑代码。被pdf渲染的元素pdf_canvas必须是canvas标签。
javascript
npm install pdfjs-dist
import * as PDFJS from "pdfjs-dist/legacy/build/pdf"; // 引入PDFJS
import pdfjsWorker from "pdfjs-dist/legacy/build/pdf.worker.entry.js"; // 引入workerSrc的地址
// 调用函数,解析pdf文件
const blobPdf = new window.Blob([res.data], { type: 'application/pdf;chaset-UTF-8' })
const pdfhref = URL.createObjectURL(blobPdf);
PDFJS.getDocument(pdfhref).promise.then(pdfDoc=>{
const numPages = pdfDoc.numPages; // pdf的总页数
// 获取第1页的数据
pdfDoc.getPage(1).then(page =>{
// 设置canvas相关的属性
const canvas = document.getElementById("pdf_canvas");
const ctx = canvas.getContext("2d");
const dpr = window.devicePixelRatio || 1;
const bsr =
ctx.webkitBackingStorePixelRatio ||
ctx.mozBackingStorePixelRatio ||
ctx.msBackingStorePixelRatio ||
ctx.oBackingStorePixelRatio ||
ctx.backingStorePixelRatio ||
1;
const ratio = dpr / bsr;
const viewport = page.getViewport({ scale: 1 });
canvas.width = viewport.width * ratio;
canvas.height = viewport.height * ratio;
canvas.style.width = viewport.width + "px";
canvas.style.height = viewport.height + "px";
ctx.setTransform(ratio, 0, 0, ratio, 0, 0);
const renderContext = {
canvasContext: ctx,
viewport: viewport,
};
// 数据渲染到canvas画布上
page.render(renderContext);
})
})
// 切换pdf页数
function changePdfPage (type) {
if (type == 'pre') {
if (pdfPage.value <= 1) {
ElMessage.error('没有上一页了');
return
}
pdfPage.value -= 1
} else {
if (pdfPage.value >= pdfValue.numPages) {
ElMessage.error('没有下一页了');
return
}
pdfPage.value += 1
}
initPdfPage()
}
// 重新初始化pdf对应页数
function initPdfPage () {
pdfValue.getPage(pdfPage.value).then(page =>{
// 设置canvas相关的属性
const canvas = document.getElementById("pdf_canvas");
const ctx = canvas.getContext("2d");
const dpr = window.devicePixelRatio || 1;
const bsr =
ctx.webkitBackingStorePixelRatio ||
ctx.mozBackingStorePixelRatio ||
ctx.msBackingStorePixelRatio ||
ctx.oBackingStorePixelRatio ||
ctx.backingStorePixelRatio ||
1;
const ratio = dpr / bsr;
const viewport = page.getViewport({ scale: 1 });
canvas.width = viewport.width * ratio;
canvas.height = viewport.height * ratio;
canvas.style.width = viewport.width + "px";
canvas.style.height = viewport.height + "px";
ctx.setTransform(ratio, 0, 0, ratio, 0, 0);
const renderContext = {
canvasContext: ctx,
viewport: viewport,
};
// 数据渲染到canvas画布上
page.render(renderContext);
})
}
3. 使用vue-pdf
javascript
npm install vue-pdf
import pdf from 'vue-pdf'
components: {
pdf
},
<pdf class="pdf-preview" style="width: 100%;height:100%" ref="myPdfComponent" :src="previewUrl"></pdf>
4. 使用iframe
javascript
<iframe :src='previewUrl' frameborder="0" width="100%" height="100%"></iframe>
5. 使用vue-pdf-embed
6. 使用pdfh5.js
txt预览
1.使用textarea实现预览
javascript
// 读取txt内容
let xhr = new XMLHttpRequest();
xhr.open("get", '文档地址', true);
xhr.responseType = "blob";
xhr.onload = (e) => {
if (e.currentTarget.status == 200) {
const reader = new FileReader();
reader.readAsText(e.currentTarget.response);//非常重要
reader.onload = () => {
txtContain = reader.result;
};
}
};
xhr.send();
// 预览HTML
<textarea :value="txtContain" readonly></textarea>
图片预览
使用文件流预览
javascript
const blobImage = new window.Blob([res.data], { type: 'image/' + fileType }) // fileType指图片的类型
const imageHref = URL.createObjectURL(blobImage); // 创造一个地址
preloadImg.value = imageHref // img标签的src属性的值
使用v-viewer
javascript
// 全局引入(main.js中)
import 'viewerjs/dist/viewer.css'
import Viewer from 'v-viewer'
Vue.use(Viewer)
//配置项
Viewer.setDefaults({
zIndexInline:9999
})
<!--1、以组件的形式-->
<viewer :images="photo">
<img v-for="(src,index) in photo" :src="src" :key="index"/>
</viewer>
<!--2、以指令的形式-->
只需要将v-viewer指令添加到任意元素即可,该元素下的所有img元素都会被viewer自动处理。
<div v-viewer>
<img v-for="(src,index) in photo" :src="src" :key="index"/>
</div>