导出文件主要还是文件下载的功能,导出数据配合下载方法
export const exportRequest=async(type:any,selectedKeys:any,url:any,fileName:any)=>{
setLoading(true);
try {
let obj = {exportType:type, idList:selectedKeys};
const res = await url(obj);
console.log(res);
if (res?.code == 0) {
let resData=res.data||res.msg;
const name=resData.substring(resData.lastIndexOf('/') + 1);
fileName=fileName?fileName:name;
downloadFile(baseUrl + resData + '?secret=' + keyId, fileName);
}
} catch (err) {
console.log(err);
} finally {
setLoading(false);
}
}
//下载文件
const keyId=encryptBySSC(useEncryptStore().getKeyId());
export const downloadFile=(url:any, fileName:any)=>{
fetch(url).then((res) => {
res.blob().then((blob) => {
const blobUrl = window.URL.createObjectURL(blob);
// 这里的文件名根据实际情况从响应头或者url里获取
const filename = fileName;
const a = document.createElement('a');
a.href = blobUrl;
a.download = filename;
a.click();
window.URL.revokeObjectURL(blobUrl);
});
});
}
导入(包含下载模板,导入文件)
两个文件参考文件上传、文件下载
<template>
<div>
<a-modal
:title="$t('common.import')"
class="import-modal no-bottom-line-modal"
v-model:visible="visible"
@close="handleClose"
title-align="start"
>
<div class="main">
<span class="download-template" @click="downloadTemplate"
>{{ $t('common.download.import.template') }} <icon-sync
rotate="90"
/></span>
<div class="limit-tips">{{ $t('common.import.excel.limit.tip') }}</div>
<div class="file">
<fileUploader
v-show="status == 1"
@onsuccess="uploadOnsuccess"
@beforeUpload="beforeUpload"
type="add"
:accept="accept"
:showUploadBtn="true"
:showFileList="false"
:fileSize="200"
>
<template #button>
<div class="unUpload">
<!-- 未上传 -->
<icon-upload size="18"/> 选择文件
</div>
</template>
</fileUploader>
<div class="state-block" v-if="status != 1">
<img alt="" src="./../../assets/images/mixedAsset/xls.png" />
<div class="state-desc" v-if="status == 2">
<!-- 导入中 -->
{{ $t('excel.on.importing') }}
<icon-close-circle-fill size="20" class="close" />
</div>
<div class="state-desc" v-if="status == 3">
<!-- 导入成功 -->
{{ $t('excel.import.succeeded') }}
<icon-check-circle-fill size="20" class="check" />
</div>
<div class="state-desc" v-if="status == 4">
<!-- 导入失败 -->
<div class="fail">
{{ $t('excel.import.error')
}}<span @click="status=1">{{ $t('excel.repeat.import') }}</span>
</div>
<icon-exclamation-circle-fill size="20" class="exclamation" />
</div>
</div>
</div>
</div>
</a-modal>
</div>
</template>
<script setup>
import {
ref,
reactive,
computed,
defineEmits,
watch,
toRaw,
getCurrentInstance,
onMounted,
nextTick
} from 'vue';
import { getToken } from '@/utils/auth';
import { Message } from '@arco-design/web-vue';
import { exportRequest } from '@/utils/mixedAsset/exportFile';
import fileUploader from '@/components/uploader/FileUploader.vue';
import { useI18n } from 'vue-i18n';
const { t } = useI18n();
const emit = defineEmits(['onsuccess','changeModalVisible','refreshTable']);
const props = defineProps({
templateUrl: Object,
ImportUrl: Object,
templateName:String,
/* visible:{
type:Boolean,
default:true
} */
});
const accept=ref(['.xls', '.xlsx']);
const visible = ref(true);
const handleClose=()=>{
emit('changeModalVisible',false);
}
const onChange = () => {};
const status = ref(1);
const beforeUpload=()=>{
status.value = 2;
}
const uploadOnsuccess = (arg) => {
console.log(arg);
let url = arg[0].url;
importFileRequest(url);
};
const importFileRequest = async (filePath) => {
console.log(props.ImportUrl);
let res = await props.ImportUrl({ filePath: filePath });
console.log(res);
if (res?.code == 0) {
status.value = 3;
} else {
status.value = 4;
}
};
const downloadTemplate = () => {
exportRequest(1, [0], props.templateUrl,props.templateName+t('common.import.template'));
};
</script>
<style scoped lang="less">
.import-modal {
.download-template {
color: rgb(var(--arcoblue-6));
cursor: pointer;
}
.limit-tips {
font-size: 14px;
color: var(--color-neutral-4);
line-height: 3em;
}
.file {
background: var(--color-neutral-2);
height: 80px;
width: 100%;
margin-top: 5px;
text-align: center;
}
.check {
color: rgb(var(--green-6));
}
.close {
color: rgb(var(--orange-6));
}
.exclamation {
color: rgb(var(--red-6));
}
.unUpload {
height: 40px;
line-height: 40px;
border-radius: 2px;
padding: 0 0.1rem;
background: transparent;
border: 1px dashed rgb(var(--arcoblue-5));
color: rgb(var(--arcoblue-6));
text-align: center;
margin: 20px auto;
}
.main {
padding: 0 10%;
}
.state-block{
display: flex;
flex-direction: row;
justify-content: space-between;
padding: 0 3%;
align-items:center;/*垂直居中*/
height: 100%;
img{
margin-right: 18px;
}
}
.state-desc{
flex: 1;
display: flex;
flex-direction: row;
justify-content: space-between;
align-items:center;/*垂直居中*/
}
.fail{
span{
color: rgb(var(--arcoblue-6));
cursor: pointer;
}
}
}
</style>