###word,excel,pdf,text,img预览
第一步:写一个button
<el-button
class="openWindown-btn"
link
type="primary"
@click="openWindown(scope.row)"
>预览
</el-button>
第二步:实现跳转方法
/**
* =================文件预览,下载====================
*/
const openWindown = (row: any) => {
window.open(`/filePreview?id=${row.id}&fileName=${row.name}`, "_blank");
};
第三步:写组件
注意点:lucksheet需要再index.html中引入依赖
<link rel='stylesheet' href='https://cdn.jsdelivr.net/npm/luckysheet/dist/plugins/css/pluginsCss.css' />
<link rel='stylesheet' href='https://cdn.jsdelivr.net/npm/luckysheet/dist/plugins/plugins.css' />
<link rel='stylesheet' href='https://cdn.jsdelivr.net/npm/luckysheet/dist/css/luckysheet.css' />
<link rel='stylesheet' href='https://cdn.jsdelivr.net/npm/luckysheet/dist/assets/iconfont/iconfont.css' />
<script src="https://cdn.jsdelivr.net/npm/luckysheet/dist/plugins/js/plugin.js"></script>
<script src="https://cdn.jsdelivr.net/npm/luckysheet/dist/luckysheet.umd.js"></script>
<template>
<div v-loading="loading" class="out-box">
<div class="img-box" v-if="state.type == 'JPG' ||
state.type == 'jpg' ||
state.type == 'JPEG' ||
state.type == 'jpeg' ||
state.type == 'PNG' ||
state.type == 'png'
">
<img :src="state.imgUrl" alt="" />
</div>
<div v-else-if="state.type == 'docx'" :style="{ height: getHeight }">
<div ref="docx" class="docx-box"></div>
</div>
<div v-else-if="state.type == 'xlsx'">
<div id="luckysheet"></div>
</div>
<!-- <div v-else-if="state.type == 'txt'" :style="{ height: getHeight }">
<div ref="txt" id="txt-box"></div>
</div> -->
<div v-else-if="state.type == 'pdf'" class="pdf-box" :style="{ height: getHeight }">
<vue-pdf-embed style="padding: 2rem 0; box-shadow: 1px 0px 15px #3a3737" :source="state.pdfSource" />
</div>
<div v-else class="notType">
<p>当前文件不支持预览,请下载查看</p>
<p>
支持预览类型:"JPG", "JPEG", "PNG", "jpg", "jpeg", "png", "pdf", "xlsx",
"docx"
</p>
</div>
</div>
</template>
<script setup lang="ts" name="filePreview">
import { ref, reactive, nextTick, onMounted, computed } from "vue";
import { useRoute } from "vue-router";
const route = useRoute();
import { ElMessage } from "element-plus";
import { commonService } from "/@/api/common";
import { renderAsync } from "docx-preview";
import LuckyExcel from "luckyexcel";
import VuePdfEmbed from "vue-pdf-embed";//
import router from "/@/router";
const loading = ref(false);
const docx = ref();
const txt = ref();
const state = reactive<any>({
fileName: route.query.fileName,
type: "",
id: route.query.id,
imgUrl: "",
pdfSource: "",
});
state.type = state.fileName.substr(state.fileName?.lastIndexOf(".") + 1);
const getHeight = computed(() => {
return window.innerHeight + "px";
});
function init(fileName: string, type: string, id: any) {
console.log("type:::::", type);
let arr = ["JPG", "JPEG", "PNG", "jpg", "jpeg", "png", "pdf", "xlsx", "docx"];
if (!arr.includes(type)) {
// ElMessage({
// type: "warning",
// message: "当前文件不支持预览,请下载查看!",
// });
return;
}
loading.value = true;
if (
type == "JPG" ||
type == "JPEG" ||
type == "PNG" ||
type == "png" ||
type == "jpg" ||
type == "jpeg"
) {
commonService
.preView_IMG(id)
.then((res: any) => {
if (res) {
let blob = new Blob([res.data], { type: res.data.type });
const imageUrl = URL.createObjectURL(blob);
state.imgUrl = imageUrl;
loading.value = false;
// (srcList.value = [imageUrl]), (loading.value = true);
} else {
ElMessage({
type: "error",
message: "接口请求失败",
});
loading.value = false;
}
})
.catch(function (error) {
loading.value = false;
});
} else if (type == "docx") {
commonService
.preView_Word(id)
.then((res: any) => {
let docxOptions = {
className: `${type}box`, // string:默认和文档样式类的类名/前缀
inWrapper: true, // boolean:启用围绕文档内容的包装器渲染
ignoreWidth: false, // boolean:禁用页面的渲染宽度
ignoreHeight: false, // boolean:禁止渲染页面高度
ignoreFonts: false, // boolean:禁用字体渲染
breakPages: true, // boolean:在分页符上启用分页
ignoreLastRenderedPageBreak: true, // boolean:在 lastRenderedPageBreak 元素上禁用分页
experimental: false, // boolean:启用实验功能(制表符停止计算)
trimXmlDeclaration: true, // boolean:如果为true,解析前会从 xmlTemplate 文档中移除 xmlTemplate 声明
useBase64URL: false, // boolean:如果为true,图片、字体等会转为base 64 URL,否则使用URL.createObjectURL
useMathMLPolyfill: false, // boolean:包括用于 chrome、edge 等的 MathML polyfill。
showChanges: false, // boolean:启用文档更改的实验性渲染(插入/删除)
debug: false, // boolean:启用额外的日志记录
};
if (res) {
let docData = new Blob([res.data], { type: res.data.type });
renderAsync(docData, docx.value, undefined, docxOptions).then(
(x) => { }
);
loading.value = false;
} else {
ElMessage({
type: "error",
message: "接口请求失败",
});
loading.value = false;
}
})
.catch(function (error) {
loading.value = false;
});
} else if (type == "pdf") {
commonService
.preView_PDF(id)
.then((res: any) => {
if (res) {
let blob = new Blob([res.data], { type: "application/pdf;charset=utf-8" });
let fileURL = URL.createObjectURL(blob);
window.open(fileURL, "_self");
loading.value = false;
} else {
ElMessage({
type: "error",
message: "接口请求失败",
});
loading.value = false;
}
})
.catch(function (error) {
loading.value = false;
});
} else if (type == "xlsx") {
//表格
commonService
.preView_Excel(id)
.then((res: any) => {
if (res) {
const blob = new Blob([res.data], {
type: res.data.type,
});
var file1 = new File([blob], fileName, {
type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
lastModified: Date.now(),
});
loadExcel(file1);
loading.value = false;
} else {
ElMessage({
type: "error",
message: "接口请求失败",
});
loading.value = false;
}
})
.catch(function (error) {
loading.value = false;
});
} else if (type == "txt") {
console.log(type, id, fileName);
// var reader = new FileReader;
// reader.readAsText(file, 'gb2312');
commonService.preView_Txt(id).then((res: any) => {
console.log(res);
let txtData = new Blob([res.data], { type: res.data.type });
// renderAsync(docData, docx.value, undefined, docxOptions).then(
// (x) => { }
// );
// loading.value = false;
// let reader = new FileReader;
// reader.readAsText(file, 'gb2312');
// renderAsync(docData, docx.value, undefined, docxOptions)
// reader.onload = (evt: any) => {
// var data = evt.target.result;
// // $('#textarea_id').val(data);
// }
})
.finally(() => {
loading.value = false;
});
}
}
/**
* ========================excel======================
*/
// 配置项
const options = {
container: "luckysheet", // 设定DOM容器的id
title: "luckysheet", // 设定表格名称
lang: "zh", // 设定表格语言
data: [
{
name: "Sheet1",
},
],
};
const initLuckysheet = () => {
luckysheet.destroy();
luckysheet.create(options);
};
nextTick(() => {
// 初始化表格
initLuckysheet();
});
const jsonData = ref({});
// 加载excel
const loadExcel = (evt: any) => {
console.log("evt::::", evt);
const files = evt;
if (files == null || files.length == 0) {
return;
}
let name = files.name;
let suffixArr = name.split("."),
suffix = suffixArr[suffixArr.length - 1];
if (suffix != "xlsx") {
throw new Error("当前仅支持xlsx文件");
}
LuckyExcel.transformExcelToLucky(
files,
function (exportJson: any, luckysheetfile: any) {
if (exportJson.sheets == null || exportJson.sheets.length == 0) {
return;
}
jsonData.value = exportJson;
// luckysheet.destroy();
let option = {
container: "luckysheet", //luckysheet is the container id
data: exportJson.sheets,
config: {},
lang: "zh", // 设定表格语言
title: exportJson.info.name,
userInfo: exportJson.info.name.creator,
showtoolbar: false, // 是否显示工具栏
showinfobar: false, // 是否显示顶部信息栏
showsheetbar: true,
showstatisticBar: false, // 是否显示底部sheet按钮
cellRightClickConfig: {
copy: false, // 复制
copyAs: false, // 复制为
paste: false, // 粘贴
insertRow: false, // 插入行
insertColumn: false, // 插入列
deleteRow: false, // 删除选中行
deleteColumn: false, // 删除选中列
deleteCell: false, // 删除单元格
hideRow: false, // 隐藏选中行和显示选中行
hideColumn: false, // 隐藏选中列和显示选中列
rowHeight: false, // 行高
columnWidth: false, // 列宽
clear: false, // 清除内容
matrix: false, // 矩阵操作选区
sort: false, // 排序选区
filter: false, // 筛选选区
chart: false, // 图表生成
image: false, // 插入图片
link: false, // 插入链接
data: false, // 数据验证
cellFormat: false, // 设置单元格格式,
},
enableAddRow: false, // 允许添加行
enableAddBackTop: false, // 允许回顶部
sheetFormulaBar: false, // 是否显示公式栏
showstatisticBarConfig: {
zoom: true,
},
};
window.luckysheet.create(option);
// window.luckysheet
}
);
};
onMounted(() => {
init(state.fileName, state.type, state.id);
});
nextTick(() => { });
</script>
<style lang="scss" scoped>
.out-box {
height: 100%;
background: #808080;
.img-box {
padding: 1rem;
max-height: 100%; /* 大高度 */
max-width: 100%;
overflow: auto; /* 滚动条 */
img {
width: 50%;
margin: 0 auto;
display: block;
box-shadow: 1px 0px 15px #3a3737;
}
}
.docx-box {
height: 100%;
overflow: scroll;
}
.pdf-box {
width: 50%;
margin: 0rem auto;
overflow: scroll;
}
#luckysheet {
margin: 0px;
padding: 0px;
position: absolute;
width: 100%;
height: 100%;
left: 0px;
top: 0px;
bottom: 0px;
}
.notType {
position: fixed;
top: -30%;
left: 0;
right: 0;
bottom: 0;
height: 100px;
margin: auto;
border-radius: 10px;
width: 800px;
padding: 10px;
background: rgba(255, 255, 255, 0.8);
box-sizing: border-box;
p {
text-align: center;
line-height: 2rem;
font-size: 18px;
}
p:first-child {
font-size: 22px;
color: rgb(220, 26, 26);
line-height: 3rem;
}
}
}
</style>
pdf可以不使用插件浏览器可以直接解析pdf,excel这里下载的插件是 LuckyExcel这个插件,docx使用的docx-preview这个插件
接口类型:
/**
* 文件预览excel
*/
static async preView_Excel(data: number): Promise<MyAxiosResponse> {
return request({
url: `/annexes/getByteStream/${data}`,
method: "post",
responseType: "arraybuffer", //告诉服务器想到的响应格式
headers: {
"Content-Type":
"application/vnd.ms-excel;application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
},
});
}
//文件预览pdf
static async preView_PDF(data: number): Promise<MyAxiosResponse> {
return request({
url: `/annexes/getByteStream/${data}`,
method: "POST",
responseType: "blob",
headers: {
"Content-Type": "application/pdf;charset=UTF-8",
},
});
}
//文件预览img
static async preView_IMG(data: number): Promise<MyAxiosResponse> {
return request({
url: `/annexes/getByteStream/${data}`,
method: "POST",
responseType: "blob",
headers: {
Accept: "application/octet-stream",
},
});
}
//文件预览Word
static async preView_Word(data: number): Promise<MyAxiosResponse> {
return request({
url: `/annexes/getByteStream/${data}`,
method: "POST",
responseType: "blob",
// headers: {
// "Content-Type":
// "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
// },
});
}
//TXT预览
static async preView_Txt(data: number): Promise<MyAxiosResponse> {
return request({
url: `/annexes/getByteStream/${data}`,
method: "POST",
responseType: "blob",
// headers: {
// "Content-Type":
// "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
// },
});
}