在线预览文件docx、xslx、pdf、img
在项目中比如要对上传的文件进行预览,这时前端通常采用的是使用各种库来解决这个问题。这里推荐一个库vue-office
,vue-office是一站式解决(docx、.xlsx、pdf)预览的vue组件库。
可以看出这个组件库还是有些缺陷的,比如docx的艺术字体、excel的多种数据格式解析不准确的问题,但普通的预览是没什么问题的。
为什么基本找不到doc或xls的在线预览,首先doc和xls是07版本前的格式,其次docx和xlsx是采用XML
的开放文件格式进行存储,解析更容易。所以市面上基本都是docx和xlsx更容易找到方案,要能够预览doc和xls一般要花费较大的成本。
相对于文档和表格pdf的库是比较多的,以下为使用vue-office/pdf
的示例:
<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' //设置文档地址,可以是base64 } }, methods: { renderedHandler() { console.log("渲染完成") }, errorHandler() { console.log("渲染失败") } } } </script>
复制
这个很简单直接放链接或base64编码就可以,这个是pdf实际就是基于pdfjs这个库,但在比较老的浏览器中兼容性并不好,检查是否支持“||=”,如果支持就直接使用vue-office/pdf
这个库,如果不支持那么我们直接使用pdf-js-dist@2.0.943
这个库。
如果要对pdf进行放大缩小为了性能和用户友好,我们先把canvas画面放大,然后再通过css把盒子缩小,直接控制盒子的缩放就行,这样一来就不用重新渲染同时保证了画质的清晰度,一定程度上提升了性能。
使用示例如下:
<template> <div class="pdfcontainer"> <div class="pdfcanvas" ref="pdfCanvasContainer" :style="'transform:scale(' + canvasScale + ')'" ></div> <div class="zoom"> <i class="el-icon-zoom-out cursor" @click="zoom('out')"></i> <i class="el-icon-zoom-in cursor" @click="zoom('in')"></i> </div> </div> </template> <script> import { getDocument } from "pdfjs-dist"; export default { name: "PdfViewer", props: { src: { type: String, }, }, data() { return { scale: 3, canvasScale: 0.5, }; }, mounted() { this.loadPdf(); }, methods: { /** * @description: 加载pdf */ loadPdf() { let base64Data = this.src.replace(/^data:application\/pdf;base64,/, ""); let pdfData = window.atob(base64Data); let arrayBuffer = new Uint8Array(pdfData.length); for (let i = 0; i < pdfData.length; i++) { arrayBuffer[i] = pdfData.charCodeAt(i); } const loadingTask = getDocument({ data: arrayBuffer }); loadingTask.promise.then((pdf) => { const numPages = pdf.numPages; const canvasContainer = this.$refs.pdfCanvasContainer; canvasContainer.innerHTML = ""; // 清空容器 for (let pageNumber = 1; pageNumber <= numPages; pageNumber++) { pdf.getPage(pageNumber).then((page) => { const viewport = page.getViewport(this.scale); const canvas = document.createElement("canvas"); const context = canvas.getContext("2d"); canvas.height = viewport.height || page.view[3]; canvas.width = viewport.width || page.view[2]; // 将canvas添加到容器中 canvasContainer.appendChild(canvas); // 渲染PDF到canvas const renderContext = { canvasContext: context, viewport: viewport, }; page.render(renderContext); }); } }); }, /** * @description: 缩放 * @param {String} type 类型 */ zoom(type) { if (type) { if (type === "out" && this.canvasScale.toFixed(2) > 0.1) { this.canvasScale -= 0.05; } else if (type === "in") { this.canvasScale += 0.05; } } }, }, }; </script> <style scoped> .pdfcontainer { position: relative; } .pdfcanvas { position: absolute; top: 12px; left: 0; right: 0; bottom: 0; max-width: 100%; max-height: 100%; } .scale { position: fixed; bottom: 24px; right: 24px; font-size: 24px; } .cursor { margin: 24px; cursor: pointer; } </style>
复制
docx
这个目前就使用vue-office/docx
就能支持,在老本版中浏览器中也能使用,使用示例如下:
<template> <vue-office-docx :src="docx" style="height: 100vh;" @rendered="renderedHandler" @error="errorHandler" /> </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' //设置文档网络地址,可以是相对地址,也可以是base64 } }, methods: { renderedHandler() { console.log("渲染完成") }, errorHandler() { console.log("渲染失败") } } } </script>
复制
xlsx
这个目前就使用vue-office/excel就能支持,在老本版中浏览器中也能使用,使用示例如下:
<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'//设置文档地址,或base64 } }, methods: { renderedHandler() { console.log("渲染完成") }, errorHandler() { console.log("渲染失败") } } } </script>
复制
图片
图片直接使用img标签就行啦
总结
以上就是在线预览的一些方案啦,有更好的方式欢迎评论留言讨论。