封装导出工具类

This commit is contained in:
linxd
2025-07-01 09:25:22 +08:00
parent 6c5c5528cb
commit 4e4b9a730d
5 changed files with 57 additions and 113 deletions

View File

@ -2,13 +2,11 @@ import React, { useState, useEffect } from 'react';
import { import {
Button, Button,
Table, Table,
Space,
Input, Input,
Select, Select,
Form, Form,
Tooltip, Tooltip,
Tag, Tag,
DatePicker,
message message
} from 'antd'; } from 'antd';
import type { TablePaginationConfig } from 'antd'; import type { TablePaginationConfig } from 'antd';
@ -17,10 +15,10 @@ import {
DeleteOutlined, DeleteOutlined,
ExportOutlined ExportOutlined
} from '@ant-design/icons'; } from '@ant-design/icons';
import CategorySelector from '@/components/CategorySelector/CategorySelector'; import { AnnualReviewYears, AnnualReviewResultText, AnnualReviewResultColor } from '@/dicts/dataStatistics';
import { AnnualReviewYears, AnnualReviewResultText, AnnualReviewResultColor, SupplierTypeText } from '@/dicts/dataStatistics'; import { getSupplierAnnualReviewStatistics } from '@/servers/api/dataStatistics';
import { getSupplierAnnualReviewStatistics, exportSupplierAnnualReviewStatistics } from '@/servers/api/dataStatistics';
import './supplierAnnualStatistics.less'; import './supplierAnnualStatistics.less';
import { downloadFile } from '@/utils/download';
const { Option } = Select; const { Option } = Select;
@ -190,21 +188,7 @@ const SupplierAnnualStatistics: React.FC = () => {
// 导出功能 // 导出功能
const handleExport = () => { const handleExport = () => {
const values = form.getFieldsValue(); const values = form.getFieldsValue();
exportSupplierAnnualReviewStatistics(values) downloadFile('/dataStatistics/exportSupplierAnnualReviewStatistics', 'GET', values);
.then(response => {
// 创建a标签进行下载
const url = window.URL.createObjectURL(new Blob([response]));
const link = document.createElement('a');
link.href = url;
link.setAttribute('download', `供应商年审情况统计_${new Date().getTime()}.xlsx`);
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
})
.catch(error => {
console.error('导出失败:', error);
message.error('导出失败');
});
}; };
return ( return (

View File

@ -23,6 +23,7 @@ import { getSupplierEvaluateStatistics, exportSupplierEvaluateStatistics } from
import { getAllEvaluateRules } from '@/servers/api/supplierEvaluate'; import { getAllEvaluateRules } from '@/servers/api/supplierEvaluate';
import type { EvaluateRuleItem } from '@/servers/dao/supplierEvaluateTask'; import type { EvaluateRuleItem } from '@/servers/dao/supplierEvaluateTask';
import './supplierEvaluateStatistics.less'; import './supplierEvaluateStatistics.less';
import { downloadFile } from '@/utils/download';
const { Option } = Select; const { Option } = Select;
const { RangePicker } = DatePicker; const { RangePicker } = DatePicker;
@ -209,21 +210,7 @@ const SupplierEvaluateStatistics: React.FC = () => {
// 更新handleExport方法实现真实导出功能 // 更新handleExport方法实现真实导出功能
const handleExport = () => { const handleExport = () => {
const values = form.getFieldsValue(); const values = form.getFieldsValue();
exportSupplierEvaluateStatistics(values) downloadFile('/dataStatistics/exportSupplierEvaluateStatistics', 'GET', values);
.then(response => {
// 创建a标签进行下载
const url = window.URL.createObjectURL(new Blob([response]));
const link = document.createElement('a');
link.href = url;
link.setAttribute('download', `供应商评价情况统计_${new Date().getTime()}.xlsx`);
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
})
.catch(error => {
console.error('导出失败:', error);
message.error('导出失败');
});
}; };
return ( return (

View File

@ -22,6 +22,7 @@ import { SupplierTypeText } from '@/dicts/dataStatistics';
import { getSupplierExitStatistics, exportSupplierExitStatistics } from '@/servers/api/dataStatistics'; import { getSupplierExitStatistics, exportSupplierExitStatistics } from '@/servers/api/dataStatistics';
import moment from 'moment'; import moment from 'moment';
import './supplierExitStatistics.less'; import './supplierExitStatistics.less';
import { downloadFile } from '@/utils/download';
const { Option } = Select; const { Option } = Select;
const { RangePicker } = DatePicker; const { RangePicker } = DatePicker;
@ -199,21 +200,7 @@ const SupplierExitStatistics: React.FC = () => {
// 导出功能 // 导出功能
const handleExport = () => { const handleExport = () => {
const values = form.getFieldsValue(); const values = form.getFieldsValue();
exportSupplierExitStatistics(values) downloadFile('/dataStatistics/exportSupplierExitStatistics', 'GET', values);
.then(response => {
// 创建a标签进行下载
const url = window.URL.createObjectURL(new Blob([response]));
const link = document.createElement('a');
link.href = url;
link.setAttribute('download', `供应商退出情况统计_${new Date().getTime()}.xlsx`);
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
})
.catch(error => {
console.error('导出失败:', error);
message.error('导出失败');
});
}; };
return ( return (

View File

@ -22,6 +22,7 @@ import { SupplierTypeText } from '@/dicts/dataStatistics';
import { getSupplierQualificationExpire, exportSupplierQualificationExpire } from '@/servers/api/dataStatistics'; import { getSupplierQualificationExpire, exportSupplierQualificationExpire } from '@/servers/api/dataStatistics';
import moment from 'moment'; import moment from 'moment';
import './supplierQualificationWarningStatistics.less'; import './supplierQualificationWarningStatistics.less';
import { downloadFile } from '@/utils/download';
const { Option } = Select; const { Option } = Select;
const { RangePicker } = DatePicker; const { RangePicker } = DatePicker;
@ -230,21 +231,7 @@ const SupplierQualificationWarningStatistics: React.FC = () => {
]; ];
} }
exportSupplierQualificationExpire(exportParams) downloadFile('/dataStatistics/exportSupplierQualificationExpire', 'GET', exportParams);
.then(response => {
// 创建a标签进行下载
const url = window.URL.createObjectURL(new Blob([response]));
const link = document.createElement('a');
link.href = url;
link.setAttribute('download', `供应商资质预警统计_${new Date().getTime()}.xlsx`);
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
})
.catch(error => {
console.error('导出失败:', error);
message.error('导出失败');
});
}; };
return ( return (

View File

@ -1,58 +1,57 @@
/**
* 通用文件下载工具(基于 umi-request + file-saver
*/
import { extend } from 'umi-request';
import { saveAs } from 'file-saver'; import { saveAs } from 'file-saver';
// 单独配置一个不拦截响应的 request 实例
const downloadRequest = extend({
timeout: 10000,
responseType: 'blob', // 关键
credentials: 'include', // 根据实际需要携带 cookie
prefix: REQUEST_BASE,
});
/** /**
* 下载文件通用函数 * 更稳妥的文件下载方法(绕过 umi-request避免被 JSON 解析)
* @param url 请求地址
* @param params 请求参数(可选)
* @param filename 下载后的文件名(可选)
* @param method 请求方法(默认 POST
*/ */
export async function downloadFile({ export async function downloadFile(
url, url: string,
params, method: 'GET' | 'POST' = 'POST',
filename, params?: Record<string, any>
method = 'POST', ) {
}: {
url: string;
params?: Record<string, any>;
filename?: string;
method?: 'GET' | 'POST';
}) {
try { try {
const blob: Blob = await downloadRequest(url, { const cleanedParams: Record<string, any> = {};
method, if (params) {
data: method === 'POST' ? params : undefined, Object.entries(params).forEach(([key, value]) => {
params: method === 'GET' ? params : undefined, if (value !== undefined && value !== null && value !== '') {
}); cleanedParams[key] = value;
}
// 尝试从响应头中获取文件名 });
const contentDisposition = (blob as any).response?.headers?.get?.('content-disposition');
let finalFilename = filename;
if (!finalFilename && contentDisposition) {
const match = contentDisposition.match(/filename="?([^"]+)"?/);
if (match && match[1]) {
finalFilename = decodeURIComponent(match[1]);
}
} }
finalFilename = finalFilename || '下载文件'; const fetchUrl =
method === 'GET' && params
? `${REQUEST_BASE}${url}?${new URLSearchParams(cleanedParams as any).toString()}`
: `${REQUEST_BASE}${url}`;
saveAs(blob, finalFilename); const response = await fetch(fetchUrl, {
} catch (error) { method,
console.error('文件下载失败:', error); headers: {
'Content-Type': 'application/json',
},
body: method === 'POST' ? JSON.stringify(params) : undefined,
credentials: 'include',
});
const contentType = response.headers.get('content-type') || '';
if (contentType.includes('text/html')) {
const htmlText = await response.text();
console.error('服务器返回 HTML 页面,可能是未登录或接口错误:', htmlText.slice(0, 300));
return;
}
if (!response.ok) {
const text = await response.text();
console.error(`请求失败(${response.status}`, text);
return;
}
const disposition = response.headers.get('content-disposition') || '';
const match = disposition.match(/filename="?([^"]+)"?/);
const fileName = match ? decodeURIComponent(match[1]) : '下载文件.xlsx';
const blob = await response.blob();
saveAs(blob, fileName);
} catch (err) {
console.error('下载失败:', err);
} }
} }