JavaWEB--POI之EXCEL操作、優化、封裝詳解系列(一)--概述與原理
阿新 • • 發佈:2019-01-24
鑑於現在部落格混雜臃腫,對POI技術講解得十分不不充分,讓本博主在開發優化時遭遇諸多大坑,為了讓後人更好製作企業級報表,我將在這一系列詳細解說這個以及羅列我所遇到的諸多問題。並且基於強大的POI技術寫一個輔助工具庫給大家。
本系列的所有程式碼均可以直接執行,請放心使用。
文章結構:(1)概述;(2)原理(以例子講解)
先貼出官方地址:POI官網
一、概述:
(一)框架背景:
Apache POI 是用Java編寫的免費開源的跨平臺的 Java API,Apache POI提供API給Java程式對Microsoft Office格式檔案讀和寫的功能。
Apache POI 是建立和維護操作各種符合Office Open XML(OOXML)標準和微軟的OLE 2複合文件格式(OLE2)的Java API。用它可以使用Java讀取和建立,修改MS Excel檔案.而且,還可以使用Java讀取和建立MS Word和MSPowerPoint檔案。Apache POI 提供Java操作Excel解決方案(適用於Excel97-2008)。
(二)POI框架的類庫:
HSSF - 提供讀寫Microsoft Excel格式檔案的功能。
XSSF - 提供讀寫Microsoft Excel OOXML格式檔案的功能。
HWPF - 提供讀寫Microsoft Word格式檔案的功能。
HSLF - 提供讀寫Microsoft PowerPoint格式檔案的功能。
HDGF - 提供讀寫Microsoft Visio格式檔案的功能。
(三)對比以前的框架JXL:(後面會給出一個jxl的例子)
(1)JXL概述:
通過Jxl,Java可以很方便的操作微軟的Excel文件。jxl是一個韓國人寫的java操作excel的工具,jExcelAPI對中文支援非常好,API是純Java的, 並不 依賴Windows系統,即使執行在Linux下,它同樣能夠正確的處理Excel檔案。 另外需要說明的是,這套API對圖形和圖表的支援很有限,而且 僅僅識別PNG格式。
(2)兩者現狀:
jxl現在基本上沒被維護了。相反,poi屬於Apache開源專案的一部分,更新維護得比較好,同時poi可以支援更高版本的excel,而jxl只能支援excel2003以及之前的版本(侷限的資料量)。
小檔案使用jxl解析效率比較高,但是因為支援的excel版本的限制,導致不能匯出65535以上量級的資料。
(3)JXL使用DEMO:
1)匯出JXL的庫
<!-- jxl excel匯入匯出的另一個庫 -->
<dependency>
<groupId>net.sourceforge.jexcelapi</groupId >
<artifactId>jxl</artifactId>
<version>2.6.12</version>
</dependency>
2)程式碼實現:
package com.fuzhu.utils;
import jxl.Workbook;
import jxl.WorkbookSettings;
import jxl.write.Label;
import jxl.write.WritableFont;
import jxl.write.WritableSheet;
import jxl.write.WritableWorkbook;
import org.apache.commons.lang3.StringUtils;
import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* Created by 符柱成 on 2017/8/23.
*/
public class JXLTest {
public static void main(String [] args){
writeInExcel();
}
public static void writeInExcel() {
//列的標題,把他寫進程式碼,是為了方便管理業務的增刪
List<String> headList = new ArrayList<>();
headList.add("專線型別");
headList.add("業務型別");
headList.add("工單標題");
headList.add("工單號");
headList.add("ESOP單號");
headList.add("來源渠道");
//(一)路徑的拼接(模板檔案路徑)
//模板檔案流
String basePath = Thread.currentThread().getContextClassLoader().getResource("").getPath();
basePath = StringUtils.substringBeforeLast(basePath, "/");
basePath = StringUtils.substringBeforeLast(basePath, "/");
basePath = StringUtils.substringBeforeLast(basePath, "/");
basePath = basePath+"/src/main/webapp/source/";
File templateFile = new File(basePath + "commonexport.xls");
//(二)匯出的檔案流
String resultFilePath = basePath + "匯出的檔名.xls";
File resultFile = new File(resultFilePath);
//(三)excel檔案物件
Workbook wb = null;//先初始化一個EXCEL檔案
WorkbookSettings settings = new WorkbookSettings();//以下兩行先不要理會,後面會詳細解釋,這個是關於Linux與wins的區別,關於單元格最大的字元限制
settings.setWriteAccess(null);
WritableWorkbook wwb = null;
try {
wb = Workbook.getWorkbook(templateFile);
wwb = Workbook.createWorkbook(resultFile, wb, settings);
WritableSheet sheet = wwb.createSheet("Sheet1", 0);//excel的工作表格
//(四)標題欄
for (int i = 0; i < headList.size(); i++) {//這個是我們匯出的模板excel的列數
Label la = new Label(i, 0, wb.getSheet(0).getCell(i, 0).getContents());
sheet.addCell(la);
}
List<Map<String, String>> dataList=new ArrayList<>();
sheet.setRowView(0, 300);//設定第一行高度
//(五)資料準備--假資料
for (int t=0;t<1000;t++){
Map<String, String> temp = new HashMap<>();
temp.put("groupid", String.valueOf(1+t));
temp.put("productcode", "abc"+String.valueOf(1+t));
dataList.add(temp);
}
//(六)導進excel的資料
for (int i = 0; i < dataList.size(); i++) {
Map<String, String> map = dataList.get(i);
Label C1 = new Label(0, i + 1, map.get("groupid"));//第一個引數指示:第一列
Label C3 = new Label(2, i + 1, map.get("productcode"));//第一個引數指示:第三列
sheet.addCell(C1);
sheet.addCell(C3);
}
/*
(七)匯出
*/
wwb.write();
wwb.close();
wb.close();
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
二、原理:
(一)明確組成一個EXCEL檔案需要多少物件:
(1)一個excel表格
HSSFWorkbook wb = new HSSFWorkbook();
XSSFWorkbook xb = new XSSFWorkbook();
(2)一個工作表格(sheet):
Sheet sheet = wb.getSheetAt(0);
(3)一行(row):
HSSFRow row1 = sheet.createRow(0);
(4)一個單元格(cell):
Cell cell = cells.next()
(5)單元格格式(cellstyle):
HSSFCellStyle style4 = wb.createCellStyle()
(6)單元格內容格式(HSSFDataFormat ):
HSSFDataFormat format= wb.createDataFormat();
(二)一個例子說明POI解析EXCEL的大致原理:(取自網上已有–一個粗糙例子)取自此文
某管理員要查某層樓有多少人叫什麼名字?
1)首先要明確大樓在那裡(找到對應的檔案)
2)其次要明確是在第幾單元(找到對應的sheet)
3)在找到第幾層樓(對應的row)
4)敲門問住戶戶主先生/小姐的姓名(cell)
public class TestA {
public static void main(String args[]) throws Exception {
//找到大樓的位置
FileInputStream input = new FileInputStream("d:\\dir.xls");
//告訴管理員
POIFSFileSystem f = new POIFSFileSystem(input);
//走到大樓樓下
HSSFWorkbook wb = new HSSFWorkbook(f);
//確認自己走到第幾單元
HSSFSheet sheet = wb.getSheetAt(0);
//看一看有沒有樓層
Iterator rows = sheet.rowIterator();
while (rows.hasNext()) {
//如果有我們一層層問
HSSFRow row = (HSSFRow)rows.next();
Iterator cells = row.cellIterator();
//如果有人開門
while(cells.hasNext()) {
//我們一戶一戶的登記
HSSFCell cell = (HSSFCell) cells.next();
//是先生還是小姐(對應的資料型別)
int cellType = cell.getCellType();
System.out.print(getValue(cell,cellType));
}
System.out.println("");
}
}