利用Ant Design of Vue组件自定义文件上传导入,并将数据导出
使用a-upload组件进行文件选取,customRequest自定义文件上传,配合a-model弹窗,选择文件后进行后续操作,例如:选择文件后输入文件的一些备注信息;
代码如下:
<template>
<a-spin tip="Loading..." :spinning="spinning">
<div>
<a-upload
:showUploadList="false"
name="file"
@change="handleChange"
:customRequest="(file) => openFileModal(file)"
>
<a-button type="primary" preIcon="ant-design:credit-card-outlined" style="margin-right: 15px;">导入</a-button>
</a-upload>
</div>
<div>
<a-button type="primary" preIcon="ant-design:export-outlined" :load="confirmLoding" @click="openOnExportXlsx"> 导出数据</a-button>
</div>
<a-modal v-model:visible="visible" title="请输入项目" @ok="onImportXls">
<a-form :model="projectData" style="padding-top: 1rem;">
<a-form-item label="项目" :rules="[{ required: true, message: '请填写项目!' }]" :labelCol="{ xxl: 4, xl: 4 }" :wrapperCol="{ xxl: 18, xl: 18 }">
<a-input v-model:value="projectData.project" />
</a-form-item>
</a-form>
</a-modal>
</a-spin>
</template>
<script lang="ts" name="milExcel" setup>
const visible = ref(false)
const spinning = ref(false)
let myFile = null
const openFileModal = (file) => {
visible.value = true
myFile = file
}
const onImportXls = async () => {
if (!projectData.project) return Message.error('请选择项目')
console.log(myFile)
if (!myFile.file.name.endsWith(".xls") && !myFile.file.name.endsWith(".xlsx")) {
return Message.error('请选择Excel文件导入');
}
const fd = new FormData()
fd.append('file', myFile.file)
fd.append('projectName', projectData.project)
spinning.value = true
await myImport(fd)
spinning.value = false
visible.value = false
Message.success('导入成功')
}
</script>
其中:blobOptions代表导出文件的类型,xlsx:‘application/vnd.openxmlformats-officedocument.spreadsheetml.sheet’
代码如下(示例):
<template xmlns="http://www.w3.org/1999/html">
<a-spin tip="转换中..." :spinning="spinning">
<a-card style="height: 100%" ref="logIndex">
<div class="log-header">
<div class="title-date" style="display:flex;">
<div>
<a-upload
:showUploadList="false"
name="file"
:customRequest="(file) => pdfToExcel(file)"
>
<a-button type="primary" preIcon="ant-design:credit-card-outlined" style="margin-right: 15px;">
PDF转换
</a-button>
</a-upload>
<a-radio-group v-model:value="fileStyleValue">
<a-radio :style="radioStyle" :value="1">PDF转EXCEL</a-radio>
<a-radio :style="radioStyle" :value="2">PDF转WORD</a-radio>
<a-radio :style="radioStyle" :value="3">PDF转PPT</a-radio>
</a-radio-group>
<div style="margin-bottom: 10px"></div>
<hr/>
<div style="margin-top: 15px">
<i><b>说明:</b></i><br>
功能:PDF文件转EXCEL、WORD、PPT文件<br>
操作:<br>
1、选择<i style="color: #2b4bcb">PDF转EXCEL</i> 或 <i style="color: #2b4bcb">PDF转WORD</i> 或 <i style="color: #2b4bcb">PDF转PPT</i><br>
2、点击<i style="color: #2b4bcb">PDF转换按钮</i>选择PDF文件<br>
3、等待一段时间(依转换文件大小而定),浏览器界面自动生成相应类型文件(也可在<i style="color: #2b4bcb">此电脑/下载</i>文件夹下查看)
</div>
</div>
</div>
</div>
</a-card>
</a-spin>
</template>
<script setup lang="ts">
import { message } from 'ant-design-vue';
import { UploadOutlined } from '@ant-design/icons-vue';
import {defineComponent, reactive, ref} from 'vue';
import type { UploadChangeParam } from 'ant-design-vue';
import { message as Message } from 'ant-design-vue'
import {defHttp} from "/@/utils/http/axios";
import {XLSX_FILE_SUFFIX, XLSX_MIME_TYPE} from "/@/hooks/system/useMethods";
const spinning = ref(false);
const fileStyleValue = ref<number>(1);
const radioStyle = reactive({
height: '30px',
lineHeight: '30px',
});
const paramsMap = reactive({
urlMap: {
exportUrl: "/intelligentoffice/materialExcel/uMaterialExcel/pdfToExcel",
},
})
let myFile = null
const pdfToExcel = async (file) => {
const fileName = file.file.name;
spinning.value = true
if (!file.file.name.endsWith(".pdf")) {
spinning.value = false
return Message.error('请选择PDF文件导入');
}
const fd = new FormData()
fd.append('file', file.file)
fd.append('fileStyle', fileStyleValue.value)
await pdfToExcels(fd,fileName)
spinning.value = false
}
// const initExportXlsxParams= ()=>{
// let paramsForm = Object.assign({}, projectListData);
// paramsForm.project = projectListData.projectSelect
// return paramsForm;
// }
const pdfToExcels = async (fd,fileName) => {
const data = await defHttp.post({ url: paramsMap.urlMap.exportUrl,responseType: 'blob',params: fd}, {joinParamsToUrl: true, isTransformResponse: false});
if (!data) {
Message.warning('文件下载失败');
return;
}
let link = document.createElement('a');
if (fileStyleValue.value === 1){
let blobOptions = {type: XLSX_MIME_TYPE};
let fileSuffix = XLSX_FILE_SUFFIX;
let url = window.URL.createObjectURL(new Blob([data], blobOptions));
link.style.display = 'none';
link.href = url;
link.setAttribute('download', fileName.split('.pdf')[0] + fileSuffix);
document.body.appendChild(link);
link.click();
document.body.removeChild(link); //下载完成移除元素
window.URL.revokeObjectURL(url); //释放掉blob对象
}else if (fileStyleValue.value === 2){
let blobOptions = {type: 'application/msword'};
let url = window.URL.createObjectURL(new Blob([data], blobOptions));
link.style.display = 'none';
link.href = url;
link.setAttribute('download', fileName.split('.pdf')[0] + '.docx');
document.body.appendChild(link);
link.click();
document.body.removeChild(link); //下载完成移除元素
window.URL.revokeObjectURL(url); //释放掉blob对象
}else if (fileStyleValue.value === 3){
let blobOptions = {type: 'application/vnd.ms-powerpoint'};
let url = window.URL.createObjectURL(new Blob([data], blobOptions));
link.style.display = 'none';
link.href = url;
link.setAttribute('download', fileName.split('.pdf')[0] + '.pptx');
document.body.appendChild(link);
link.click();
document.body.removeChild(link); //下载完成移除元素
window.URL.revokeObjectURL(url); //释放掉blob对象
}
}
</script>
<style scoped lang="less">
.total-box {
height: 80px;
margin-top: 16px;
display: flex;
justify-content: space-between;
.total-item {
width: 100%;
// background-color: #fafafa;
}
}
.item-text {
height: 40px;
font-size: 18px;
color: #00bb00;
background-color: #e9ebec;
display: flex;
justify-content: center;
align-items: center;
}
.item-title {
font-size: large;
height: 24px;
display: flex;
background-color: #e9ebec;
justify-content: center;
align-items: center;
}
.box-content {
margin-top: 1%;
flex-wrap: wrap;
justify-content: space-between;
}
.log-content {
height: 460px;
margin-top: 10px;
display: flex;
flex-wrap: wrap;
justify-content: space-between;
.content-item {
width: 100%;
height: 100%;
// background-color: #fff;
border: 1px solid rgba(0, 0, 0, 1.07);
box-shadow: 0px 2px 4px rgba(0, 0, 0, 0.1);
border-radius: 10px;
}
}
.red {
color: red;
}
.green {
color: #00bb00;
}
</style>
`写的不好,仅供备忘,供自己后续查看