当前位置 : 主页 > 网络编程 > JavaScript >

Vue项目导入导出文件功能以及导出文件后乱码问题及解决

来源:互联网 收集:自由互联 发布时间:2023-02-08
目录 vue项目导入导出功能 1.导出 2.导入 3.另一种方法实现文件上传 vue项目导入导出功能 1.导出 导出功能其实很简单,只需要调用后端的接口即可,不过有一些需要注意的地方,具体代
目录
  • vue项目导入导出功能
    • 1.导出
    • 2.导入
    • 3.另一种方法实现文件上传

vue项目导入导出功能

1.导出

导出功能其实很简单,只需要调用后端的接口即可,不过有一些需要注意的地方,具体代码如下所示:

这是导出按钮,定义导出的点击事件:

<a-button type="primary" @click="downExcel">
      <template #icon>
            <UploadOutlined />
     </template>
     导出    
</a-button>

js部分,调用接口,导出文件:

// 导出excel
        const downExcel = () => {
            if (state.selectedRowKeys.length == 0) {
                Message.warning("请先选择需要导出的数据")
                return
            }
            // const date = moment(new Date()).format("YYYY-MM")
            const params = {
                exportUserIds: state.selectedRowKeys
            }
            const hideLoading = message.loading("文件导出中...", 0)
            apiDownExcel(params)
                .then((res: any) => {
                    if (res.status == 200) {
                        const system = window.navigator.platform == "Win32" ? "window" : "mac"
                        const link = document.createElement("a")
                        const blob = new Blob([res.data], { type: "application/vnd.ms-excel" })
                        link.href = URL.createObjectURL(blob)
                        link.download = `月度薪资.${system == "mac" ? "xlw" : "xls"}` //下载的文件名
                        document.body.appendChild(link)
                        link.click()
                        document.body.removeChild(link)
                    }
                })
                .finally(() => {
                    setTimeout(hideLoading, 0)
                })
        }

在这里需要注意的是:

点击导出按钮,接口跑通后,文件会成功导出,不过打开文件会出现乱码,这个时候我们需要配置下接口,具体代码如下所示:

// 导出月度薪资
export const apiDownExcel = (params: object) => {
    return request({
        url: "/api/slaughter_smart/mySalaryMonthResult/exportExcel",
        method: "post",
        data: params,
        responseType: "blob",
    })
}

需要设置 ** responseType: “blob” ** 即可正常打开该文件。

2.导入

导入功能也不难,ant-design-vue已经封装了上传组件,我们按照upload上传组件开发即可,具体代码如下所示:

<a-upload
     name="file"
     action="/api/slaughter_smart/mySalaryMonthResult/importExcel"
     :headers="{ Authorization: token, 'Muyuan-Auth': token }"
     accept=".xls,.xlsx"
     :multiple="false"
     :showUploadList="false"
     @change="uploadChangeHandle
>
     <a-button type="primary">
          <template #icon>
              <DownloadOutlined />
          </template>
          导入  
     </a-button>
</a-upload>

解析:

action是上传文件请求的路径,headers里面设置了token,accept表示接受文件的格式,multiple表示是否上传多个文件,showUploadList表示是否展示uploadList,@change则表示上传文件改变时的状态,上传文件有三种状态,分别是uploading、done以及error。

使用action作为上传文件的接口路径,通常是没有携带token的,所以需要在请求头里自定义带上token。

文件上传后js部分代码:

// 文件状态 -- 上传文件后更新列表
        const uploadChangeHandle = (data: any) => {
            if (data.file.status == "done") {
                Message.success("文件导入成功")
                getList()
            }
            if (data.file.status == "error") {
                Message.error(data.file.response.message ? data.file.response.message : "文件导入失败")
                getList()
            }
        }

当然,还有其他的情况,还可以使用自定义上传的方式,通过customRequest覆盖默认上传的方式

3.另一种方法实现文件上传

接口部分:

// 导入月度薪资
export const apiImportExcel = (params: any) => {
    return request({
        url: '/api/slaughter_smart/mySalaryMonthResult/importExcel',
        method: 'post',
        data: params,
        headers: {
            'Content-Type': 'multipart/form-data'
        }
    })
}

html部分:

<!-- 导入模板弹框 -->
        <a-modal title="导入" :visible="modalDate.importVisivle" @cancel="cancelModal" :maskClosable="false" :footer="null" :width="540">
            <div>
                <a-button type="primary" ghost @click="downloadTemplateClick">
                    <template #icon>
                        <DownloadOutlined />
                    </template>
                    模板下载
                </a-button>
                <div style="font-size: 14px;color: #FF4122;font-weight: 400;margin-top: 5px">(注:请按照模板进行设计,如与模板不符将无法录入)</div>
            </div>
            <div style="margin-top: 30px">
                <a-upload :showUploadList="false" accept=".xls,.xlsx,xlw" :customRequest="customRequestChange">
                    <a-button type="primary" ghost v-if="!modalDate.fileList.length">
                        <UploadOutlined />
                        上传文件
                    </a-button>
                    <a-button type="primary" ghost disabled v-else>
                        <UploadOutlined />
                        上传文件
                    </a-button>
                </a-upload>
                <div class="martp_15">
                    <div class="dis_flex flex_y_center" v-for="(item, index) in modalDate.fileList" :key="index">
                        <i class="iconfont icon-paperclip marrt_10" style="font-size: 14px;color: #0194FE"></i>
                        <span style="color: #0194FE">{{ item.name }}</span>
                        <i class="iconfont icon-icon_close_remove" style="font-size: 20px;margin-left: 15px" @click.stop="deleteFileClick(index)"></i>
                    </div>
                </div>
            </div>
            <div class="text_right" style="margin-top: 20px">
                <a-button class="marrt_15" type="primary" v-prevent-click @click="imporSaveClick">确认</a-button>
                <a-button
                    @click="cancelModal"
                >取消</a-button
                >
            </div>
        </a-modal>

该弹框打开后效果如下图所示:

js部分:

// 自定义导入
        const customRequestChange = (options: any) => {
            modalDate.fileList.push(options.file)
        }
        
// 点击确认上传文件
        const imporSaveClick = () => {
            if (modalDate.fileList.length == 0) {
                message.warning("请选择上传的文件")
                return false
            }
            const params = new FormData()
            modalDate.fileList.forEach((item: any)=> {
                params.append("file", item)
            })
            apiImportExcel(params).then((res: any)=>{
                if (res.data.status == 200 && res.data.rel) {
                    getList()
                    message.success("上传成功!")
                    modalDate.importVisivle = false
                    modalDate.fileList = []
                }else {
                    message.error(res.data.message)
                }
            })
        }

该写法只能上传一个文件!!!

以上为个人经验,希望能给大家一个参考,也希望大家多多支持易盾网络。

网友评论