POI之EXCEL導出工具--PoiExportUtil入門篇(三)


POI之EXCEL導出工具--PoiExportUtil入門篇--(三)

轉載自:https://blog.csdn.net/Jack__Frost/article/details/77623052

本篇章先做個簡單的萬能POI之EXCEL導出工具(博主已經抽象成庫,請於文末前去使用),后面再做個優化分頁的萬能POI之EXCEL導出工具。

文章結構:(1)面向JavaBean的導出工具;(2)面向List-Map結構的導出工具。

大家閱讀了前篇就知道Excel報表導出之JSP方式就是這么簡單了,查出數據直接對到jsp處理,樣式也可以在制作excel模板時自定義,相當簡單。但是我們要想當要導出大量數據的時候呢??難道我們也這樣實時導出??這樣一個正常系統而且在大量人使用的時候,對於系統的負載會非常非常高的,所以前篇我也給出了另一種方式:Excel報表導出之上傳文件流方式。在這樣的方式下,如何做出一個公用的適應各種情況的設計,這就是往后幾篇文章要探討的。

一、面向JavaBean的導出工具:

(一)設計的關鍵:

(1)兼容普通JavaBean;

(2)接口方法易用性;

(3)導出數據准確性;

(4)擴展性。

(二)基於POI抽象的關鍵步驟:

(1)設置表格標題

(2)設置標題欄

(3)設置內容欄(為了精確比對,需要給出標題欄對應的字段—DTO類(普通javabean)的屬性)

(4)導出寫入到流對象

(三)核心代碼與demo:

准備實體:(一個普通的JavaBean)

 1 package com.fuzhu.model;
 2 
 3 /**
 4  * Created by 符柱成 on 2017/8/24.
 5  */
 6 public class Student {
 7     private int id;
 8     private String name;
 9     private String sex;
10 
11     public Student(int id, String name, String sex) {
12         this.id = id;
13         this.name = name;
14         this.sex = sex;
15     }
16 
17     public int getId() {
18         return id;
19     }
20 
21     public void setId(int id) {
22         this.id = id;
23     }
24 
25     public String getName() {
26         return name;
27     }
28 
29     public void setName(String name) {
30         this.name = name;
31     }
32 
33     public String getSex() {
34         return sex;
35     }
36 
37     public void setSex(String sex) {
38         this.sex = sex;
39     }
40 }

工具代碼:

  1 package com.fuzhu.utils;
  2 
  3 /**
  4  * Created by 符柱成 on 2017/8/23.
  5  */
  6 
  7 import java.io.FileNotFoundException;
  8 import java.io.FileOutputStream;
  9 import java.io.IOException;
 10 import java.lang.reflect.Field;
 11 import java.lang.reflect.InvocationTargetException;
 12 import java.lang.reflect.Method;
 13 import java.util.*;
 14 
 15 
 16 import com.fuzhu.entity.Student;
 17 import org.apache.poi.hssf.usermodel.HSSFCell;
 18 import org.apache.poi.hssf.usermodel.HSSFCellStyle;
 19 import org.apache.poi.hssf.usermodel.HSSFRow;
 20 import org.apache.poi.hssf.usermodel.HSSFSheet;
 21 import org.apache.poi.hssf.usermodel.HSSFWorkbook;
 22 
 23 
 24 public class ExportBeanExcel<T> {
 25 
 26     /**
 27      * 這是一個通用的方法,利用了JAVA的反射機制,可以將放置在JAVA集合中並且符號一定條件的數據以EXCEL 的形式輸出
 28      *
 29      * title         表格標題名
 30      * headersName  表格屬性列名數組
 31      * headersId    表格屬性列名對應的字段---你需要導出的字段名(為了更靈活控制你想要導出的字段)
 32      *  dtoList     需要顯示的數據集合,集合中一定要放置符合javabean風格的類的對象
 33      *  out         與輸出設備關聯的流對象,可以將EXCEL文檔導出到本地文件或者網絡中
 34      */
 35     public  void exportExcel(String title, List<String> headersName,List<String> headersId,
 36                             List<T> dtoList) {
 37         /*(一)表頭--標題欄*/
 38         Map<Integer, String> headersNameMap = new HashMap<>();
 39         int key=0;
 40         for (int i = 0; i < headersName.size(); i++) {
 41             if (!headersName.get(i).equals(null)) {
 42                 headersNameMap.put(key, headersName.get(i));
 43                 key++;
 44             }
 45         }
 46         /*(二)字段*/
 47         Map<Integer, String> titleFieldMap = new HashMap<>();
 48         int value = 0;
 49         for (int i = 0; i < headersId.size(); i++) {
 50             if (!headersId.get(i).equals(null)) {
 51                 titleFieldMap.put(value, headersId.get(i));
 52                 value++;
 53             }
 54         }
 55         /* (三)聲明一個工作薄:包括構建工作簿、表格、樣式*/
 56         HSSFWorkbook wb = new HSSFWorkbook();
 57         HSSFSheet sheet = wb.createSheet(title);
 58         sheet.setDefaultColumnWidth((short)15);
 59         // 生成一個樣式
 60         HSSFCellStyle style = wb.createCellStyle();
 61         HSSFRow row = sheet.createRow(0);
 62         style.setAlignment(HSSFCellStyle.ALIGN_CENTER);
 63         HSSFCell cell;
 64         Collection c = headersNameMap.values();//拿到表格所有標題的value的集合
 65         Iterator<String> it = c.iterator();//表格標題的迭代器
 66         /*(四)導出數據:包括導出標題欄以及內容欄*/
 67         //根據選擇的字段生成表頭
 68         short size = 0;
 69         while (it.hasNext()) {
 70             cell = row.createCell(size);
 71             cell.setCellValue(it.next().toString());
 72             cell.setCellStyle(style);
 73             size++;
 74         }
 75         //表格標題一行的字段的集合
 76         Collection zdC = titleFieldMap.values();
 77         Iterator<T> labIt = dtoList.iterator();//總記錄的迭代器
 78         int zdRow =0;//列序號
 79         while (labIt.hasNext()) {//記錄的迭代器,遍歷總記錄
 80             int zdCell = 0;
 81             zdRow++;
 82             row = sheet.createRow(zdRow);
 83             T l = (T) labIt.next();
 84             // 利用反射,根據javabean屬性的先后順序,動態調用getXxx()方法得到屬性值
 85             Field[] fields = l.getClass().getDeclaredFields();//獲得JavaBean全部屬性
 86             for (short i = 0; i < fields.length; i++) {//遍歷屬性,比對
 87                 Field field = fields[i];
 88                 String fieldName = field.getName();//屬性名
 89                 Iterator<String> zdIt = zdC.iterator();//一條字段的集合的迭代器
 90                 while (zdIt.hasNext()) {//遍歷要導出的字段集合
 91                     if (zdIt.next().equals(fieldName)) {//比對JavaBean的屬性名,一致就寫入,不一致就丟棄
 92                         String getMethodName = "get"
 93                                 + fieldName.substring(0, 1).toUpperCase()
 94                                 + fieldName.substring(1);//拿到屬性的get方法
 95                         Class tCls = l.getClass();//拿到JavaBean對象
 96                         try {
 97                             Method getMethod = tCls.getMethod(getMethodName,
 98                                     new Class[] {});//通過JavaBean對象拿到該屬性的get方法,從而進行操控
 99                             Object val = getMethod.invoke(l, new Object[] {});//操控該對象屬性的get方法,從而拿到屬性值
100                             String textVal = null;
101                             if (val!= null) {
102                                 textVal = String.valueOf(val);//轉化成String
103                             }else{
104                                 textVal = null;
105                             }
106                             row.createCell((short) zdCell).setCellValue(textVal);//寫進excel對象
107                             zdCell++;
108                         } catch (SecurityException e) {
109                             e.printStackTrace();
110                         } catch (IllegalArgumentException e) {
111                             e.printStackTrace();
112                         } catch (NoSuchMethodException e) {
113                             e.printStackTrace();
114                         } catch (IllegalAccessException e) {
115                             e.printStackTrace();
116                         } catch (InvocationTargetException e) {
117                             e.printStackTrace();
118                         }
119                     }
120                 }
121             }
122         }
123         try {
124             FileOutputStream exportXls = new FileOutputStream("E://工單信息表.xls");
125             wb.write(exportXls);
126             exportXls.close();
127             System.out.println("導出成功!");
128         } catch (FileNotFoundException e) {
129             System.out.println("導出失敗!");
130             e.printStackTrace();
131         } catch (IOException e) {
132             System.out.println("導出失敗!");
133             e.printStackTrace();
134         }
135     }
136     /*
137         使用例子
138     */
139     public static void main(String [] args){
140         List<String> listName = new ArrayList<>();
141         listName.add("id");
142         listName.add("名字");
143         listName.add("性別");
144         List<String> listId = new ArrayList<>();
145         listId.add("id");
146         listId.add("name");
147         listId.add("sex");
148         List<Student> list = new ArrayList<>();
149         list.add(new Student(111,"張三asdf","男"));
150         list.add(new Student(111,"李四asd","男"));
151         list.add(new Student(111,"王五","女"));
152 
153 
154         ExportBeanExcel<Student> exportBeanExcelUtil = new ExportBeanExcel();
155         exportBeanExcelUtil.exportExcel("測試POI導出EXCEL文檔",listName,listId,list);
156 
157     }
158 }

(四)工具注意點:

(1)應用泛型,代表任意一個符合javabean風格的類

(2)注意這里為了簡單起見,boolean型的屬性xxx的get器方式為getXxx(),而不是isXxx()

(3) T這里代表一個不確定是實體類,即參數實體


二、面向List-Map結構的導出工具:

(一)設計的關鍵:

(1)兼容普通List-Map結構;

(2)接口方法易用性;

(3)導出數據准確性;

(4)擴展性。

(二)基於POI抽象的關鍵步驟:

(1)設置表格標題

(2)設置標題欄

(3)設置內容欄(為了精確比對,需要給出標題欄對應的字段—dtoList(List-Map結構中的key))

(4)導出寫入到流對象

(三)核心代碼與demo:

  1 package com.fuzhu.utils;
  2 
  3 import org.apache.poi.hssf.usermodel.*;
  4 
  5 import java.io.FileNotFoundException;
  6 import java.io.FileOutputStream;
  7 import java.io.IOException;
  8 import java.util.*;
  9 
 10 /**
 11  * Created by 符柱成 on 2017/8/24.
 12  */
 13 public class ExportMapExcel {
 14     public void exportExcel(String title, List<String> headersName, List<String> headersId,
 15                             List<Map<String, Object>> dtoList) {
 16         /*
 17                (一)表頭--標題欄
 18          */
 19         Map<Integer, String> headersNameMap = new HashMap<>();
 20         int key = 0;
 21         for (int i = 0; i < headersName.size(); i++) {
 22             if (!headersName.get(i).equals(null)) {
 23                 headersNameMap.put(key, headersName.get(i));
 24                 key++;
 25             }
 26         }
 27         /*
 28                 (二)字段---標題的字段
 29          */
 30         Map<Integer, String> titleFieldMap = new HashMap<>();
 31         int value = 0;
 32         for (int i = 0; i < headersId.size(); i++) {
 33             if (!headersId.get(i).equals(null)) {
 34                 titleFieldMap.put(value, headersId.get(i));
 35                 value++;
 36             }
 37         }
 38        /*
 39                 (三)聲明一個工作薄:包括構建工作簿、表格、樣式
 40        */
 41         HSSFWorkbook wb = new HSSFWorkbook();
 42         HSSFSheet sheet = wb.createSheet(title);
 43         sheet.setDefaultColumnWidth((short) 15);
 44         // 生成一個樣式
 45         HSSFCellStyle style = wb.createCellStyle();
 46         HSSFRow row = sheet.createRow(0);
 47         style.setAlignment(HSSFCellStyle.ALIGN_CENTER);
 48         HSSFCell cell;
 49         Collection c = headersNameMap.values();//拿到表格所有標題的value的集合
 50         Iterator<String> headersNameIt = c.iterator();//表格標題的迭代器
 51         /*
 52                 (四)導出數據:包括導出標題欄以及內容欄
 53         */
 54         //根據選擇的字段生成表頭--標題
 55         short size = 0;
 56         while (headersNameIt.hasNext()) {
 57             cell = row.createCell(size);
 58             cell.setCellValue(headersNameIt.next().toString());
 59             cell.setCellStyle(style);
 60             size++;
 61         }
 62         //表格一行的字段的集合,以便拿到迭代器
 63         Collection zdC = titleFieldMap.values();
 64         Iterator<Map<String, Object>> titleFieldIt = dtoList.iterator();//總記錄的迭代器
 65         int zdRow = 1;//真正的數據記錄的列序號
 66         while (titleFieldIt.hasNext()) {//記錄的迭代器,遍歷總記錄
 67             Map<String, Object> mapTemp = titleFieldIt.next();//拿到一條記錄
 68                 row = sheet.createRow(zdRow);
 69                 zdRow++;
 70                 int zdCell = 0;
 71                 Iterator<String> zdIt = zdC.iterator();//一條記錄的字段的集合的迭代器
 72                 while (zdIt.hasNext()) {
 73                     String tempField =zdIt.next();//字段的暫存
 74                     if (mapTemp.get(tempField) != null) {
 75                         row.createCell((short) zdCell).setCellValue(String.valueOf(mapTemp.get(tempField)));//寫進excel對象
 76                         zdCell++;
 77                     }
 78                 }
 79         }
 80         try {
 81             FileOutputStream exportXls = new FileOutputStream("E://工單信息表Map.xls");
 82             wb.write(exportXls);
 83             exportXls.close();
 84             System.out.println("導出成功!");
 85         } catch (FileNotFoundException e) {
 86             System.out.println("導出失敗!");
 87             e.printStackTrace();
 88         } catch (IOException e) {
 89             System.out.println("導出失敗!");
 90             e.printStackTrace();
 91         }
 92     }
 93     public static void main(String [] args) {
 94 
 95         List<String> listName = new ArrayList<>();
 96         listName.add("id");
 97         listName.add("名字");
 98         listName.add("性別");
 99         List<String> listId = new ArrayList<>();
100         listId.add("id");
101         listId.add("name");
102         listId.add("sex");
103 
104         List<Map<String,Object>> listB = new ArrayList<>();
105         for (int t=0;t<6;t++){
106             Map<String,Object> map = new HashMap<>();
107             map.put("id",t);
108             map.put("name","abc"+t);
109             map.put("sex","男"+t);
110             listB.add(map);
111         }
112         System.out.println("listB  : "+listB.toString());
113         ExportMapExcel exportExcelUtil = new ExportMapExcel();
114         exportExcelUtil.exportExcel("測試POI導出EXCEL文檔",listName,listId,listB);
115 
116     }
117 }

(四)工具注意點:

(1)面向的是List-Map數據結構,請不要注入別的數據結構

(2)方法參數說明:

1)title是:表格的名稱
2)headersName標題欄的文字
3)headersId:對應標題欄的字段,為了准確導出到對應列而設計
4)dtoList:我們要導出的所有數據(把數據封裝在dtoList數據傳輸對象中)

(3)此處的入門篇工具兼容性並不很好,只是講解了工具的核心。博客抽象的工具是已這兩個demo工具為基准點去設計的。


本篇的demo源碼下載:JavaWEB–POI之EXCEL操作、優化、封裝詳解系列(三)萬能POI之EXCEL導出工具–PoiExportUtil入門篇

POI輔助庫:POI輔助庫

更多內容,可以訪問JackFrost的博客


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM