vue项目中实现doc/excel/pdf/txt/图片等文件的预览
word预览
1. 使用vue-office-docx(只支持docx文件预览,不支持doc文件)
支持文档网络地址(https://***.docx)。
文件上传时预览,此时可以获取文件的ArrayBuffer或二进制文件预览Blob。
// 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
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
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 HTMLthis.$refs.docpreview.innerHTML = html}).catch(function(error) {console.error(error);});
4. 使用微软的Office Web Viewer
使用iframe作为载体。
文件会传输到微软的服务器上,因此可能会涉及到文件隐私。
不需要安装 Office 软件,直接通过浏览器在线预览 docx、xlsx、pptx 文件。
不支持 pdf 预览。
<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。
// 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表中的数据,并不会进行排版,所以需要自己写样式重新排列数据。
npm install xlsx
import * as XLSX from 'xlsx/xlsx.mjs'<el-table :data="excelData" style="width: 100%"><el-table-columnv-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_workbookgetTable(tem_workbook.SheetNames[0]); // 读取第一张表数据// 解析xlsx数据为tablefunction getTable(sheetName) {let worksheet = workbook.value.Sheets[sheetName];excelData.value = XLSX.utils.sheet_to_json(worksheet);}
3. 使用SpreadJS
4.使用luckysheet(支持在线编辑,目前只支持xlsx格式)
// 在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为容器idshowinfobar: false, // 信息栏lang: 'zh'// 设定表格语言// loadUrl:''}luckysheet.create(options)})},
}
pdf预览
1. 使用vue-office-pdf
支持文档网络地址(https://***.docx)。
文件上传时预览,此时可以获取文件的ArrayBuffer或二进制文件预览Blob。
// 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标签。
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
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
<iframe :src='previewUrl' frameborder="0" width="100%" height="100%"></iframe>
5. 使用vue-pdf-embed
6. 使用pdfh5.js
txt预览
1.使用textarea实现预览
// 读取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>
图片预览
使用文件流预览
const blobImage = new window.Blob([res.data], { type: 'image/' + fileType }) // fileType指图片的类型
const imageHref = URL.createObjectURL(blobImage); // 创造一个地址
preloadImg.value = imageHref // img标签的src属性的值
使用v-viewer
// 全局引入(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>
链接
- vue-office官方
- sheetjs
- 链接1
- XDOC文档预览服务
- luckysheet
- Office Web Viewer
- 链接2
- 全网最全的docx、pptx、xlsx、pdf文件预览方案(典藏版