vue3 文件excel,word等文档的导入(上传)组件和导出(下载)功能

149 阅读2分钟

excel表格导出 -- 下载功能

先装包

    npm install file-saver

http请求配置 -- 对请求的url地址做筛选处理

// 添加请求拦截器
http.interceptors.request.use(
	function (config: any) {
		// head保存指定header字段 -- 常规处理
		const cookieTmToken = useCookie('tm-token')
		config.headers.Authorization = cookieTmToken.value
		config.responseType = 'json'
		// blob
		if (
			config.url.includes('downloadTemplateFile') ||
			config.url.includes('export') ||
			config.url.includes('downLoad')
		) {
                    // head保存指定header字段 -- 下载处理
			config.responseType = 'blob'
		}
		return config
	},
	function (error) {
		// 对请求错误做些什么
		return Promise.reject(error)
	}
)

使用

import { saveAs } from 'file-saver'

const historyOut = () => {
  // 请求接口获取表格数据
	exportHistory({ ...historyId.value })
		.then((response: any) => {
			const blob = new Blob([response.data])

			// 保存文件到本地
			saveAs(blob,`历史数据.xlsx')
		})
		.catch(error => {
			console.error('下载Excel文件时出错:', error)
		})
}

excel表格导入 -- 上传按钮

组件封装

<el-button
		v-if="prop.leadIn !== ''"
		class="add"
		type="primary"
		:style="{ padding: '0px', height: '42px' }"
		@click="spot"
	>
		<label
			:form="
				'uploadID' +
				(((1 + Math.random()) * 0x10000) | 0).toString(16).substring(1)
			"
			class=""
			:style="{ padding: ' 20px', cursor: 'pointer' }"
		>
			<i class="ri-download-2-line mr-1"></i>
			{{ prop.text }}
			<input
				:id="
					'uploadID' +
					(((1 + Math.random()) * 0x10000) | 0).toString(16).substring(1)
				"
				ref="uploadInputFile"
				accept=".xlsx"
				class="hidden"
				:style="{ display: 'none' }"
				type="file"
				@change="handleUpload"
			/>
		</label>
	</el-button>
// 向父组件发送信息
const emit: any = defineEmits(['spot'])

// 父组件信息
const prop: any = defineProps({
	// 文字按钮
	text: {
		type: String,
		default: '',
	},
	// 导入按钮 -- 通过switch判断请求哪个接口
	leadIn: {
		type: String,
		default: '',
	},
	// 成功回调
	callback: {
		type: Function,
		default: () => {},
	},
})

// 点击按钮
const spot = () => {
	emit('spot')
}


// 上传按钮对象
const uploadInputFile = ref()

// 文件上传逻辑
const handleUpload = async (fileData: any) => {
	try {
		const file = fileData.target.files[0]
		if (!file) {
			return false
		}
		// 限制的格式范围 --  根据不同要求修改限制类型
		const txtName = '.xlsx'
		// 校验-把路径中的所有字母全部转换为小写
		const extName = file.name
			.substring(file.name.lastIndexOf('.'))
			.toLowerCase()
		const extSize = file.size
		// 判断格式
		if (!txtName.includes(extName)) {
			ElMessage({
				message: '请上传正确的文件格式!如:' + txtName,
				type: 'warning',
			})
			uploadInputFile.value.value = null
			return false
		}
		// 判断大小
		if (extSize / 1000 / 1000 > 50) {
			ElMessage({
				message: '请上传小于 50M 的文件!',
				type: 'warning',
			})
			uploadInputFile.value.value = null
			return false
		}
		if (!file) return false
		// 开始上传

		ElMessage({
			message: '导入中...',
			type: 'success',
		})

		const formData: any = new FormData()
		formData.append('file', file)
		if (prop.params) {
			Object.keys(prop.params).forEach(key => {
				formData.append(key, prop.params[key])
			})
		}
		let res: any = null
		switch (prop.leadIn) {
			// 用户管理-学生导入 请求接口
			case 'student':
				res = await importStudent(formData)
				break
			// 科普知识-心理维度导入
			case 'questionDimension':
				res = await importQuestionDimension(formData)
				break
			// 科普知识-问题导入
			case 'question':
				res = await importQuestion(formData)
				break
			// 科普知识-心理量表导入
			case 'scale':
				res = await importScale(formData)
				break
		}
		ElMessage({
			message: '导入成功',
			type: 'warning',
		})

		uploadInputFile.value.value = null
		// 成功回调
		prop.callback(res)
	} catch (error: any) {
		uploadInputFile.value.value = null
	}
}

组件使用

	<BtnBox text="心理量表导入" leadIn="scale" :callback="scaleIn" />
// 心理量表导入  导入后的回调函数
const scaleIn = () => {
	getData()
}