關於 EasyExcel 導出下載文件需要知道的那些事


Part 1. 前言

好記性不如爛筆頭,本着自己已經在開發過程中花費了大把時間去檢索“為什么不行”以及“該怎么辦”的檢索過程,故在這里進行整理和歸納,也將所參考的文章羅列在Part 0中,部分解決方式也經過了校驗,方便大家在遇到相同問題時可以方便在茫茫的 cv 博客中找到真正能解決問題的好文(滑稽.jpg

講講我為什么會遇到這個問題,首先業務測使用的文件下載工具采用的是 EasyExcel,這里放上 EasyExcel文檔方便大家檢索使用,我采用的是最簡單的寫的方式,需要明確一點,寫 excelweb 端下載 excel 的區別:

Part 2. EasyExcel 寫文件

在最簡單的寫 excel 中,EasyExcel 所需要的條件即文件名/文件路徑、表頭數據、sheet 名以及寫入的數據,以官網示例為例如下:

// WriteTest.java
EasyExcel.write(fileName, DemoData.class).sheet("模板").doWrite(data());

private List<DemoData> data() {
    List<DemoData> list = new ArrayList<DemoData>();
    for (int i = 0; i < 10; i++) {
        DemoData data = new DemoData();
        data.setString("字符串" + i);
        data.setDate(new Date());
        data.setDoubleData(0.56);
        list.add(data);
    }
    return list;
}

// DemoData.java
import lombok.Data;

@Data
public class DemoData {
    @ExcelProperty("字符串標題")
    private String string;
    @ExcelProperty("日期標題")
    private Date date;
    @ExcelProperty("數字標題")
    private Double doubleData;
}

需要注意的是,這里說的是文件名或文件路徑,當 fileName 具體到文件路徑時,excel 文件寫后即寫在該路徑下,若 fileName 為文件名時,會寫在該項目的根目錄下

以上兩種方式的寫 excel ,都並不是 web 端下載的方式(即瀏覽器下載文件的形式)來得到的,這是我最開始誤會的地方

Part 3. EasyExcel web 端寫文件

在實現 web 端的寫文件之前,這里需要先明確一下自己 web 頁面寫文件的方式是哪一種,我這里的業務采用的是 jQuery 的 Ajax 的 Post 請求方式,過程里訪問接口一直都能夠正常訪問,但就是沒有執行 web 端的文件下載,接口返回的盡是些亂碼,於是我就踏上了不斷檢索的道路,很慶幸檢索到和我遇到相同問題的道友,並進一步驗證了他的說法,下面就來談談為什么可以訪問接口但是返回亂碼且不執行 web 端下載的問題:

首先 jQuery 所封裝的 ajax 它所能接收的數據類型需要明確一下,從下圖文檔中可以看到,dataType 在預期的接受類型中,並不包含有二進制流數據 blob,所以直接通過 $.ajax 的方式是無法滿足預期需求

網上有提供通過更新 xhr 的方式改變 $.ajaxresponseType解決方案,我驗證了下似乎沒有預期效果,因為不接受 blob 類型直接進 error 的回調函數中,報錯信息如下:

DOMException: Failed to read the 'responseText' property from 'XMLHttpRequest': The value is only accessible if the object's '' is '' or 'text' (was 'blob').

這邊也就不再多余的贅述,如果有成功的驗證,歡迎留言指正我的誤解,謝謝大家,下面介紹能夠正常使用的兩種方式

  • 通過 form 表單的形式進行提交

    var url = 'xxxxxxxxxxxx';
    var form = document.createElement('form');
    var xxx = document.createElement('input');
    
    form.setAttribute('style', 'display:none');
    form.setAttribute('target', '');
    form.setAttribute('method', 'post');
    form.setAttribute('action', url);
    
    xxx.type = 'hidden';
    xxx.name = 'xxx';
    xxx.value = param ? param : '';
    form.appendChild(xxx);
    
    // ...
    
    document.body.appendChild(form);
    form.appendChild(xxx);
    
    // ...
    
    form.submit();
    form.remove();
    
  • 通過原生 js 實現 ajax 的方式,即原生的XMLHttpRequest對象發出 HTTP 請求,對接收的數據先進行 createObjectURL 的包裝,再通過以 <a>標簽下載鏈接的方式觸發 web 端下載該文件

    var params = {xxx:xxx};
    
    var url = 'xxxxxxxxxxxx';
    var xhr = new XMLHttpRequest();
    xhr.open('POST', url, true); // 也可以使用POST方式,根據接口
    xhr.responseType = 'blob'; // 返回類型blob
    xhr.onload = function () {
    	if (this.status === 200) {
    		var blob = this.response;
    		const url = window.URL.createObjectURL(blob);
    		const a = document.createElement('a');
    		a.style.display = 'none';
    		a.href = url;
    		a.download = 'xxx.xlsx';
    		document.body.appendChild(a);
    		a.click();
    		window.URL.revokeObjectURL(url);
    	}
    };
    // 發送ajax請求
    xhr.send(params);
    

Part 0. Reference

  1. EasyExcel 使用說明 - 如何使用 EasyExcel
  2. web頁面實現文件下載的幾種方法 - 闡述 web 端文件下載方式
  3. EasyExcel實現下載Excel(解決無法從瀏覽器下載問題) - jQuery 的 ajax 無法接收二進制流
  4. Handle file download from ajax post
  5. Receiving binary data using JavaScript typed arrays - 二進制文件流
  6. jQuery.ajax() API 文檔 - ajax API 文檔
  7. 關於javascript:使用jQuery的ajax方法將圖片檢索為blob
  8. AJAX 之 XHR, jQuery, Fetch 的對比


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM