首先,按需拉取,依赖和项目对应的版本 ,引入方法,和调用方法,根据版本来
- npm install @vue-office/docx
- npm install @vue-office/pdf
- npm install @vue-office/excel
- npm install @vue-office/pptx
- 根据版本,有的需要 npm install @vue/composition-api

image.png
如果pdf不需要修改样式,可以使用iframe
<template>
<div id="docx-demo">
<div class="file-info">
<h3>正在预览: {{ selectedFile.name }}</h3>
<p>文件大小: {{ formatFileSize(selectedFile.size) }}</p>
</div>
<div class="loading" v-if="loading">
<div class="spinner"></div>
<p>加载中,请稍候...</p>
</div>
<el-upload
:limit="1"
:file-list="fileList"
:beforeUpload="beforeUpload"
action=""
>
<el-button size="small" type="warning">点击上传</el-button>
</el-upload>
<vue-office-docx
v-if="fileType === 'docx' || fileType === 'doc'"
:src="src"
@rendered="onRendered"
@error="onError"
/>
<vue-office-excel
:src="excel"
v-if="fileType === 'xlsx' || fileType === 'xls'"
:options="options"
style="height: 500px"
@rendered="onRendered"
@error="onError"
/>
<vue-office-pdf
v-if="fileType === 'pdf'"
:src="pdf"
style="height: 100vh"
@rendered="onRendered"
@error="onError"
/>
<div
class="custom-ppt-viewer"
v-if="fileType === 'pptx' || fileType === 'ppt'"
>
<vue-office-pptx :src="ppt" @rendered="onRendered" @error="onError" />
</div>
<iframe
:src="previewUrl"
frameborder="0"
class="pdf-iframe"
@load="handleIframeLoad"
@error="handleIframeError"
></iframe>
</div>
</template>
<script>
import VueOfficeDocx from "@vue-office/docx";
import "@vue-office/docx/lib/index.css";
//引入VueOfficeExcel组件
import VueOfficeExcel from "@vue-office/excel";
//引入相关样式
import "@vue-office/excel/lib/index.css";
import VueOfficePdf from "@vue-office/pdf";
import VueOfficePptx from "@vue-office/pptx";
export default {
components: {
VueOfficeDocx,
VueOfficeExcel,
VueOfficePdf,
VueOfficePptx,
},
data() {
return {
ppt: "",
previewUrl: "",
acceptTypes: ".docx,.xlsx,.pptx,.pdf",
loading: false,
fileType: "",
selectedFile: { name: "", size: 0 },
pdf: "",
excel: "",
src: "",
fileList: [],
options: {
xls: false, //预览xlsx文件设为false;预览xls文件设为true
// minColLength: 0, // excel最少渲染多少列,如果想实现xlsx文件内容有几列,就渲染几列,可以将此值设置为0.
// minRowLength: 0, // excel最少渲染多少行,如果想实现根据xlsx实际函数渲染,可以将此值设置为0.
widthOffset: 10, //如果渲染出来的结果感觉单元格宽度不够,可以在默认渲染的列表宽度上再加 Npx宽
heightOffset: 10, //在默认渲染的列表高度上再加 Npx高
beforeTransformData: (workbookData) => {
return workbookData;
}, //底层通过exceljs获取excel文件内容,通过该钩子函数,可以对获取的excel文件内容进行修改,比如某个单元格的数据显示不正确,可以在此自行修改每个单元格的value值。
transformData: (workbookData) => {
return workbookData;
}, //将获取到的excel数据进行处理之后且渲染到页面之前,可通过transformData对即将渲染的数据及样式进行修改,此时每个单元格的text值就是即将渲染到页面上的内容
},
};
},
methods: {
// 检查文件大小 (这里限制为10MB)
// const maxSize = 10 * 1024 * 1024; // 10MB
// if (file.size > maxSize) {
// this.errorMessage = '文件大小不能超过10MB';
// return;
// }
// 处理iframe加载完成
handleIframeLoad() {
console.log("PDF预览加载完成");
},
// 处理iframe加载错误
handleIframeError() {
this.errorMessage = "PDF预览失败,请尝试重新上传";
},
formatFileSize(bytes) {
if (bytes === 0) return "0 Bytes";
const k = 1024;
const sizes = ["Bytes", "KB", "MB", "GB"];
const i = Math.floor(Math.log(bytes) / Math.log(k));
return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + " " + sizes[i];
},
onRendered() {
this.loading = false;
console.log("文档渲染完成");
},
onError(err) {
this.loading = false;
this.error = "文档预览失败: " + err.message;
console.error("预览错误:", err);
},
//在beforeUpload中读取文件内容
beforeUpload(file) {
if (!file) return;
this.selectedFile = file;
this.error = "";
this.loading = true;
// 获取文件类型
const fileName = file.name.toLowerCase();
if (fileName.endsWith(".docx")) {
this.fileType = "docx";
} else if (fileName.endsWith(".doc")) {
this.fileType = "doc";
} else if (fileName.endsWith(".ppt")) {
this.fileType = "ppt";
} else if (fileName.endsWith(".xlsx")) {
this.fileType = "xlsx";
} else if (fileName.endsWith(".xls")) {
this.fileType = "xls";
} else if (fileName.endsWith(".pptx")) {
this.fileType = "pptx";
} else if (fileName.endsWith(".pdf")) {
this.fileType = "pdf";
} else if (fileName.endsWith(".txt")) {
this.fileType = "txt";
} else {
this.error = "不支持的文件格式";
this.loading = false;
return;
}
let reader = new FileReader();
reader.readAsArrayBuffer(file);
reader.onload = (loadEvent) => {
let arrayBuffer = loadEvent.target.result;
if (this.fileType == "xlsx" || this.fileType == "xls") {
this.excel = arrayBuffer;
} else if (this.fileType == "docx" || this.fileType == "doc") {
this.src = arrayBuffer;
} else if (this.fileType == "pptx" || this.fileType == "ppt") {
this.ppt = arrayBuffer;
}
if (this.fileType == "pdf" || this.fileType == "txt") {
this.pdf = arrayBuffer;
this.previewFile(file);
}
};
return false;
},
// 预览PDF文件
previewFile(file) {
// 模拟上传进度
this.uploadProgress = 0;
const interval = setInterval(() => {
this.uploadProgress += 10;
if (this.uploadProgress >= 100) {
clearInterval(interval);
// 创建文件的临时URL用于预览
this.previewUrl = URL.createObjectURL(file);
}
}, 200);
},
},
};
</script>
<style scoped>
.pdf-iframe {
width: 100%;
height: 400px;
}
.custom-ppt-viewer {
width: 100%;
max-width: 900px;
margin: 0 auto;
height: 700px;
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
}
.custom-ppt-viewer .slide-container {
background-color: #f9f9f9;
margin-bottom: 20px;
border-radius: 8px;
overflow: hidden;
}
</style>