使用POI導出Excel

来源:http://www.cnblogs.com/qq765065332/archive/2017/11/09/7811760.html
-Advertisement-
Play Games

先分享幾個鏈接:(POI的中文API,別人總結的拿來用特別方便) http://blog.csdn.net/m0_37505412/article/details/71109503 https://www.cnblogs.com/fqfanqi/p/6172223.html 我在項目中做這個功能的時 ...


先分享幾個鏈接:(POI的中文API,別人總結的拿來用特別方便)

  http://blog.csdn.net/m0_37505412/article/details/71109503      

  https://www.cnblogs.com/fqfanqi/p/6172223.html

 

我在項目中做這個功能的時候,其實項目中是有現成代碼的,本來我以為我只需要修改一下,後來看過代碼才發現和我要的不一樣,於是只能重寫一個。

 

導出功能:

  1、在action層拿到要導出的數據  --  results

  2、同樣在action層拿到要導出數據的欄位集,即列   --  exportFields

    解釋一下,一般我們在獲取數據的時候,往往會把一些表中的冗餘欄位或者一些我不需要的欄位也獲取了,我們不可能也把它們導出來。其實這個欄位集,就是我們在Excel表中要顯示的列。在現成的功能中支持在頁面選擇要導出的欄位,而我的導出功能不支持選擇,導出的欄位是寫死的。

  3、拿到導出時一張表中存多少條數據  --  rowNum

    在現成的功能中還支持這個由用戶選,就是導出到一張表,要太多條數據,然後我們根據這個值去劃分數據,比如這個值是5000,然後我們就每5000條數據新建一個工作表,再繼續存放數據。我的功能……這個值同樣寫死的。

  4、調用Service層方法,傳入上面的參數和HttpServletResponse 。傳哪些參數大家隨意,當然  results是肯定不能少的。

  5、在Service層寫方法,接受剛纔的四個參數

 1     @Override
 2     public void createExcelWorkBookInfo(HttpServletResponse response, List<BaseAlumni> results, String exportFields,
 3             Integer rowNum) {
 4         String nowStr = new Date().getTime() + "";
 5         //這個out我還不太瞭解就不給你們說了,大致意思就是導出動作吧
 6         OutputStream out = null;
 7         try {
 8             out = response.getOutputStream();
 9             response.reset();
10             //設置表名
11             response.setHeader("content-disposition",
12                     "attachment;filename=" + new String(("校友信息" + nowStr).getBytes("gb2312"), "ISO8859-1") + ".xls");
13             response.setContentType("APPLICATION/msexcel");
14             //創建Excel表
15             HSSFWorkbook workbook = new HSSFWorkbook();
16             //調用導出方法
17             excelSrv.export(results, exportFields, workbook, rowNum);
18             workbook.write(out);
19         } catch (IOException e) {
20             e.printStackTrace();
21         } finally {
22             try {
23                 // 強行將響應緩存中的內容發送到目的地
24                 response.flushBuffer();
25                 if (out != null) {
26                     out.flush();
27                     out.close();
28                 }
29             } catch (IOException e) {
30                 LOGGER.error(e);
31             }
32         }
33     }

  5、寫export方法,在現成的方法中,封裝好了一個方法,行,列的生成都是通過foreach,很高大上。在這裡,我先附上我寫的,後面再附上現成的,給自己做一個對比。

 1     @Override
 2     public void alumniBranchExport(List<BaseAlumniBranch> results, Map<String, String> fildsMap, HSSFWorkbook wb) {
 3         //因為之前沒有傳,所以在這寫死,這個功能大家不想要也是可以的  -- rowMaxNum = 10000
 4         Integer rowNum = rowMaxNum;
 5         for (int i = 0; i < results.size(); i += rowNum) {
 6             List<BaseAlumniBranch> newlist = new ArrayList<>();
 7             if ((i + rowNum) < results.size()) {
 8                 //數據的截取
 9                 newlist = results.subList(i, i + rowNum);
10             } else {
11                 newlist = results.subList(i, results.size());
12             }
13             //創建工作表
14             HSSFSheet sheet = wb.createSheet();
15             for (int j = 0; j < fildsMap.size(); j++) {
16                 //設置列寬,第一個參數是列,第二個參數是寬值
17                 sheet.setColumnWidth(i, 5000);
18             }
19             //填充表頭
20             this.fillClubExcelHeader(wb, sheet, fildsMap);
21             //填充內容
22             this.fillClubExcelBody(newlist, sheet, wb, fildsMap);
23         }
24     }

6、其實現成的代碼和我這個是差不多一樣的,不一樣的地方就是在填充的那兩個方法裡面

  這是現成的header填充:

 1     private void fillCommonHeader(HSSFWorkbook wb, HSSFSheet sheet, Map<String, String> fildsMap) {
 2         //創建樣式
 3         HSSFCellStyle style = wb.createCellStyle();
 4         style.setAlignment(HSSFCellStyle.ALIGN_CENTER);
 5         //字體的顏色,大小
 6         HSSFFont font = wb.createFont();
 7         font.setColor(HSSFColor.BLACK.index);
 8         font.setFontHeightInPoints((short) 18);
 9         style.setFont(font);
10         //創建第一行,從0開始,參數是第幾行的索引,第一行是0
11         HSSFRow row = sheet.createRow(0);
12         //在這裡說一下,foreach是拿不到index的,這裡在外面聲明一個i,在表示第幾列
13         int i = 0;
14         //迴圈傳過來的欄位集
15         for (String key : fildsMap.keySet()) {
16             //創建一個單元格,創建完後i自增1
17             HSSFCell cell = row.createCell(i++);
18             String value = fildsMap.get(key);
19             //給單元格賦值
20             cell.setCellValue(value);
21             //給單元格設置樣式
22             cell.setCellStyle(style);
23         }
24         //在這裡有一個順序的問題,我也是用傳參的方式,但是我的fildsMap的順序就是亂了,我又不會調,尷尬
25     }

  這是我的header填充:

 1     private void fillClubExcelHeader(HSSFWorkbook wb, HSSFSheet sheet, Map<String, String> fildsMap) {
 2         HSSFCellStyle style = wb.createCellStyle();
 3         style.setAlignment(HSSFCellStyle.ALIGN_CENTER);
 4         HSSFFont font = wb.createFont();
 5         font.setColor(HSSFColor.BLACK.index);
 6         font.setFontHeightInPoints((short) 18);
 7         style.setFont(font);
 8         // 創建第一行
 9         HSSFRow row = sheet.createRow(0);
10         // 創建第一列
11         HSSFCell cell = row.createCell(0);
12         // 賦值
13         cell.setCellValue(fildsMap.get("clubName"));
14         cell.setCellStyle(style);
15         // 創建第二列,在這裡不能再出現HSSFCell聲明,為什麼……我也是一知半解,就不說了
16         cell = row.createCell(1);
17         cell.setCellValue(fildsMap.get("clubWechatId"));
18         cell.setCellStyle(style);
19         // 創建第三列……
20         cell = row.createCell(2);
21         cell.setCellValue(fildsMap.get("clubAddress"));
22         cell.setCellStyle(style);
23         cell = row.createCell(3);
24         cell.setCellValue(fildsMap.get("clubEmail"));
25         cell.setCellStyle(style);
26         cell = row.createCell(4);
27         cell.setCellValue(fildsMap.get("clubEstablishedTime"));
28         cell.setCellStyle(style);
29         cell = row.createCell(5);
30         cell.setCellValue(fildsMap.get("name"));
31         cell.setCellStyle(style);
32         cell = row.createCell(6);
33         cell.setCellValue(fildsMap.get("staff"));
34         cell.setCellStyle(style);
35         cell = row.createCell(7);
36         cell.setCellValue(fildsMap.get("phone"));
37         cell.setCellStyle(style);
38         cell = row.createCell(8);
39         cell.setCellValue(fildsMap.get("email"));
40         cell.setCellStyle(style);
41     }

  這是現成的body填充:

 1     private <T> void fillCommonBody(List<T> results, HSSFSheet sheet, HSSFWorkbook wb, Map<String, String> fildsMap) {
 2         HSSFCellStyle style = wb.createCellStyle();
 3         style.setAlignment(HSSFCellStyle.ALIGN_CENTER);
 4         HSSFFont font = wb.createFont();
 5         font.setColor(HSSFColor.BLACK.index);
 6         font.setFontHeightInPoints((short) 16);
 7         style.setFont(font);
 8         int i = 1;
 9         for (T inst : results) {
10             HSSFRow row = sheet.createRow(i++);
11             row.setRowStyle(style);
12             int j = 0;
13             for (String key : fildsMap.keySet()) {
14                 HSSFCell cell = row.createCell(j++);
15                 String val = setCell(key, inst);  //在里我這差點被騙了,也不知道是誰命名的,還以為單元格帶有的get,set方法
16                 cell.setCellValue(val);
17             }
18         }
19     }

  這個方法主要是寫如何從results中拿值的,我看了半天沒看懂

 1     @SuppressWarnings("rawtypes")
 2     private <T> String setCell(String field, T data) {
 3         String val = "";
 4 
 5         Class clazz = data.getClass();
 6         Field[] fields = ArrayUtils.addAll(clazz.getDeclaredFields(), clazz.getSuperclass().getDeclaredFields());
 7         for (int i = 0; i < fields.length; i++) {
 8             if (fields[i].getName().equals(field)) {
 9                 try {
10                     Object resultObject = invokeMethod(data, fields[i].getName(), null);
11                     if (resultObject == null) {
12                         resultObject = "";
13                     }
14                     val = resultObject.toString();
15                     break;
16                 } catch (SecurityException | NoSuchMethodException | IllegalArgumentException | IllegalAccessException
17                         | InvocationTargetException e) {
18                     e.printStackTrace();
19                 }
20             }
21         }
22 
23         return val;
24     }

  我的body方法:

 1     private <T> void fillClubExcelBody(List<BaseAlumniBranch> results, HSSFSheet sheet, HSSFWorkbook wb,
 2             Map<String, String> fildsMap) {
 3         HSSFCellStyle style = wb.createCellStyle();
 4         style.setAlignment(HSSFCellStyle.ALIGN_CENTER);
 5         HSSFFont font = wb.createFont();
 6         font.setColor(HSSFColor.BLACK.index);
 7         font.setFontHeightInPoints((short) 16);
 8         style.setFont(font);
 9         int k = 1;
10         if (results.size() < 2 || "null".equals(results.size())) {
11             LOGGER.error("alumniBranchExport but results is empty !");
12             return;
13         }
14         for (int i = 0; i < results.size(); i++) {
15             BaseAlumniBranch inst = results.get(i);
16             if (inst.getStaffList().size() < 1 || "null".equals(inst.getStaffList().size())) {
17                 HSSFRow row = sheet.createRow(k++);
18                 row.setRowStyle(style);
19                 HSSFCell cell = row.createCell(0);
20                 cell.setCellValue(inst.getName());
21                 cell.setCellStyle(style);
22                 cell = row.createCell(1);
23                 cell.setCellValue(inst.getWechatId());
24                 cell.setCellStyle(style);
25                 cell = row.createCell(2);
26                 cell.setCellValue(inst.getAddress());
27                 cell.setCellStyle(style);
28                 cell = row.createCell(3);
29                 cell.setCellValue(inst.getEmail());
30                 cell.setCellStyle(style);
31                 cell = row.createCell(4);
32                 cell.setCellValue(inst.getEstablishedTime());
33                 cell.setCellStyle(style);
34                 cell = row.createCell(5);
35                 cell.setCellValue("");
36                 cell.setCellStyle(style);
37                 cell = row.createCell(6);
38                 cell.setCellValue("");
39                 cell.setCellStyle(style);
40                 cell = row.createCell(7);
41                 cell.setCellValue("");
42                 cell.setCellStyle(style);
43                 cell = row.createCell(8);
44                 cell.setCellValue("");
45                 cell.setCellStyle(style);
46             } else {
47                 for (int j = 0; j < inst.getStaffList().size(); j++) {
48                     HSSFRow row = sheet.createRow(k++);
49                     row.setRowStyle(style);
50                     HSSFCell cell = row.createCell(0);
51                     cell.setCellValue(inst.getName());
52                     cell.setCellStyle(style);
53                     cell = row.createCell(1);
54                     cell.setCellValue(inst.getWechatId());
55                     cell.setCellStyle(style);
56                     cell = row.createCell(2);
57                     cell.setCellValue(inst.getAddress());
58                     cell.setCellStyle(style);
59                     cell = row.createCell(3);
60                     cell.setCellValue(inst.getEmail());
61                     cell.setCellStyle(style);
62                     cell = row.createCell(4);
63                     cell.setCellValue(inst.getEstablishedTime());
64                     cell.setCellStyle(style);
65                     cell = row.createCell(5);
66                     cell.setCellValue(inst.getStaffList().get(j).getName());
67                     cell.setCellStyle(style);
68                     cell = row.createCell(6);
69                     cell.setCellValue(inst.getStaffList().get(j).getStaff());
70                     cell.setCellStyle(style);
71                     cell = row.createCell(7);
72                     cell.setCellValue(inst.getStaffList().get(j).getPhone());
73                     cell.setCellStyle(style);
74                     cell = row.createCell(8);
75                     cell.setCellValue(inst.getStaffList().get(j).getEmail());
76                     cell.setCellStyle(style);
77                 }
78                 for (int column = 0; column < 5; column++) {
79                     mergeCell(sheet, k - inst.getStaffList().size(), k - 1, column, column);
80                 }
81 
82             }
83         }
84     }

  7、我在方法的最後做了合併單元格,這是在原方法上改不動的,所以我必須再寫一個方法。

    傳的參數中,從左到右:工作表名,起始行,結束行,起始列,結束行

    就是要合併單元格,合併從哪行開始到哪行,從哪列開始到哪列

1     public void mergeCell(HSSFSheet sheet, int rolStart, int rolEnd, int cowStart, int cowEnd) {
2         CellRangeAddress region = new CellRangeAddress(rolStart, rolEnd, cowStart, cowEnd);
3         sheet.addMergedRegion(region);
4     }

  8、到此,導出結束。

  9、過程中碰到的坎坷:

    Excel表我聲明瞭兩次,導致到後來導出的內容是沒有行的,如圖:(要註意,不止是表,行,列也不能重覆,否則就會出錯)

  

 

  10、最後的成功:

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 有時會遇到this作為返回值的情況,那麼此時返回的到底是什麼呢? 返回的是調用this所處方法的那個對象的引用,讀起來有點繞口哈,有沒有想起小學語文分析句子成份的試題,哈哈。 一點點分析的話,主幹是“返回的是引用”; 什麼引用呢?“那個對象的引用”; 哪個對象呢?“調用方法的那個對象”; 調用的哪個 ...
  • 字元串是 Python 中最常用的數據類型。我們可以使用引號( ' 或 " )來創建字元串。 創建字元串很簡單,只要為變數分配一個值即可。 python中單引號和雙引號使用完全相同。 使用三引號( ''' 或 """ )可以指定一個多行字元串。 轉義符 '\' 自然字元串, 通過在字元串前加r或R。 ...
  • 文件的讀操作 示例: 運行結果: 文件的寫操作 知識點: 1. 寫操作前,文件先格式化清空文件 2.清空操作,在執行open的w方法後,清空 運行結果: 打開文件後顯示如下 文件的append方法 語法格式: 文件這種方法為追加模式:1, 空白文件中,直接從頭開始寫入內容; 2 有內容的文件,會在末 ...
  • 在正式進入Spring AOP的源碼實現前,我們需要準備一定的基礎也就是面向切麵編程的核心——動態代理。 動態代理實際上也是一種結構型的設計模式,JDK中已經為我們準備好了這種設計模式,不過這種JDK為我們提供的動態代理有2個缺點: 鑒於以上2個缺點,於是就出現了第二種動態代理技術——CGLIB(C ...
  • 寫自己的游戲引擎-魂鬥羅源代碼詳解-1_環境搭建與載入項目 上學期我們大一的c++程式設計基礎課需要寫一個課設,我看了題庫,都沒有特別感興趣的。所以我自己選了用c++寫魂鬥羅。這個游戲從main開始,自己建了迴圈,自己寫了框架,也花費了我一個假期的時間。現在想分享出來,併在後續的博客裡面詳細分析思路 ...
  • ——略談Java web軟體如何提供二次開發介面 接手公司的一個Java web軟體產品,該軟體採用傳統的dwr框架。dwr框架相當於一個中間層,使得javascript能夠識別Java類對象,進而能夠調用Java類對象的方法。該軟體要為項目部同事提供二次開發包。 這種方式界面層代碼和邏輯實現代碼混 ...
  • 迭代器 迭代是Python最強大的功能之一,是訪問集合元素的一種方式。。 迭代器對象是一個可以記住遍歷的位置的對象。 迭代器對象從集合的第一個元素開始訪問,直到所有的元素被訪問完結束。迭代器只能往前不會後退。 迭代器有兩個基本的方法:iter() 和 next()。 字元串,列表或元組對象都可用於創 ...
  • 一、新來同事rose2 建用戶名 [root@localhost ~]# useradd rose2 正在創建信箱文件: 文件已存在 建用戶ID [root@localhost ~]# id rose2 uid=3244(rose2) gid=3244(rose2) 組=3244(rose2) 建密 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...