POI操作Excel文件、讀取、寫入、合併單元格
一、POI專案簡介
POI全稱 Poor Obfuscation Implementation,利用POI介面可以通過JAVA操作Microsoft office 套件工具的讀寫功能。官網:http://poi.apache.org ,POI支援office的所有版本。
二、POI操作Excel文件
(一)準備開發環境 所需要的相關依賴包:
<!-- POI --> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi</artifactId> <version>3.16</version> </dependency> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-ooxml-schemas</artifactId> <version>3.16</version> </dependency> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-excelant</artifactId> <version>3.16</version> </dependency> <!-- Junit --> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> <scope>test</scope> </dependency>
(二)用POI操作03版EXCEL文件 在POI包中有如下幾個主要物件和excel的幾個物件對應:
HSSFWorkbook | Excel 工作簿workbook |
---|---|
HSSFSheet | Excel 工作表 sheet |
HSSFRow | Excel 行 |
HSSFCell | Excel 單元格 |
利用以上幾個物件,我們簡單建立一個Excel工作表,往裡面的C1單元格寫入和讀出“Hello World”: 1、寫入excel:
@Test public void testExcelWrite() throws IOException{ //1、新建工作簿 HSSFWorkbook workbook=new HSSFWorkbook(); //2、建立工作表 HSSFSheet sheet=workbook.createSheet("工作表1"); //3、建立行 HSSFRow row=sheet.createRow(0); //4、建立單元格 HSSFCell cell=row.createCell(2); //5、單元格寫入內容 cell.setCellValue("你好JAVA"); //6、儲存工作簿 File file=new File("d:\\hello.xls"); workbook.write(file); System.out.println("建立Excel成功"); }
2、讀取excel:
/** * 讀取Excel演示 * @throws IOException */ @Test public void readExcelTest() throws IOException{ FileInputStream input=new FileInputStream("d:\\hello.xls"); HSSFWorkbook workbook=new HSSFWorkbook(input); HSSFSheet sheet=workbook.getSheet("工作表1"); HSSFRow row=sheet.getRow(0); HSSFCell cell=row.getCell(2); System.out.println("讀取單元格內容:"+cell.getStringCellValue()); }
(三)用POI操作07版EXCEL文件 POI 也能對07以後的excel版本進行讀寫,讀寫方法和讀寫03版是一樣的,只是物件名稱變了;原來各物件的開頭字母H變為X,操作方式不變。 1、 Excel 的工作簿對應POI的XSSFWorkbook物件; 2、 Excel 的工作表對應POI的XSSFSheet物件; 3、 Excel 的行對應POI的XSSFRow物件; 4、 Excel 的單元格對應POI的XSSFCell物件。 1、寫入xlsx:
/**
* 寫入2007格式的Excel
* @throws IOException
*/
@Test
public void testExcel2007Write() throws IOException{
//1、建立工作簿
XSSFWorkbook workbook=new XSSFWorkbook();
//2、新建工作表
XSSFSheet sheet=workbook.createSheet("新建工作表1");
//3、新增行
XSSFRow row=sheet.createRow(0);
//4、新建單元格
XSSFCell cell=row.createCell(2);
//5、給單元格填充資料
cell.setCellValue("hello world");
//6、儲存工作簿
FileOutputStream fileout=new FileOutputStream("d:\\hello2.xlsx");
workbook.write(fileout);
System.out.println("建立2007格式的Excel成功");
}
2、讀取xlsx:
/**
* 讀取2007格式的Excel
* @throws IOException
*/
@Test
public void TestExcel2007Read() throws IOException{
//1、建立FileInputStream
FileInputStream filein=new FileInputStream("d:\\hello2.xlsx");
//2、基於流來建立Excel工作簿
XSSFWorkbook workbook=new XSSFWorkbook(filein);
//3、從工作簿來讀取工作表
XSSFSheet sheet=workbook.getSheet("新建工作表1");
//4、從工作表讀取行
XSSFRow row=sheet.getRow(0);
//5、從行中讀取單元格
XSSFCell cell=row.getCell(2);
//6、從單元格獲取內容
System.out.println(cell.getStringCellValue());
}
(四)用POI統一讀取03、07版EXCEL文件 從api文件中我們瞭解到: HSSFWorkbook 和 XSSFWorkbook 都實現了Workbook介面; HSSFSheet 和 XSSFSheet 實現了Sheet介面; HSSFRow 和 XSSFRow 實現了Row介面; HSSFCell 和 XSSFCell 實現了Cell介面; 因為這兩類處理物件共同實現了對應的同一介面,屆時將大大方便和簡化了同時處理不同格式的excel檔案的編碼工作。如;在處理03和07版本的excel檔案時利用統一的介面就可以做到分析兩個版本的excel資料。 POI同時讀入03和07版本的excel。 方法一:判斷檔案的名稱後呼叫對應版本的讀入方法。 方法二:根據WorkbookFactory來讀入檔案並統一處理。
@Test
public void AllExcelRead() throws IOException, EncryptedDocumentException, InvalidFormatException{
//1、指定要讀取EXCEL文件名稱
String filename="d:\\hello2.xlsx";
//filename="d:\\hello.xls";
//2、建立輸入流
FileInputStream input=new FileInputStream(filename);
//3、通過工作簿工廠類來建立工作簿物件
Workbook workbook=WorkbookFactory.create(input);
//4、獲取工作表
Sheet sheet=workbook.getSheet("新建工作表1");
//5、獲取行
Row row=sheet.getRow(0);
//6、獲取單元格
Cell cell=row.getCell(2);
//7、讀取單元格內容
System.out.println(cell.getStringCellValue());
}
(五)遍歷讀取一個Excel檔案
/**
* 遍歷一個Excel
*
* @throws IOException
* @throws InvalidFormatException
* @throws EncryptedDocumentException
*/
@Test
public void ExcelReadIteart() throws EncryptedDocumentException, InvalidFormatException, IOException {
// 1、指定要讀取EXCEL文件名稱
String filename = "d:\\test.xlsx";
// filename="d:\\hello.xls";
// 2、建立輸入流
FileInputStream input = new FileInputStream(filename);
// 3、通過工作簿工廠類來建立工作簿物件
Workbook workbook = WorkbookFactory.create(input);
//4、遍歷工作簿下面的所有工作表
int sheetnum=workbook.getNumberOfSheets();
for(int i=0;i<sheetnum;i++){
//獲取到單個工作表
Sheet sheet=workbook.getSheetAt(i);
//獲取工作表下的所有行數
int rownum=sheet.getPhysicalNumberOfRows();
//獲取第一行的單元格個數
for(int j=0;j<rownum;j++){
//獲取到每一行
Row row=sheet.getRow(j);
int cellnum=row.getPhysicalNumberOfCells();
//獲取每一行下的全部單元格
for(int x=0;x<cellnum;x++){
Cell cell=row.getCell(x);
//判斷單元格型別,獲取對應資料
if(cell.getCellTypeEnum()==CellType.STRING){
System.out.print(cell.getStringCellValue()+"\t");
}else if(cell.getCellTypeEnum()==CellType.NUMERIC){
System.out.print(cell.getNumericCellValue()+"\t");
}else if(cell.getCellTypeEnum()==CellType.BOOLEAN){
System.out.print(cell.getBooleanCellValue()+"\t");
}else if(cell.getCellTypeEnum()==CellType.BLANK){
System.out.print("null"+"\t");
}else{
System.out.print(cell.getDateCellValue()+"\t");
}
}
System.out.println("");
}
}
}
單元格型別 | 描述 |
---|---|
CELL_TYPE_BLANK | 代表空白單元格 |
CELL_TYPE_BOOLEAN | 代表布林單元(true或false) |
CELL_TYPE_ERROR | 表示在單元的誤差值 |
CELL_TYPE_FORMULA | 表示一個單元格公式的結果 |
CELL_TYPE_NUMERIC | 表示對一個單元的數字資料 |
CELL_TYPE_STRING | 表示對一個單元串(文字) |
(六)POI合併EXCEL單元格 合併單元格 在POI中有一個CellRangeAddress物件,中文直譯是 單元格範圍地址,主要用於在單元格的合併上,這個物件的構造方法CellRangeAddress(int firstRow, int lastRow, int firstCol, int lastCol) 有4個引數,分別表示(起始行號,終止行號, 起始列號,終止列號), 設定這個物件中要合併的單元格範圍後,工作表物件sheet呼叫方法addMergedRegion(CellRangeAddress region) ,將上述設定的CellRangeAddress物件作為引數傳入即可合併單元格。
//新建工作薄
XSSFWorkbook workbook =new XSSFWorkbook();
//新建工作表
XSSFSheet sheet1=workbook.createSheet("工作表1");
//指定合併開始行、合併結束行 合併開始列、合併結束列
CellRangeAddress rangeAddress=new CellRangeAddress(1,2,1,4);
//新增要合併地址到表格
sheet1.addMergedRegion(rangeAddress);
//建立行,指定起始行號,從0開始
XSSFRow row=sheet1.createRow(1);
//建立單元格,指定起始列號,從0開始
XSSFCell cell=row.createCell(1);
//設定單元格內容
cell.setCellValue("我是合併後的單元格");
//建立樣式物件
CellStyle style=workbook.createCellStyle();
//設定樣式對齊方式:水平\垂直居中
style.setAlignment(HorizontalAlignment.CENTER);
style.setVerticalAlignment(VerticalAlignment.CENTER);
//設定填充單色
style.setFillPattern(FillPatternType.SOLID_FOREGROUND);
//設定背景顏色
style.setFillForegroundColor(IndexedColors.RED.getIndex());
//為指定單元格設定樣式
cell.setCellStyle(style);
FileOutputStream fileout=new FileOutputStream("d:\\chart\\hello-3.xlsx");
workbook.write(fileout);
fileout.close();
【注意:上圖中合併單元格後,單元格的名稱是第一個單元格;即上面中合併了第二到第三行的第二列到第五列,合併後的單元格叫B2,而其它被合併的單元格已經無效了,不能對無效單元格設定值。如果進行了設定將不顯示。】