Laravel后端通过Ajax下载maatwebsite生成的Excel文件损坏问题
Laravel maatwebsite Excel导出正常但Ajax下载文件损坏的解决方法
问题原因分析
- jQuery代码存在拼写错误:
xhrFileds应为xhrFields,导致responseType: 'blob'未生效,响应被解析为字符串而非二进制数据,生成的Blob文件损坏。 - 手动设置的响应头可能与maatwebsite自动生成的头冲突,导致文件格式识别错误。
- Blob类型使用
application/octet-stream不够精确,xlsx文件需匹配对应专属MIME类型。
解决方案步骤
1. 修正控制器代码(移除冗余响应头)
maatwebsite的download方法会自动为xlsx文件设置正确的响应头,无需手动传入自定义头参数:
return $this->excel->download( new ExportDataObject( $data, $headers, "view_name", "sheet", ["header_widths" => [30,30,30,20,30]], ["timezone" => ""] ), 'TrpReport'.Date("dmY").'.xlsx' );
2. 修正jQuery Ajax代码(修复拼写+调整Blob类型)
$.ajax({ type: "POST", url: "/trips/download-report", data: { "id": 11 }, headers: { 'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content') }, xhrFields: { // 修正拼写错误 responseType: 'blob' }, success: function (response) { // 使用xlsx对应的正确MIME类型 var blob = new Blob([response], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' }); var link = document.createElement('a'); link.href = URL.createObjectURL(blob); // 从响应头自动获取文件名,避免硬编码 var contentDisposition = response.headers.get('Content-Disposition'); var filename = contentDisposition ? contentDisposition.match(/filename="?([^"]+)"?/)[1] : 'TrpReport.xlsx'; link.download = filename; document.body.appendChild(link); link.click(); document.body.removeChild(link); URL.revokeObjectURL(link.href); // 释放URL资源,避免内存泄漏 }, error: function (response) { alert(response.responseText); } });
额外说明
- xlsx文件的标准MIME类型为
application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,xls文件才使用application/vnd.ms-excel,需注意区分。 - 若必须自定义响应头,确保不覆盖maatwebsite自动生成的
Content-Type字段,避免文件格式识别异常。
内容的提问来源于stack exchange,提问作者Manu Joseph
相关产品推荐
相关产品推荐

