使用POI導出Excel

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

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

  http://www.javashuo.com/article/p-eckudyxa-a.htmlide

  https://blog.csdn.net/s_istvan/article/details/69266915  (單元格顏色) 字體

 

我在項目中作這個功能的時候,其實項目中是有現成代碼的,原本我覺得我只須要修改一下,後來看過代碼才發現和我要的不同,因而只能重寫一個。this

 

導出功能:spa

  一、在action層拿到要導出的數據  --  results.net

  二、一樣在action層拿到要導出數據的字段集,即列   --  exportFieldsexcel

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

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

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

  四、調用Service層方法,傳入上面的參數和HttpServletResponse 。傳哪些參數你們隨意,固然  results是確定不能少的。

  五、在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     }

  五、寫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     }

六、其實現成的代碼和我這個是差很少同樣的,不同的地方就是在填充的那兩個方法裏面

  這是現成的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     }

  七、我在方法的最後作了合併單元格,這是在原方法上改不動的,因此我必須再寫一個方法。

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

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

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     }

  八、到此,導出結束。

  九、過程當中碰到的坎坷:

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

  

 

  十、最後的成功:

相關文章
相關標籤/搜索