vue3 封装图片上传预览组件支持docx、excel、pdf、图片、txt格式
主要是使用vue-office来实现docx和excel、pdf插件来实现预览
插件下载插件
npm i @vue-office/docx
npm i @vue-office/excel
npm i @vue-office/pdf
<script setup lang="ts">
//引入VueOfficeDocx组件
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'
//引入VueOfficePdf组件
import VueOfficePdf from '@vue-office/pdf'
import * as FileApi from '@/api/system/file'
const message = useMessage() // 消息弹窗
const { t } = useI18n() // 国际化
const dialogVisible = ref(false) // 弹窗的是否展示
const formLoading = ref(false)
const src = ref('')
const docx = ref('')
const excel = ref('')
const pdf = ref('')
const txt = ref('')
const fileObj = ref<{ fileFormat: string; fileName: string }>({fileFormat: '',fileName: ''
})
let fileInfo
let fileUrl
const renderedHandler = () => {formLoading.value = false
}
const errorHandler = () => {formLoading.value = false
}
const open = async (data: any, url: string) => {src.value = ''docx.value = ''excel.value = ''pdf.value = ''txt.value = ''fileInfo = datadialogVisible.value = trueformLoading.value = truefileObj.value = await FileApi.getuploadInfo(url)fileUrl = await FileApi.getDownloadUrl(url)if (fileUrl) {try {if (fileObj.value.fileFormat === 'jpeg' ||fileObj.value.fileFormat === 'jpg' ||fileObj.value.fileFormat === 'png') {src.value = fileUrlformLoading.value = false} else {if (fileObj.value.fileFormat === 'xlsx' || fileObj.value.fileFormat === 'xls') {excel.value = fileUrl} else if (fileObj.value.fileFormat === 'docx') {docx.value = fileUrl} else if (fileObj.value.fileFormat === 'pdf') {pdf.value = fileUrl} else if (fileObj.value.fileFormat === 'txt') {try {const response = await fetch(fileUrl)txt.value = await response.text()formLoading.value = false} catch (e) {console.log(e)formLoading.value = false}} else {formLoading.value = false}console.log('fileObj.value.fileFormat', fileObj.value.fileFormat)}} finally {// formLoading.value = false}}
}
const close = () => {dialogVisible.value = false
}
const handleDownload = async () => {if (!fileUrl) {return}const response = await fetch(fileUrl)if (!response.ok) {message.success(t('common.downloadFail'))}const blob = await response.blob()const url = URL.createObjectURL(blob)const a = document.createElement('a')a.href = urla.download = fileInfo.fileName || fileObj.value.fileName + '.' + fileObj.value.fileFormata.click()
}
defineExpose({open
})
</script><template><Dialog v-model="dialogVisible" @close="close" width="900px" :destroy-on-close="true"><div class="preview-content" v-loading="formLoading"><img:src="src"alt=""style="width: 100%"v-if="fileObj.fileFormat === 'jpeg' ||fileObj.fileFormat === 'jpg' ||fileObj.fileFormat === 'png'"/><template v-else><vue-office-docx:src="docx"v-if="docx"style="width: 100%; height: 100%"@rendered="renderedHandler"@error="errorHandler"/><vue-office-excel:src="excel"v-if="excel"style="width: 100%; height: 100%"@rendered="renderedHandler"@error="errorHandler"/><vue-office-pdf:src="pdf"v-if="pdf"style="width: 100%; height: 100%"@rendered="renderedHandler"@error="errorHandler"/><div v-if="txt">{{ txt }}</div><span v-if="!docx && !excel && !pdf && !txt">文件类型暂不支持预览</span></template></div><template #icon><Icon class="is-hover mr-10px cursor-pointer" icon="ep:download" @click="handleDownload" /></template></Dialog>
</template><style scoped lang="scss">
.preview-content {position: relative;width: 100%;height: 600px;overflow: hidden;
}
</style>