vue2.0纯前端预览附件方法汇总

程序媛_MISS_zhang_0110 2024-09-03 15:33:01 阅读 73

vue2.0纯前端预览附件方法汇总

一、使用iframe预览1.使用 Office 在线查看器2.XDOC文档预览服务XDOC官网地址:[https://view.xdocin.com/](https://view.xdocin.com/)

二、vue-office具体效果可以参考: [https://501351981.github.io/vue-office/examples/dist/#/docx](https://501351981.github.io/vue-office/examples/dist/#/docx)

1.docx预览2.excel文档预览3.pdf文档预览具体代码可以参考: [https://gitee.com/ye-jizeng/vue-office#https://gitee.com/link?target=https%3A%2F%2F501351981.github.io%2Fvue-office%2Fexamples%2Fdist%2F](https://gitee.com/ye-jizeng/vue-office#https://gitee.com/link?target=https%3A%2F%2F501351981.github.io%2Fvue-office%2Fexamples%2Fdist%2F)

三、file-viewer插件(封装好的预览组件)1.通过上传获取文件arrayBuffer具体效果可以参考: [https://zhuye1993.github.io/file-view/dist/index.html](https://zhuye1993.github.io/file-view/dist/index.html)代码地址: [https://github.com/zhuye1993/file-view](https://github.com/zhuye1993/file-view)

2.通过上传获取文件arrayBuffer和Url方式(都转换成html 和css方式)具体效果可以参考: [https://viewer.flyfish.group/](https://viewer.flyfish.group/)代码地址:[https://git.flyfish.dev/flyfish-group/file-viewer-demo](https://git.flyfish.dev/flyfish-group/file-viewer-demo)

四、vue-pdf插件1.全文预览2.指定页数,直接预览到某页的

五、pptx.js插件

一、使用iframe预览

1.使用 Office 在线查看器

支持 Word 和 Excel 和Pdf 文档预览,兼容性好。不需要额外安装库,直接使用在线服务。 文件地址必须公网

<code><iframe :src="textVisibleURl" frameborder="0" width="700" height="800"></iframe>code>

// 打开文件预览

clickPreview(pitem) { -- -->

if (/\.pdf$/i.test(pitem.name)) {

this.textVisibleURl = pitem.url;

} else if (/\.(doc|docx|xls|xlsx|ppt|pptx|pdf)$/i.test(pitem.name)) {

let src = pitem.url;

//这个地址预览的时候有一些按钮

// this.textVisibleURl = `https://view.officeapps.live.com/op/view.aspx?src=${src}`;

this.textVisibleURl = `https://view.officeapps.live.com/op/embed.aspx?src=${ src}`;

} else if (/\.csv$/i.test(pitem.name)) {

this.textVisibleURl = `http://view.xdocin.com/xdoc?_xdoc=${ pitem.url}`;

}

},

2.XDOC文档预览服务

调用方法:https://view.xdocin.com/view?src=你的文档地址

<iframe

class="iframeDom"code>

:src="textVisibleURl"code>

frameborder="0"code>

width="100%"code>

height="800"code>

></iframe>

clickPreview(){ -- -->

var xurl = 'https://view.xdocin.com/view?src=';

xurl += encodeURIComponent(newV);

let ops = {

pdf: true,

// toolbar: false,

// limit: '2,1', //只显示第二页code>

// limit: '2', //显示一二页

limit: '5,4', //显示一二页

// limit: '2,3', //显示二三四页

};

for (var a in ops) { -- -->

xurl += '&' + a + '=' + encodeURIComponent(ops[a]);

}

this.textVisibleURl = xurl;

}

XDOC官网地址:https://view.xdocin.com/

二、vue-office

支持多种文件(.docx、.pdf、.excel)预览的vue组件套装,支持vue2/3。

只需提供文档的src(网络地址)即可完成文档预览

(其中word是转换成html 和css,可以对文档内容进行高亮定位什么的)

有文档网络地址,比如 https://***.docx

文件上传时预览,此时可以获取文件的ArrayBuffer或Blob

具体效果可以参考: https://501351981.github.io/vue-office/examples/dist/#/docx

//docx文档预览组件

npm install @vue-office/docx vue-demi

//excel文档预览组件

npm install @vue-office/excel vue-demi

//pdf文档预览组件

npm install @vue-office/pdf vue-demi

1.docx预览

// 使用网络地址

<template>

<vue-office-docx :src="docx" @rendered="rendered"/>code>

</template>

<script>

//1.引入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.element的上传组件,获取文件的arrayBuffer

<template>

<div id="docx-demo">code>

<el-upload :limit="1" :file-list="fileList" accept=".docx" :beforeUpload="beforeUpload" action="">code>

<el-button size="small" type="warning">点击上传</el-button>code>

</el-upload>

<vue-office-docx :src="src" />code>

</div>

</template>

<script>

import VueOfficeDocx from '@vue-office/docx'

import '@vue-office/docx/lib/index.css'

export default { -- -->

components: {

VueOfficeDocx

},

data(){

return {

src:'',

fileList:[]

}

},

methods:{

beforeUpload(file){

let reader = new FileReader();

reader.readAsArrayBuffer(file);

reader.onload = (loadEvent) => {

let arrayBuffer = loadEvent.target.result;

this.src = arrayBuffer

};

return false

}

}

}

</script>

//********************************************************************************************

//3.原生的input type="file"code>

<template>

<div>

<input type="file" @change="changeHandle"/>code>

<vue-office-docx :src="src"/>code>

</div>

</template>

<script>

import VueOfficeDocx from '@vue-office/docx'

import '@vue-office/docx/lib/index.css'

export default { -- -->

components: {

VueOfficeDocx

},

data(){

return {

src: ''

}

},

methods:{

changeHandle(event){

let file = event.target.files[0]

let fileReader = new FileReader()

fileReader.readAsArrayBuffer(file)

fileReader.onload = () => {

this.src = fileReader.result

}

}

}

}

</script>

2.excel文档预览

<template>

<vue-office-excel :src="excel" @rendered="rendered"/>code>

</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:{

rendered(){

console.log("渲染完成")

}

}

}

</script>

3.pdf文档预览

<template>

<vue-office-pdf :src="pdf" @rendered="rendered"/>code>

</template>

<script>

//引入VueOfficePdf组件

import VueOfficePdf from '@vue-office/pdf'

export default { -- -->

components:{

VueOfficePdf

},

data(){

return {

pdf: 'http://static.shanhuxueyuan.com/test.pdf' //设置文档地址

}

},

methods:{

rendered(){

console.log("渲染完成")

}

}

}

</script>

具体代码可以参考: https://gitee.com/ye-jizeng/vue-office#https://gitee.com/link?target=https%3A%2F%2F501351981.github.io%2Fvue-office%2Fexamples%2Fdist%2F

三、file-viewer插件(封装好的预览组件)

1.通过上传获取文件arrayBuffer

具体效果可以参考: https://zhuye1993.github.io/file-view/dist/index.html

代码地址: https://github.com/zhuye1993/file-view

参考文章链接: https://juejin.cn/post/7071598747519549454

// 主要代码

<template>

<div :class="{ hidden }">code>

<div class="banner">code>

<div class="container">code>

<h1>

<div>

在线文档查看

<input class="file-select" type="file" @change="handleChange" />code>

</div>

</h1>

</div>

</div>

<div class="container">code>

<div v-show="loading" class="well loading">正在加载中,请耐心等待...</div>code>

<div v-show="!loading" class="well" ref="output"></div>code>

</div>

</div>

</template>

<script>

import { -- --> getExtend, readBuffer, render } from "@/components/util";

import { parse } from "qs";

/**

* 支持嵌入式显示,基于postMessage支持跨域

* 示例代码:

*

*/

export default {

name: "HelloWorld",

props: {

msg: String,

},

data() {

return {

// 加载状态跟踪

loading: false,

// 上个渲染实例

last: null,

// 隐藏头部,当基于消息机制渲染,将隐藏

hidden: false,

};

},

created() {

// 允许使用预留的消息机制发送二进制数据,必须在url后添加?name=xxx.xxx&from=xxx

const { from, name } = parse(location.search.substr(1));

if (from) {

window.addEventListener("message", (event) => {

const { origin, data: blob } = event;

if (origin === from && blob instanceof Blob) {

// 构造响应,自动渲染

const file = new File([blob], name, { });

this.hidden = true;

this.handleChange({ target: { files: [file] } });

}

});

}

},

methods: {

async handleChange(e) {

this.loading = true;

try {

const [file] = e.target.files;

const arrayBuffer = await readBuffer(file);

this.loading = false;

this.last = await this.displayResult(arrayBuffer, file);

} catch (e) {

console.error(e);

} finally {

this.loading = false;

}

},

displayResult(buffer, file) {

// 取得文件名

const { name } = file;

// 取得扩展名

const extend = getExtend(name);

// 输出目的地

const { output } = this.$refs;

// 生成新的dom

const node = document.createElement("div");

// 添加孩子,防止vue实例替换dom元素

if (this.last) {

output.removeChild(this.last.$el);

this.last.$destroy();

}

const child = output.appendChild(node);

// 调用渲染方法进行渲染

return new Promise((resolve, reject) =>

render(buffer, extend, child).then(resolve).catch(reject)

);

},

},

};

</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->

<style scoped>

.banner {

overflow: auto;

text-align: center;

/* background-color: #12b6ff; */

color: #000;

}

.hidden .banner {

display: none;

}

.hidden .well {

height: calc(100vh - 12px);

}

.file-select {

position: absolute;

left: 5%;

top: 17px;

margin-left: 20px;

}

.banner div {

color: #000;

}

.banner h1 {

font-size: 20px;

line-height: 2;

margin: 0.5em 0;

}

.well {

display: block;

background-color: #f2f2f2;

border: 1px solid #ccc;

margin: 5px;

width: calc(100% - 12px);

height: calc(100vh - 73px);

overflow: auto;

}

.loading {

text-align: center;

padding-top: 50px;

}

.messages .warning {

color: #cc6600;

}

</style>

<style>

.pptx-wrapper {

max-width: 1000px;

margin: 0 auto;

}

</style>

2.通过上传获取文件arrayBuffer和Url方式(都转换成html 和css方式)

具体效果可以参考: https://viewer.flyfish.group/

代码地址:https://git.flyfish.dev/flyfish-group/file-viewer-demo

如果要获取最新的源码,要找人家开放私库权限(文章链接里面有)

参考文章链接: https://blog.csdn.net/wybaby168/article/details/122842866?spm=1001.2014.3001.5502

//对应解析的插件

word预览是用的docxjs

pdf预览是用的pdfjs

ppt预览是用的pptx2html

// 主要代码

<template>

<div class="file-viewer">code>

<div class="name">{ -- -->{ filename}}</div>code>

<div v-if="error" class="content loading">{ -- -->{ error}}</div>code>

<template v-else>

<div v-show="loading" class="content loading">{ -- -->{ message}}</div>code>

<div v-show="!loading" class="content" ref="output"></div>code>

</template>

</div>

</template>

<script>

import { -- --> getExtend, render } from "./util";

import axios from "axios";

import { readBuffer } from "../../common/util";

const messages = {

loading: '正在加载中,请耐心等待...',

reading: '正在努力解析文件...',

errorLoading: e => `加载文件异常:${ e}`,

errorReading: e => `读取文件异常:${ e}`,

}

export default {

name: "FileViewer",

props: {

file: {

type: [File, Blob, ArrayBuffer],

description: '通过文件对象或二进制数据加载文档'

},

url: {

type: String,

description: '通过url加载文档'

}

},

data() {

return {

// 加载状态跟踪

loading: false,

// 存在错误时有值

error: '',

// 消息

message: '',

// 文件名

filename: '',

}

},

watch: {

// url改变时,重新请求

url() {

this.loadFromUrl();

},

file(file) {

this.resolveFile(file);

},

},

mounted() {

if (this.file) {

this.resolveFile(this.file);

}

this.loadFromUrl();

},

methods: {

// 从url加载

async loadFromUrl() {

// 要预览的文件地址

const { url } = this;

if (!url) return;

this.startLoading(messages.loading)

const filename = url.substr(url.lastIndexOf('/') + 1);

// 拼接ajax请求文件内容

try {

const { data } = await axios({ url, method: 'get', responseType: 'blob' });

// 展示错误

if (!data) return this.showError('文件下载失败');

// 手动构建一个file

const file = this.wrap(data, filename);

// 解析文件

return this.resolveFile(file);

} catch (e) {

this.showError(messages.errorLoading(e));

} finally {

this.endLoading();

}

},

// 包装file

wrap(data, filename) {

if (data instanceof File) {

return data;

}

if (data instanceof Blob) {

return new File([ data ], filename, { });

}

if (data instanceof ArrayBuffer) {

return this.wrap(new Blob([ data ]));

}

},

// 处理并解析文件

async resolveFile(data) {

// 停止之前的加载

if (this.loading) this.endLoading();

// 安全的包装文件

const file = this.wrap(data);

// 开始加载

this.startLoading(messages.reading);

try {

this.filename = file.name && decodeURIComponent(file.name) || '';

const arrayBuffer = await readBuffer(file);

this.last = await this.displayResult(arrayBuffer, file)

} catch (e) {

this.showError(messages.errorReading(e));

} finally {

this.endLoading();

}

},

// 展示渲染最终效果

displayResult(buffer, file) {

// 取得文件名

const { name } = file;

// 取得扩展名

const extend = getExtend(name);

// 输出目的地

const { output } = this.$refs;

// 生成新的dom

const node = document.createElement('div');

// 添加孩子,防止vue实例替换dom元素

if (this.last) {

output.removeChild(output.lastChild);

this.last.$destroy();

}

const child = output.appendChild(node);

// 调用渲染方法进行渲染

return new Promise((resolve, reject) => render(buffer, extend, child)

.then(resolve).catch(reject));

},

showError(message) {

this.error = message;

},

startLoading(message) {

this.loading = true;

this.message = message;

this.error = '';

},

endLoading() {

this.loading = false;

this.message = '';

}

}

}

</script>

<style scoped>

.file-viewer {

position: relative;

}

.content {

display: block;

background-color: #f2f2f2;

border: 1px solid #ccc;

margin: 5px;

width: calc(100% - 12px);

height: calc(100vh - 73px);

overflow: auto;

}

.loading {

text-align: center;

padding-top: 50px;

}

.name {

position: absolute;

bottom: 0;

left: 0;

width: 100%;

padding: 13px 0;

font-size: 20px;

text-shadow: 2px 2px #616161;

pointer-events: none;

color: white;

background: rgba(31, 31, 31, 0.22);

text-align: center;

z-index: 10000;

}

</style>

四、vue-pdf插件

arrayBuffer和Url方式都支持

npm install --save vue-pdf

import pdf from 'vue-pdf'

1.全文预览

<template>

<div>

<pdf

v-for="i in numPages"code>

:key="i"code>

:page="i"code>

:src="pdfUrl"code>

style="width: 100%"code>

@num-pages="pageCount = $event"code>

></pdf>

</div>

</template>

<script>

import pdf from 'vue-pdf';

export default { -- -->

name: 'PDF',

components: { pdf },

data() {

return {

pageCount: 10, //当前页

pdfUrl: '',

src: 'https://.pdf', // pdf文件地址

numPages: 0, //总页数

};

},

mounted() {

this.loadPdfHandler();

},

methods: {

async loadPdfHandler() {

this.pdfUrl = pdf.createLoadingTask(this.src);

this.pdfUrl.promise.then(pdf => {

this.numPages = pdf.numPages;

});

},

},

};

</script>

2.指定页数,直接预览到某页的

<template>

<div class="pdf-preview-out" v-loading="boxLoading">code>

<!-- 上部 外层容器 用于滚动-->

<div class="scroll-box">code>

<!-- 用于截取调缩放后的空白区域 -->

<div class="pdf-box">code>

<!-- pdf预览区域(会被缩放) -->

<div :style="getPdfSize()" class="pdf-scale-box">code>

<!-- 预览组件 -->

<pdf

:src="url"code>

:page="currentPage"code>

@num-pages="getTotalPage"code>

@page-loaded="pageLoaded"code>

@loaded="mountedLoaded"code>

></pdf>

</div>

</div>

</div>

<!-- 底部操作栏 -->

<div class="bottom-tools">code>

<div>共 { -- -->{ pageTotal }} 页</div>

<div class="page">code>

<el-button round type="primary" :disabled="currentPage === 1" @click="chengPage">code>

上一页

</el-button>

<!-- 页码展示及跳转 -->

<el-button

round

type="primary"code>

:disabled="currentPage === pageTotal"code>

@click="chengPage('+')"code>

>

下一页

</el-button>

</div>

<div class="scale">code>

<el-button

type="primary"code>

icon="el-icon-minus"code>

circle

:disabled="pageScale - 0.1 < 0.3"code>

@click="scalePage"code>

></el-button>

<el-button

type="primary"code>

icon="el-icon-plus"code>

circle

:disabled="pageScale + 0.1 > 1"code>

@click="scalePage('+')"code>

></el-button>

</div>

</div>

</div>

</template>

<script>

// 插件引入

import pdf from 'vue-pdf';

export default { -- -->

components: {

pdf,

},

data() {

return {

// 总页数

pageTotal: 0,

// 当前页

currentPage: 3,

// 缩放比例

pageScale: 0.8,

// 遮罩

boxLoading: true,

pageChangeTimer: null,

url: 'https://.pdf',

};

},

methods: {

// 获取到pdf总页数时触发 会传入总页数

getTotalPage(page) {

this.pageTotal = page;

},

// 初始化加载完毕触发

mountedLoaded() {

// 去除遮罩

this.boxLoading = false;

},

// 每加载完成一页时触发(初始化/翻页时均会触发)

pageLoaded() {

// 重新设置pdf预览区域容器外容器的尺寸

this.setPdfBoxSize();

},

// 设置pdf预览区域容器的缩放尺寸

getPdfSize() {

return {

transform: `scale(${ this.pageScale})`,

};

},

// 点击缩放时触发

scalePage(type) {

// 改变缩放比例

let sacle = 0;

if (type === '+') {

sacle = this.pageScale + 0.1;

} else {

sacle = this.pageScale - 0.1;

}

// 可能会涉及js的精度损失 保留一位小数即可

this.pageScale = Number(sacle.toFixed(1));

// 缩放后pdf预览区域容器中会有留白 重新设置pdf预览区域容器外容器的尺寸

this.setPdfBoxSize();

},

// 方法 翻页

chengPage(type) {

// 防抖 0.5秒内不再次触发时执行

if (this.pageChangeTimer) {

clearTimeout(this.pageChangeTimer);

}

// 执行翻页

this.pageChangeTimer = setTimeout(() => {

if (type === '+') {

this.currentPage += 1;

} else {

this.currentPage -= 1;

}

// 翻页后将滚动条归位到顶部

this.scrollbarReset();

this.pageChangeTimer = null;

}, 500);

},

// 方法 滚动条归位到顶部

scrollbarReset() {

let boxDom = document.querySelector('.scroll-box');

boxDom.scrollTop = 0;

},

// 方法 设置pdf预览区域容器外容器的尺寸

setPdfBoxSize() {

// 缩放后 pdf的显示上会缩小 但元素的实际占地尺寸不会变化(仍是原尺寸) 导致可能会出现部分区域留白 通过改变pdf预览区域容器外容器的尺寸 来将留白区域hidden

// 获取pdf的原尺寸

let boxDom = document.querySelector('.pdf-scale-box');

// 获取要设置尺寸的元素dom

let setDom = document.querySelector('.pdf-box');

// 如有缩放 高度根据缩放比例变化(48px是预留的上下外边距)

if (this.pageScale !== 1 && boxDom && setDom) {

setDom.style.height = `${ boxDom.clientHeight * this.pageScale + 48}px`;

} else {

setDom.style.height = '';

}

// console.log(this.pageScale)

// console.log(boxDom.clientWidth * this.pageScale)

},

},

};

</script>

<style lang="scss" scoped>code>

.pdf-preview-out { -- -->

// 高度为占满父组件中的外层容器(若不需要在父组件中设置高度 也可以在本组件中直接设置为所需值)

height: 100%;

// border: 1px solid #909;

&,

div {

-webkit-box-sizing: border-box;

-moz-box-sizing: border-box;

box-sizing: border-box;

}

// 滚动容器

.scroll-box {

// 高度按比例 溢出滚动

height: 800px;

overflow: auto;

border: 2px solid #c0d8f3;

border-bottom: none;

border-radius: 6px;

background-color: #eeeeee;

// 滚动条样式

&::-webkit-scrollbar {

width: 10px;

}

&::-webkit-scrollbar-thumb {

background-color: #c0d8f3;

border-radius: 6px;

}

&::-webkit-scrollbar-track {

background-color: transparent;

border-radius: 6px;

}

// 用于缩放后截取掉不需要的空白的容器

.pdf-box {

overflow: hidden;

padding: 24px;

// border: 1px solid rgb(165, 11, 236);

}

// pdf预览区容器

.pdf-scale-box {

box-shadow: 0px 0px 20px 5px #666565;

// border: 2px solid #090;

// 设置缩放的中心点

transform-origin: center top;

transition: 0.2s;

}

}

.bottom-tools {

height: 50px;

line-height: 50px;

background-color: #c0d8f3;

border: 1px solid #5caaf8;

border-radius: 6px;

display: flex;

padding: 0px 24px;

.page {

color: #636a70;

flex-grow: 1;

// border: 1px solid #909;

span {

margin-right: 20px;

}

}

.scale {

// border: 1px solid #909;

text-align: right;

}

}

}

</style>

链接: https://blog.csdn.net/m0_71537867/article/details/131614868

五、pptx.js插件

另外预览ppt还有一个插件pptx但是我没试,放两个链接,你们可以自己试试

链接: https://www.cnblogs.com/xyulz/p/17812301.html

链接: https://blog.51cto.com/u_16213605/8386577

重要写完了~~~~~心累

在这里插入图片描述



声明

本文内容仅代表作者观点,或转载于其他网站,本站不以此文作为商业用途
如有涉及侵权,请联系本站进行删除
转载本站原创文章,请注明来源及作者。