创建preview-file组件
- pptx文件,点此下载 PPTXjs压缩包,解压后放在public目录下,在index.html中拿到文件url
在PPTXjs/index.html页面,获取传给iframe的动态文件地址
<template>
<t-dialog :visible="visible" :footer="false" width="100vw" header="文件预览" @close="clickClose">
<div style="width: 100%; height: calc(80vh - 88px)">
<!-- word -->
<div id="docx"></div>
<!-- excel -->
<div
id="xlsx "
:style="{
width: fileMessage.excelShow ? '100%' : '',
height: fileMessage.excelShow ? 'calc(80vh - 88px)' : '',
}"
></div>
<!--ppt,pptx-->
<div v-if="fileMessage.pptShow" class="d-flex">
<iframe
:src="`PPTXjs-1.21.1/index.html?file=${fileMessage.downloadUrl}`"
width="100%"
height="calc(80vh - 88px)"
frameborder="0"
></iframe>
</div>
<!--图片-->
<div v-if="fileMessage.imgShow" class="d-flex">
<img :src="fileMessage.downloadUrl" />
</div>
<!--音频-->
<div v-else-if="fileMessage.audioShow">
<!-- loop="loop" 循环播放 -->
<audio id="myaudio" :src="fileMessage.downloadUrl" controls preload="preload">不支持audio标签</audio>
</div>
<!--视频-->
<div v-else-if="fileMessage.videoShow" class="d-flex">
<video preload="auto" align="center" controls>
<source :src="fileMessage.downloadUrl" type="video/mp4" />
</video>
</div>
<!--其他不能预览的-->
<!-- <div v-else-if="fileMessage.otherShow"></div> -->
</div>
</t-dialog>
</template>
<script lang="ts">
import { computed, onMounted, reactive, defineComponent, ref } from 'vue';
import jsPreviewDocx from '@js-preview/docx';
import jsPreviewExcel from '@js-preview/excel';
import '@js-preview/excel/lib/index.css';
import '@js-preview/docx/lib/index.css';
import { MessagePlugin } from 'tdesign-vue-next';
export default defineComponent({
name: 'PreviewFile',
props: {
file: {
type: Object,
default: () => {
return {};
},
},
visible: {
type: Boolean,
default: false,
},
},
emits: ['close'],
setup(props, { emit }) {
interface FileMessage {
fileId: string | number;
fileName: string;
downloadUrl: string;
imgShow: boolean;
docShow: boolean;
pdfShow: boolean;
excelShow: boolean;
audioShow: boolean;
videoShow: boolean;
pptShow: boolean;
// 其他不能预览的
// otherShow: boolean;
}
// interface FileStyle {
// height: string;
// width: string;
// }
// const props = defineProps<Props>();
// const $emits = defineEmits<Emits>();
const file = computed(() => props.file);
// 文件信息
const fileMessage = reactive<FileMessage>({
fileId: '',
fileName: '',
downloadUrl: '',
imgShow: false,
docShow: false,
excelShow: false,
audioShow: false,
videoShow: false,
// 其他不能预览的
// otherShow: false,
pdfShow: false,
pptShow: false,
});
// const fileStyle = reactive<FileStyle>({
// height: `${window.innerHeight}px`,
// width: '100%',
// });
const myDocxPreviewer = ref(null);
const myXlsxPreviewer = ref(null);
// 判断文件类型
const judgeFileType = () => {
fileMessage.fileName = file.value.fileName;
fileMessage.downloadUrl = file.value.downloadUrl;
fileMessage.fileId = file.value.id;
console.log(fileMessage, 'fileMessage');
if (
fileMessage.fileName.endsWith('png') ||
fileMessage.fileName.endsWith('jpg') ||
fileMessage.fileName.endsWith('jpeg') ||
fileMessage.fileName.endsWith('gif')
) {
fileMessage.imgShow = true;
} else if (fileMessage.fileName.endsWith('docx') || fileMessage.fileName.endsWith('doc')) {
fileMessage.docShow = true;
} else if (fileMessage.fileName.endsWith('pdf') || fileMessage.fileName.endsWith('txt')) {
emit('close');
window.open(fileMessage.downloadUrl);
} else if (fileMessage.fileName.endsWith('pptx') || fileMessage.fileName.endsWith('ppt')) {
fileMessage.pptShow = true;
} else if (fileMessage.fileName.endsWith('xlsx') || fileMessage.fileName.endsWith('xls')) {
fileMessage.excelShow = true;
} else if (fileMessage.fileName.endsWith('mp3')) {
fileMessage.audioShow = true;
} else if (fileMessage.fileName.endsWith('mp4')) {
fileMessage.videoShow = true;
} else if (fileMessage.fileName.endsWith('zip')) {
MessagePlugin.warning('压缩文件暂不支持预览,请下载后查看');
emit('close');
}
};
const clickClose = () => {
emit('close');
};
onMounted(async () => {
await judgeFileType();
if (fileMessage.docShow) {
myDocxPreviewer.value = jsPreviewDocx.init(document.getElementById('docx'));
myDocxPreviewer.value
.preview(fileMessage.downloadUrl)
.then((res) => {
console.log('预览完成');
})
.catch((e) => {
console.log('预览失败', e);
});
} else if (fileMessage.excelShow) {
myXlsxPreviewer.value = jsPreviewExcel.init(document.getElementById('xlsx'));
myXlsxPreviewer.value
.preview(fileMessage.downloadUrl)
.then((res) => {
console.log('预览完成');
})
.catch((e) => {
console.log('预览失败', e);
});
}
});
return {
fileMessage,
clickClose,
// fileStyle,
};
},
});
</script>
<style scoped lang="less">
img {
width: 620px;
height: 620px;
}
audio {
width: 100%;
}
video {
width: 80%;
}
.d-flex {
display: flex;
align-items: center;
justify-content: center;
}
</style>
使用方法:
<!-- 文件预览 -->
<preview-file v-if="previewFiles.fileShow" :visible="previewFiles.fileShow" :file="previewFiles.fileMessage" @close="()=>{
previewFiles.fileShow = false;
}" />