使用POST下载Axios Excel文件会导致文件损坏
我以前使用Axios下载GET端点提供的文件。端点已更改,现在是POST,但不需要参数。我正在更新原始下载方法,但返回了一个损坏的文件使用POST下载Axios Excel文件会导致文件损坏,excel,reactjs,axios,Excel,Reactjs,Axios,我以前使用Axios下载GET端点提供的文件。端点已更改,现在是POST,但不需要参数。我正在更新原始下载方法,但返回了一个损坏的文件 downloadTemplate() { axios.post(DOWNLOAD_TEMPLATE_URL, { responseType: 'blob', headers: { 'Content-Disposition
downloadTemplate() {
axios.post(DOWNLOAD_TEMPLATE_URL,
{
responseType: 'blob',
headers: {
'Content-Disposition': "attachment; filename=template.xlsx",
'Content-Type': 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
}
})
.then((response) => {
const url = window.URL.createObjectURL(new Blob([response.data]));
const link = document.createElement('a');
link.href = url;
link.setAttribute('download', 'template.xlsx');
document.body.appendChild(link);
link.click();
})
.catch((error) => console.log(error));
}
我不确定问题是否与响应类型
、标题
有关,也不确定响应是如何处理的,或者上述所有问题。到目前为止,我已经尝试过各种各样的选择,但都不走运。如有任何建议,将不胜感激
我已经能够使用Postman下载该文件,因此我知道端点提供的文件很好。我只是无法在我的React代码中找到要执行此操作的参数。终于让它工作了!问题代码块中的
post
语法不正确,并且将responseType
更改为“arraybuffer”
工作示例如下:
downloadTemplate() {
axios.post(DOWNLOAD_TEMPLATE_URL, null,
{
headers:
{
'Content-Disposition': "attachment; filename=template.xlsx",
'Content-Type': 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
},
responseType: 'arraybuffer',
}
).then((response) => {
const url = window.URL.createObjectURL(new Blob([response.data]));
const link = document.createElement('a');
link.href = url;
link.setAttribute('download', 'template.xlsx');
document.body.appendChild(link);
link.click();
})
.catch((error) => console.log(error));
}
我们可以使用以下代码从POST方法导出Excel文件。愿它能帮助别人,节省时间 对于API,请使用.NETCore2.2,方法如下 注意:当我们创建FileStreamResult时,响应的内容处置头将包含文件名,流将作为附件 在启动文件中将“内容处置”添加到Cors
app.UseCors(b => b.AllowAnyHeader().AllowAnyMethod().AllowAnyOrigin().AllowCredentials().WithExposedHeaders("Content-Disposition"));
我正在使用该软件包生成Excel文件
using OfficeOpenXml;
using OfficeOpenXml.Style;
public static MemoryStream InvoiceToExcel(List<InvoiceSearchDto> invoices)
{
var listOfFieldNames = typeof(InvoiceSearchDto).GetProperties().Select(f => f.Name).ToList();
int cellCounter = 1, recordIndex = 2;
var ms = new MemoryStream();
using (ExcelPackage package = new ExcelPackage(ms))
{
ExcelWorksheet worksheet;
worksheet = package.Workbook.Worksheets.Add("New HGS");
// Setting the properties of the first row
worksheet.Row(1).Height = 20;
worksheet.Row(1).Style.HorizontalAlignment = ExcelHorizontalAlignment.Center;
worksheet.Row(1).Style.Font.Bold = true;
// Header of the Excel sheet
foreach (string header in listOfFieldNames)
{
worksheet.Cells[1, cellCounter++].Value = header;
}
// Inserting the article data into excel
// sheet by using the for each loop
// As we have values to the first row
// we will start with second row
foreach (InvoiceSearchDto invoice in invoices)
{
worksheet.Cells[recordIndex, 1].Value = invoice.CompanyName;
worksheet.Cells[recordIndex, 2].Value = invoice.CustomerNo;
worksheet.Cells[recordIndex, 3].Value = invoice.DocumentNumber;
worksheet.Cells[recordIndex, 4].Value = invoice.BillingPeriodStartDate.ToString("YYYY-MM-DD");
worksheet.Cells[recordIndex, 5].Value = invoice.BillingPeriodEndDate.ToString("YYYY-MM-DD");
worksheet.Cells[recordIndex, 6].Value = invoice.DateOfInvoice.ToString("YYYY-MM-DD");
worksheet.Cells[recordIndex, 7].Value = invoice.ExpirationDate.ToString("YYYY-MM-DD");
worksheet.Cells[recordIndex, 8].Value = invoice.Amount;
worksheet.Cells[recordIndex, 9].Value = invoice.InvoiceStatusText;
recordIndex++;
}
// By default, the column width is not
// set to auto fit for the content
// of the range, so we are using
// AutoFit() method here.
worksheet.Column(1).AutoFit();
worksheet.Column(2).AutoFit();
worksheet.Column(3).AutoFit();
worksheet.Column(4).AutoFit();
worksheet.Column(5).AutoFit();
worksheet.Column(6).AutoFit();
worksheet.Column(7).AutoFit();
worksheet.Column(8).AutoFit();
worksheet.Column(9).AutoFit();
package.Save();
}
ms.Position = 0;
return ms;
}
最后,React和axos代码如下所示
服务代码:
return http.post(
API_BASE_URL + "/Invoice/GetInvoiceWithExcel",
searchInvoice,
{
headers: getHeaders(), // for token and others
responseType: 'blob' // **don't forget to add this**
}
);
};
操作方法代码如下所示。在这里,我使用包下载文件
import { saveAs } from 'file-saver';
export const getInvoiceWithExcel = invoiceInfo => {
return dispatch => {
dispatch({
type: LOADING_ON
});
InvoiceService.getInvoiceWithExcel(invoiceInfo)
.then(res => {
console.log(res);
let filename = res.headers['content-disposition']
.split(';')
.find((n) => n.includes('filename='))
.replace('filename=', '')
.trim();
let url = window.URL
.createObjectURL(new Blob([res.data]));
saveAs(url, filename);
dispatch({
type: GET_INVOICE_EXCEL_SUCCESS,
payload: ""
});
dispatch({
type: LOADING_OFF
});
dispatch({
type: ON_NOTIFY,
payload: {
...res.data.notification
}
});
})
.catch(err => {
dispatch({
type: GET_INVOICE_EXCEL_FAILED
});
dispatch({
type: LOADING_OFF
});
dispatch({
type: ON_NOTIFY,
payload: {
...Utility.errorResponseProcess(err.response)
}
});
});
};
};
强烈建议您在单击链接后调用
revokeObjectURL(url)
,否则blob对象将保留在内存中,直到卸载文档(用户关闭选项卡!)。
import { saveAs } from 'file-saver';
export const getInvoiceWithExcel = invoiceInfo => {
return dispatch => {
dispatch({
type: LOADING_ON
});
InvoiceService.getInvoiceWithExcel(invoiceInfo)
.then(res => {
console.log(res);
let filename = res.headers['content-disposition']
.split(';')
.find((n) => n.includes('filename='))
.replace('filename=', '')
.trim();
let url = window.URL
.createObjectURL(new Blob([res.data]));
saveAs(url, filename);
dispatch({
type: GET_INVOICE_EXCEL_SUCCESS,
payload: ""
});
dispatch({
type: LOADING_OFF
});
dispatch({
type: ON_NOTIFY,
payload: {
...res.data.notification
}
});
})
.catch(err => {
dispatch({
type: GET_INVOICE_EXCEL_FAILED
});
dispatch({
type: LOADING_OFF
});
dispatch({
type: ON_NOTIFY,
payload: {
...Utility.errorResponseProcess(err.response)
}
});
});
};
};