JavaWEB--POI之EXCEL操作、優化、封裝詳解系列(三)--萬能POI之EXCEL匯出工具--PoiExportUtil入門篇
阿新 • • 發佈:2019-02-15
前面講完概述、原理以及helloworld,現在就講下怎樣的POI的EXCEL匯出工具可以適用於各種情況吧。後面再做個優化分頁的萬能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)
package com.fuzhu.model;
/**
* Created by 符柱成 on 2017/8/24.
*/
public class Student {
private int id;
private String name;
private String sex;
public Student(int id, String name, String sex) {
this.id = id;
this.name = name;
this.sex = sex;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
}
工具程式碼:
package com.fuzhu.utils;
/**
* Created by 符柱成 on 2017/8/23.
*/
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.*;
import com.fuzhu.entity.Student;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFCellStyle;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
public class ExportBeanExcel<T> {
/**
* 這是一個通用的方法,利用了JAVA的反射機制,可以將放置在JAVA集合中並且符號一定條件的資料以EXCEL 的形式輸出
*
* title 表格標題名
* headersName 表格屬性列名陣列
* headersId 表格屬性列名對應的欄位---你需要匯出的欄位名(為了更靈活控制你想要匯出的欄位)
* dtoList 需要顯示的資料集合,集合中一定要放置符合javabean風格的類的物件
* out 與輸出裝置關聯的流物件,可以將EXCEL文件匯出到本地檔案或者網路中
*/
public void exportExcel(String title, List<String> headersName,List<String> headersId,
List<T> dtoList) {
/*(一)表頭--標題欄*/
Map<Integer, String> headersNameMap = new HashMap<>();
int key=0;
for (int i = 0; i < headersName.size(); i++) {
if (!headersName.get(i).equals(null)) {
headersNameMap.put(key, headersName.get(i));
key++;
}
}
/*(二)欄位*/
Map<Integer, String> titleFieldMap = new HashMap<>();
int value = 0;
for (int i = 0; i < headersId.size(); i++) {
if (!headersId.get(i).equals(null)) {
titleFieldMap.put(value, headersId.get(i));
value++;
}
}
/* (三)宣告一個工作薄:包括構建工作簿、表格、樣式*/
HSSFWorkbook wb = new HSSFWorkbook();
HSSFSheet sheet = wb.createSheet(title);
sheet.setDefaultColumnWidth((short)15);
// 生成一個樣式
HSSFCellStyle style = wb.createCellStyle();
HSSFRow row = sheet.createRow(0);
style.setAlignment(HSSFCellStyle.ALIGN_CENTER);
HSSFCell cell;
Collection c = headersNameMap.values();//拿到表格所有標題的value的集合
Iterator<String> it = c.iterator();//表格標題的迭代器
/*(四)匯出資料:包括匯出標題欄以及內容欄*/
//根據選擇的欄位生成表頭
short size = 0;
while (it.hasNext()) {
cell = row.createCell(size);
cell.setCellValue(it.next().toString());
cell.setCellStyle(style);
size++;
}
//表格標題一行的欄位的集合
Collection zdC = titleFieldMap.values();
Iterator<T> labIt = dtoList.iterator();//總記錄的迭代器
int zdRow =0;//列序號
while (labIt.hasNext()) {//記錄的迭代器,遍歷總記錄
int zdCell = 0;
zdRow++;
row = sheet.createRow(zdRow);
T l = (T) labIt.next();
// 利用反射,根據javabean屬性的先後順序,動態呼叫getXxx()方法得到屬性值
Field[] fields = l.getClass().getDeclaredFields();//獲得JavaBean全部屬性
for (short i = 0; i < fields.length; i++) {//遍歷屬性,比對
Field field = fields[i];
String fieldName = field.getName();//屬性名
Iterator<String> zdIt = zdC.iterator();//一條欄位的集合的迭代器
while (zdIt.hasNext()) {//遍歷要匯出的欄位集合
if (zdIt.next().equals(fieldName)) {//比對JavaBean的屬性名,一致就寫入,不一致就丟棄
String getMethodName = "get"
+ fieldName.substring(0, 1).toUpperCase()
+ fieldName.substring(1);//拿到屬性的get方法
Class tCls = l.getClass();//拿到JavaBean物件
try {
Method getMethod = tCls.getMethod(getMethodName,
new Class[] {});//通過JavaBean物件拿到該屬性的get方法,從而進行操控
Object val = getMethod.invoke(l, new Object[] {});//操控該物件屬性的get方法,從而拿到屬性值
String textVal = null;
if (val!= null) {
textVal = String.valueOf(val);//轉化成String
}else{
textVal = null;
}
row.createCell((short) zdCell).setCellValue(textVal);//寫進excel物件
zdCell++;
} catch (SecurityException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
}
}
}
try {
FileOutputStream exportXls = new FileOutputStream("E://工單資訊表.xls");
wb.write(exportXls);
exportXls.close();
System.out.println("匯出成功!");
} catch (FileNotFoundException e) {
System.out.println("匯出失敗!");
e.printStackTrace();
} catch (IOException e) {
System.out.println("匯出失敗!");
e.printStackTrace();
}
}
/*
使用例子
*/
public static void main(String [] args){
List<String> listName = new ArrayList<>();
listName.add("id");
listName.add("名字");
listName.add("性別");
List<String> listId = new ArrayList<>();
listId.add("id");
listId.add("name");
listId.add("sex");
List<Student> list = new ArrayList<>();
list.add(new Student(111,"張三asdf","男"));
list.add(new Student(111,"李四asd","男"));
list.add(new Student(111,"王五","女"));
ExportBeanExcel<Student> exportBeanExcelUtil = new ExportBeanExcel();
exportBeanExcelUtil.exportExcel("測試POI匯出EXCEL文件",listName,listId,list);
}
}
(四)工具注意點:
(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:
package com.fuzhu.utils;
import org.apache.poi.hssf.usermodel.*;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.*;
/**
* Created by 符柱成 on 2017/8/24.
*/
public class ExportMapExcel {
public void exportExcel(String title, List<String> headersName, List<String> headersId,
List<Map<String, Object>> dtoList) {
/*
(一)表頭--標題欄
*/
Map<Integer, String> headersNameMap = new HashMap<>();
int key = 0;
for (int i = 0; i < headersName.size(); i++) {
if (!headersName.get(i).equals(null)) {
headersNameMap.put(key, headersName.get(i));
key++;
}
}
/*
(二)欄位---標題的欄位
*/
Map<Integer, String> titleFieldMap = new HashMap<>();
int value = 0;
for (int i = 0; i < headersId.size(); i++) {
if (!headersId.get(i).equals(null)) {
titleFieldMap.put(value, headersId.get(i));
value++;
}
}
/*
(三)宣告一個工作薄:包括構建工作簿、表格、樣式
*/
HSSFWorkbook wb = new HSSFWorkbook();
HSSFSheet sheet = wb.createSheet(title);
sheet.setDefaultColumnWidth((short) 15);
// 生成一個樣式
HSSFCellStyle style = wb.createCellStyle();
HSSFRow row = sheet.createRow(0);
style.setAlignment(HSSFCellStyle.ALIGN_CENTER);
HSSFCell cell;
Collection c = headersNameMap.values();//拿到表格所有標題的value的集合
Iterator<String> headersNameIt = c.iterator();//表格標題的迭代器
/*
(四)匯出資料:包括匯出標題欄以及內容欄
*/
//根據選擇的欄位生成表頭--標題
short size = 0;
while (headersNameIt.hasNext()) {
cell = row.createCell(size);
cell.setCellValue(headersNameIt.next().toString());
cell.setCellStyle(style);
size++;
}
//表格一行的欄位的集合,以便拿到迭代器
Collection zdC = titleFieldMap.values();
Iterator<Map<String, Object>> titleFieldIt = dtoList.iterator();//總記錄的迭代器
int zdRow = 1;//真正的資料記錄的列序號
while (titleFieldIt.hasNext()) {//記錄的迭代器,遍歷總記錄
Map<String, Object> mapTemp = titleFieldIt.next();//拿到一條記錄
row = sheet.createRow(zdRow);
zdRow++;
int zdCell = 0;
Iterator<String> zdIt = zdC.iterator();//一條記錄的欄位的集合的迭代器
while (zdIt.hasNext()) {
String tempField =zdIt.next();//欄位的暫存
if (mapTemp.get(tempField) != null) {
row.createCell((short) zdCell).setCellValue(String.valueOf(mapTemp.get(tempField)));//寫進excel物件
zdCell++;
}
}
}
try {
FileOutputStream exportXls = new FileOutputStream("E://工單資訊表Map.xls");
wb.write(exportXls);
exportXls.close();
System.out.println("匯出成功!");
} catch (FileNotFoundException e) {
System.out.println("匯出失敗!");
e.printStackTrace();
} catch (IOException e) {
System.out.println("匯出失敗!");
e.printStackTrace();
}
}
public static void main(String [] args) {
List<String> listName = new ArrayList<>();
listName.add("id");
listName.add("名字");
listName.add("性別");
List<String> listId = new ArrayList<>();
listId.add("id");
listId.add("name");
listId.add("sex");
List<Map<String,Object>> listB = new ArrayList<>();
for (int t=0;t<6;t++){
Map<String,Object> map = new HashMap<>();
map.put("id",t);
map.put("name","abc"+t);
map.put("sex","男"+t);
listB.add(map);
}
System.out.println("listB : "+listB.toString());
ExportMapExcel exportExcelUtil = new ExportMapExcel();
exportExcelUtil.exportExcel("測試POI匯出EXCEL文件",listName,listId,listB);
}
}