三十五、面向對象底層邏輯-Spring MVC中AbstractXlsxStreamingView的設計

在Web應用開發中,大數據量的Excel導出功能是常見需求。傳統Apache POI的XSSF實現方式在處理超大數據集時,會因全量加載到內存導致OOM(內存溢出)問題。Spring MVC提供的AbstractXlsxStreamingView通過流式處理機制,有效解決了這一痛點。本文將深入剖析其設計原理與實現細節。

一、設計背景與核心問題

當使用POI的XSSFWorkbook生成Excel時,所有數據會以DOM樹形式駐留內存。對于10萬行數據,內存占用可能高達數百MB。而AbstractXlsxStreamingView基于POI的SXSSF(Streaming Usermodel API)實現,采用"行窗"(Row Window)機制,僅保留固定行數在內存中,其余數據通過臨時文件持久化,將內存消耗控制在可接受范圍內。

二、類繼承體系解析
public abstract class AbstractXlsxStreamingView extends AbstractStreamingView {@Overrideprotected void renderMergedOutputModel(Map<String, Object> model, HttpServletRequest request,HttpServletResponse response) throws Exception {// 1. 創建SXSSFWorkbook實例SXSSFWorkbook workbook = createWorkbook();// 2. 構建Excel文檔核心方法buildExcelDocument(workbook, model, request, response);// 3. 設置響應頭response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");response.setHeader("Content-Disposition", "attachment; filename=" + getFilename());// 4. 流式寫入響應輸出流workbook.write(response.getOutputStream());// 5. 清理臨時資源workbook.dispose();}protected abstract void buildExcelDocument(SXSSFWorkbook workbook, Map<String, Object> model,HttpServletRequest request, HttpServletResponse response) throws Exception;
}
三、關鍵設計實現
  1. 流式工作簿創建
    protected SXSSFWorkbook createWorkbook() {return new SXSSFWorkbook(getWindowSize());
    }
    • getWindowSize()默認返回100,表示內存中保留的行數
    • 超過窗口大小的行會被寫入磁盤臨時文件
    • 通過workbook.setRandomAccessWindowSize()可動態調整窗口
  2. 樣式管理優化
    protected CellStyle createStyle(SXSSFWorkbook workbook, String styleKey) {Map<String, CellStyle> styles = getStylesMap(workbook);return styles.computeIfAbsent(styleKey, k -> {CellStyle style = workbook.createCellStyle();// 配置字體/邊框/對齊等樣式return style;});
    }
    • 使用線程安全的ConcurrentHashMap緩存樣式對象
    • 避免頻繁創建樣式導致的性能損耗
  3. 數據分片寫入
    SXSSFSheet sheet = workbook.createSheet();
    int rowNum = 0;
    for (DataItem item : dataList) {Row row = sheet.createRow(rowNum++);int colNum = 0;for (Field field : fields) {Cell cell = row.createCell(colNum++);cell.setCellValue(extractValue(item, field));}// 強制刷新到磁盤(可選)if (rowNum % FLUSH_INTERVAL == 0) {((SXSSFSheet)sheet).flushRows(FLUSH_INTERVAL);}
    }
    • 通過flushRows()手動控制刷盤時機
    • 平衡內存使用與IO開銷
四、性能優化策略
  1. 內存配置調優
    SXSSFWorkbook workbook = new SXSSFWorkbook(1000) {@Overrideprotected void finalize() throws Throwable {super.finalize();System.gc(); // 強制觸發臨時文件清理}
    };
    • 適當增大窗口大小(500-1000)可減少磁盤IO
    • 通過-Dorg.apache.poi.ss.util.SheetUtil.DEFAULT_COLUMN_WIDTH調整默認列寬
  2. 異步處理方案
    @GetMapping("/export")
    public Callable<View> exportAsync() {return () -> {// 長時間運行任務return new AbstractXlsxStreamingView() {// 實現build方法};};
    }
    • 結合@Async實現完全異步導出
    • 避免請求線程阻塞
  3. 資源清理機制
    • 調用workbook.dispose()刪除臨時文件
    • 在finally塊中確保資源釋放:
      try {workbook.write(outputStream);
      } finally {workbook.close();workbook.dispose();
      }
五、適用場景與擴展建議
  1. 典型適用場景
    • 日志數據導出(百萬級記錄)
    • 報表系統定時任務
    • 監控數據持久化
  2. 擴展方向
    • 集成EasyExcel實現注解驅動開發
    • 添加模板引擎支持(Freemarker/Thymeleaf)
    • 實現分片上傳到云存儲(OSS/S3)
六、總結

AbstractXlsxStreamingView通過流式處理機制,將Excel導出的內存占用從O(n)降低到O(1),完美解決了大數據量場景下的性能瓶頸。其設計體現了以下核心思想:

  1. 空間換時間:通過臨時文件持久化換取內存空間
  2. 分治策略:將大數據集拆分為可管理的行窗
  3. 資源預分配:樣式緩存機制減少重復創建開銷

在實際項目中,建議結合業務特點調整窗口大小,并采用異步處理機制提升用戶體驗。對于超大規模數據(千萬級),可考慮分庫分表查詢+多線程合并寫入等高級優化方案。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/84065.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/84065.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/84065.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

【大模型:知識圖譜】--3.py2neo連接圖數據庫neo4j

【圖數據庫】--Neo4j 安裝_neo4j安裝-CSDN博客 需要打開圖數據庫Neo4j&#xff0c; neo4j console 目錄 1.圖數據庫--連接 2.圖數據庫--操作 2.1.創建節點 2.2.刪除節點 2.3.增改屬性 2.4.建立關系 2.5.查詢節點 2.6.查詢關系 3.圖數據庫--實例 1.圖數據庫--連接 fr…

基于dify的營養分析工作流:3分鐘生成個人營養分析報告

你去醫院做體檢&#xff0c;需要多久拿到體檢報告呢&#xff1f;醫院會為每位病人做一份多維度的健康報告嗎&#xff1f;"人工報告需1小時/份&#xff1f;數據誤差率高達35%&#xff1f;傳統工具無法個性化&#xff1f; Dify工作流AI模型的組合拳&#xff0c;正在重塑健康…

Web后端基礎(基礎知識)

BS架構&#xff1a;Browser/Server&#xff0c;瀏覽器/服務器架構模式。客戶端只需要瀏覽器&#xff0c;應用程序的邏輯和數據都存儲在服務端。 優點&#xff1a;維護方便缺點&#xff1a;體驗一般 CS架構&#xff1a;Client/Server&#xff0c;客戶端/服務器架構模式。需要單獨…

MySQL(56)什么是復合索引?

復合索引&#xff08;Composite Index&#xff09;&#xff0c;也稱為多列索引&#xff0c;是在數據庫表的多列上創建的索引。它可以提高涉及多個列的查詢性能&#xff0c;通過組合多個列的值來索引數據。復合索引特別適用于需要同時過濾多列的查詢。 復合索引的優點 提高多列…

高并發下的緩存擊穿/雪崩解決方案

有效解決緩存擊穿和雪崩的方法包括&#xff1a;1. 使用互斥鎖處理緩存擊穿&#xff1b;2. 采用熔斷器模式防止雪崩&#xff1b;3. 實施緩存預熱和降級策略&#xff1b;4. 利用分片和多級緩存分散請求壓力。這些方法各有優劣&#xff0c;需根據實際業務場景靈活調整和結合使用。…

【讀論文】OpenAI o3與o4系統模型技術報告解讀

回顧一下,4月16日,OpenAI發布了一份關于其o系列新模型——OpenAI o3和OpenAI o4-mini——的System Card。這份文檔不僅揭示了這兩款模型在推理能力和工具使用方面的顯著進步,也詳細闡述了其訓練方法、數據來源、安全評估以及在圖像理解生成、數學推理等多個核心領域的表現。…

第1課、LangChain 介紹

LangChain 介紹 LangChain 是一個以大語言模型&#xff08;LLM, Large Language Model&#xff09;為核心的開發框架&#xff0c;旨在幫助開發者高效地將如 GPT-4 等大型語言模型與外部數據源和計算資源集成&#xff0c;構建智能化應用。 1.1 工作原理 如上圖所示&#xff…

【論文閱讀28】-CNN-BiLSTM-Attention-(2024)

本文把滑坡位移序列拆開、篩優質因子&#xff0c;再用 CNN-BiLSTM-Attention 來動態預測每個子序列&#xff0c;最后重構出總位移&#xff0c;預測效果超越傳統模型。 文章目錄 1 引言2 方法2.1 位移時間序列加性模型2.2 變分模態分解 (VMD) 具體步驟2.3.1 樣本熵&#xff08;S…

[論文閱讀] 人工智能+軟件工程(軟件測試) | 當大語言模型遇上APP測試:SCENGEN如何讓手機應用更靠譜

當大語言模型遇上APP測試&#xff1a;SCENGEN如何讓手機應用更靠譜&#xff1f; 一、論文基礎信息 論文標題&#xff1a;LLM-Guided Scenario-based GUI Testing&#xff08;《大語言模型引導的基于場景的GUI測試》&#xff09;作者及機構&#xff1a;Shengcheng Yu等&#x…

香橙派3B學習筆記7:snap安裝管理軟件包_打包程序與依賴

有時可以嘗試把程文件與其依賴一塊打包安裝&#xff0c;這里就學習一下。 ssh &#xff1a; orangepi本地ip 密碼 &#xff1a; orangepi 操作系統發行版&#xff1a; 基于 Ubuntu 20.04.6 LTS&#xff08;Focal Fossa&#xff09;的定制版本&#xff0c;專門為 Orange Pi 設備…

Playwright 測試框架 - .NET

??親愛的技術愛好者們,熱烈歡迎來到 Kant2048 的博客!我是 Thomas Kant,很開心能在CSDN上與你們相遇~?? 本博客的精華專欄: 【自動化測試】

Model Context Protocol (MCP) 是一個前沿框架

微軟發布了 Model Context Protocol (MCP) 課程&#xff1a;mcp-for-beginners。 Model Context Protocol (MCP) 是一個前沿框架&#xff0c;涵蓋 C#、Java、JavaScript、TypeScript 和 Python 等主流編程語言&#xff0c;規范 AI 模型與客戶端應用之間的交互。 MCP 課程結構 …

【量化】策略交易 - 均線策略(Moving Average Strategy)- 代碼增強版本

策略交易 - 均線策略&#xff08;Moving Average Strategy&#xff09;- 代碼增強版本 一、前言 本文主要是針對 【量化】策略交易 - 均線策略&#xff08;Moving Average Strategy&#xff09; 中的代碼事例&#xff0c;進行邏輯的增強&#xff0c;添加了模擬買入和賣出邏輯&…

為什么要引入內聯函數?

C 中引入內聯函數主要有以下幾個目的&#xff1a; 提高程序運行效率 - 普通函數調用會有一定的開銷&#xff0c;如保存現場、傳遞參數、跳轉到函數地址執行等。內聯函數在編譯時&#xff0c;會將函數體直接插入到調用處&#xff0c;避免了函數調用的開銷&#xff0c;從而提高程…

C++.OpenGL (17/64)模型(Model)

模型(Model) 模型系統架構 #mermaid-svg-Zaji5BPdvnIkXIVg {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-Zaji5BPdvnIkXIVg .error-icon{fill:#552222;}#mermaid-svg-Zaji5BPdvnIkXIVg .error-text{fill:#55222…

【Java學習筆記】System類

System 類 常用方法 方法描述System.exit()退出當前程序System.arraycopy(源數組&#xff0c;源數組起始索引&#xff0c;目標數組&#xff0c;目標數組起始索引&#xff0c;拷貝長度)復制數組元素&#xff0c;比較適合底層調用System.currentTimeMillis()返回當前時間距離 1…

因泰立科技H1X激光雷達:因泰立科技為智慧工業注入新動力

在當今工業領域&#xff0c;精準測量與高效作業是推動產業升級的關鍵因素。因泰立科技推出的H1X三維輪廓掃描激光雷達&#xff0c;憑借其卓越的性能和廣泛的應用場景&#xff0c;正成為智慧工業中不可或缺的高科技裝備。 產品簡介 H1X三維輪廓掃描激光雷達是因泰立科技基于二維…

【threejs】每天一個小案例講解:創建基本的3D場景

代碼倉 GitHub - TiffanyHoo/three_practices: Learning three.js together! 可自行clone&#xff0c;無需安裝依賴&#xff0c;直接liver-server運行/直接打開chapter01中的html文件 運行效果圖 知識要點 核心運行代碼 <!DOCTYPE html><html><head><t…

微軟PowerBI考試 PL300-使用 Power BI 準備數據以供分析【提供練習數據】

微軟PowerBI考試 PL300-使用 Power BI 準備數據以供分析 您將了解如何使用 Power Query 從不同的數據源中提取數據&#xff0c;選擇存儲模式和連接性類型。 您還將了解在對數據進行建模之前&#xff0c;如何分析、清理數據以及將數據加載到 Power BI 中。 在 Power BI 中獲取…

Linux與Windows切換使用Obsidian,出現 unexplained changes 問題的解決

如果你的Obsidian文檔在Linux與Windows間來回切換&#xff0c;可能會涉及到文件的保存換行符問題&#xff0c;但這樣的話就容易導致一個問題&#xff0c;那就是內容無差異&#xff0c;Obsidian卻提示unexplained changes&#xff0c;Windows系統下的解決方法如下&#xff0c;找…