做后臺系統的開發者幾乎都遇到過這個場景:運營同事要一份"用戶+訂單"的匯總報表,數據量不大,但分屬兩張表。最直覺的做法是寫兩個導出按鈕,或者把數據合并到一張表。前者體驗差,后者結構亂。其實Laravel生態里有個更干凈的解法——多Sheet單文件導出。
這篇技術筆記來自一位印尼開發者的實踐,核心依賴是maatwebsite/excel 3.1版本。整個方案五步走完,但第四步的設計值得細品。
![]()
先看前端。兩個日期選擇框加一個導出按鈕,點擊后把起止時間拼進URL參數,走GET請求到后端。沒有用什么花哨的異步交互,就是最簡單的window.location.href跳轉。這種"樸素"反而減少了出錯面——導出本來就是耗時操作,讓用戶等個頁面加載,比假裝即時響應更誠實。
控制器里的邏輯分層很清楚。從request里取日期范圍,分別查users表和orders表,各取兩列,最后map成二維數組。這里有個注釋值得注意:如果查詢變慢,建議拆Sheet并配合FromQuery和WithChunkReading。這不是廢話——當單表數據過百萬行時,一次性get()會直接把內存撐爆。但示例代碼為了可讀性,用了最簡單的get()->map(),把優化空間留給了注釋。
真正的設計在Export類和Sheet類。MyExport實現WithMultipleSheets接口,構造函數收兩個數據集,sheets()方法返回兩個MySheet實例,分別命名'Users'和'Orders'。這種"一個類管文件,一個類管Sheet"的分層,讓代碼有了復用性——下次要導"用戶+商品+庫存"三張表,改一下sheets()方法的返回數組就行。
MySheet類更細。它同時實現FromArray和WithTitle,array()方法里根據title判斷表頭:Users表輸出NAME/EMAIL,Orders表輸出INVOICE/TOTAL。這里用了if分支而不是傳參配置,看起來不夠"優雅",但勝在直觀。畢竟報表的表頭很少變動,硬編碼比抽象層更不容易出錯。
整個方案沒有涉及隊列、沒有分片下載、沒有前端進度條。它解決的是一個特定規模的問題:數據量中等、實時性要求不高、需要多表關聯呈現的場景。如果你的導出任務超過這個邊界,注釋里提到的FromQuery和WithChunkReading就是下一步。
最后提一下作者留下的聯系方式。raflizocky.netlify.app,PayPal和Saweria的打賞鏈接——典型的獨立開發者做內容變現的路子。技術文檔本身免費,信任建立后轉化外包需求。這種模式在東南亞開發者社區很常見,比國內"引流私域再賣課"的路徑更直接。
特別聲明:以上內容(如有圖片或視頻亦包括在內)為自媒體平臺“網易號”用戶上傳并發布,本平臺僅提供信息存儲服務。
Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.