xl_echo編輯整理,歡迎轉載,轉載請聲明文章來源。歡迎添加echo微信(微信號:t2421499075)交流學習。 百戰不敗,依不自稱常勝,百敗不頹,依能奮力前行。——這纔是真正的堪稱強大!!java
excel使用poi直接導出最大值是多少?估計不少人不會關注這個問題,由於不多有業務要求excel直接導出上萬條數據,更甚者可能沒有聽過excel直接導出100w條數據。這裏給你們介紹一個引用場景和博主採坑的經歷。spring
公司要求實現一個銀行流水的導出功能,看上去就是一個簡單的按鈕,可是這個需求有幾點要求:apache
樓主開發環境:jdk1.8, idea2018.1,springboot1.5x,dubbox瀏覽器
剛開始的時候,沒有過多的關注5w條這個數量,直接使用的poi-3.9。在整個開發過程當中基本沒有碰到問題。在測試的時候,碰到了一個不能知足需求的問題。當我直接下載5w條的時候,程序直接報錯。通過不斷的測試,發現3.9的直接使用,最高下載值爲6000+(這個最高值和電腦性能有必定的關係,不過出入不會很大)。springboot
很明顯上面的嘗試不能作出與需求相關的功能,通過百度,發現easyexcel是一個不錯的解決方案。微信
導入的easyexcel爲app
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
<version>1.1.1</version>
</dependency>複製代碼
使用該依賴的時候,我參考了覺得博主的代碼,代碼地址爲:https://blog.csdn.net/qq_35206261/article/details/88579151。當我將他的百萬行級別的解決方案搬到個人項目中的時候,發現一切好像沒有問題。可是當我啓動的時候發現一直報錯java.lang.NoSuchMethodError: org.apache.poi.ss.usermodel.Font.setBold(Z)V。(這裏的錯誤來源於公司項目原有的項目導入依賴衝突,若是沒有作過導入導出相關功能的應該不會出現)。通過排查發現,問題出如今依賴上面。公司本來是有導入和導出功能的ide
引入的依賴以下:工具
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>3.9</version>
</dependency>複製代碼
衝突以下圖所示:性能
點擊進入easyexcel的依賴發現,它的底層是依賴的poi3.17的版本。當我一直覺得poi是可以向下兼容的時候,最終每次啓動和編譯的時候出現的問題都指向了並無向下兼容。底層的poi-ooxml版本爲3.17,如圖所示
這個時候咱們能夠若是還要去使用easyexcel,那咱們須要更改版本或者解決poi-ooxml的版本兼容問題。
通過不兼容問題以後,看公司原有poi-ooxml的應用因而決定使用poi-ooxml的解決方案。
通過以上幾個坑以後,因而決定使用poi-ooxml的3.9版本可以兼容的解決方案,百度以後發現有一個以3.8版本基礎的應用。通過上面的不兼容以後,仍是決定試一試。因而採用了該博主文章中的一段代碼,文章地址:https://blog.csdn.net/happyljw/article/details/52809244。
這篇文章中描述了一個思路,同時也給出了一段博主提供的實現代碼,相對來講,若是做爲測試問題不大,最後根據需求進行調整,修改了部分實現的步驟,同時也新增了一些新的實現和限制。代碼以下:
@ResponseBody
@RequestMapping(value = "/exportDataMoreThan1000")
public void readMoreThan1000RowBySheet(@RequestParam(value = "start") Integer start,
@RequestParam(value = "limit") Integer limit,
HttpServletResponse response) throws Exception {
//內存中只建立100個對象,寫臨時文件,當超過100條,就將內存中不用的對象釋放。
Workbook wb = new SXSSFWorkbook(100);
//工做表對象
final Sheet[] sheet = {null};
//行對象
final Row[] nRow = {null};
//列對象
final Cell[] nCell = {null};
//總行號
final int[] rowNo = {0};
//頁行號
final int[] pageRowNo = {0};
List<BankDto> list = new ArrayList<>(50000);
//數據源
list = BankServer.getList();
list.forEach(it -> {
if (rowNo[0] % 10001 == 0) {
sheet[0] = wb.createSheet("個人第" + (rowNo[0] / 10001 + 1) + "個工做簿");
sheet[0] = wb.getSheetAt(rowNo[0] / 10001);
//每當新建了工做表就將當前工做表的行號重置爲0
pageRowNo[0] = 0;
}
rowNo[0]++;
nRow[0] = sheet[0].createRow(pageRowNo[0]++);
//這一步很關鍵,若是沒有就沒有表頭。
if (pageRowNo[0] == 1) {
for (int j = 0; j < 9; j++) {
nCell[0] = nRow[0].createCell(j);
if (j == 0) nCell[0].setCellValue("編號");
if (j == 1) nCell[0].setCellValue("編號");
if (j == 2) nCell[0].setCellValue("編號");
if (j == 3) nCell[0].setCellValue("編號");
if (j == 4) nCell[0].setCellValue("編號");
if (j == 5) nCell[0].setCellValue("編號");
if (j == 6) nCell[0].setCellValue("編號");
if (j == 7) nCell[0].setCellValue("編號");
if (j == 8) nCell[0].setCellValue("備註");
}
rowNo[0]++;
nRow[0] = sheet[0].createRow(pageRowNo[0]++);
}
// 輸出每行,每行有9列數據
for (int j = 0; j < 9; j++) {
nCell[0] = nRow[0].createCell(j);
if (j == 0) nCell[0].setCellValue(it.getPaycode());
if (j == 1) nCell[0].setCellValue(it.getPaycode());
if (j == 2) nCell[0].setCellValue(it.getPaycode());
if (j == 3) nCell[0].setCellValue(it.getPaycode());
if (j == 4) nCell[0].setCellValue(it.getPaycode());
if (j == 5) nCell[0].setCellValue(it.getPaycode());
if (j == 6) nCell[0].setCellValue(it.getPaycode());
if (j == 7) nCell[0].setCellValue(it.getPaycode());
if (j == 8) nCell[0].setCellValue(it.getRemark());
}
});
String fileName = "銀行流水錶.xlsx";
//設置請求頭
response.setHeader("content-Type", "application/vnd.ms-excel");
response.setContentType("application/vnd.ms-excel;charset=utf-8");
response.setHeader("Content-Disposition", "attachment; filename=" + fileName + ".xlsx");
ServletOutputStream outputStream = response.getOutputStream();
wb.write(outputStream);
outputStream.flush();
outputStream.close();
}複製代碼
這裏簡化了數據源的操做,若是須要能夠根據本身的業務進行修改,個人實際實現裏對數據源操做相對複查,不只進行了分片請求(避免dubbox超時),同時還對數據進行了不少處理。這裏的操做有一個亮點,那就是進行了多Sheet的分割。
當完成以上的代碼編寫以後,使用工具測試,發現已經實現了我須要的功能。目前的一個下載量10w之內都沒有什麼太大的問題,實測10w數據20s。若是業務邏輯簡單些還會提高一倍的速度。