程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> 關於JAVA >> 讓POI架起Java與Office之間的橋梁一

讓POI架起Java與Office之間的橋梁一

編輯:關於JAVA

本文將闡述如何用POI來讀取/寫入完整的Excel文件。

  

  約定:POI項目2.0版現在已經接近正式發行階段,開發進度迅速,不斷有新的功能集成到原有的系統,同時也有對原有系統的修改。

  

  為了保證本文的及時性,本文將按照最近的1.9開發版說明。雖然編譯最近的發行版源代碼也能正常運行,但現在的代碼和2.0的發行版會有一些出入。

  

  一、Excel基礎

  

  Microsoft Excel 97文件格式也被稱為BIFF8,最近版本的Excel只對該格式作了少量的改動。增加對新格式的支持除了增加項目的復雜性之外,唯一的效果也許只是不得不使每個用戶升級代碼,沒有什麼實際的好處。

  

  因此,在下文說明中,凡是提到Excel 97格式的地方其實都是指Excel從97到XP的格式。

  

  二、HSSF概況

  

  POI項目實現的Excel 97文件格式稱為HSSF??也許你已經猜到,HSSF是Horrible SpreadSheet Format的縮寫,也即“討厭的電子表格格式”(微軟使某些原本簡單的事情過分復雜,同時又過分簡單地處理了某些原本需要靈活性的事情,讓人不勝佩服!)

  

  也許HSSF的名字有點滑稽,就本質而言它是一個非常嚴肅、正規的API。通過HSSF,你可以用純Java代碼來讀取、寫入、修改Excel文件。

  

  前面一篇文章提到了POIFS,那麼HSSF和POIFS又有什麼關系呢?就象其他POI的API一樣,HSSF建立在POIFS的基礎上,因此在HSSF內的有些代碼和前文的某些代碼很相似。不過,當我們編寫基於HSSF API的代碼時,一般不需要了解POIFS API的細節。

  

  HSSF為讀取操作提供了兩類API:usermodel和eventusermodel,即“用戶模型”和“事件-用戶模型”。前者很好理解,後者比較抽象,但操作效率要高得多。usermodel主要有org.apache.poi.hssf.usermodel和org.apache.poi.hssf.eventusermodel包實現(在HSSF的早期版本中,org.apache.poi.hssf.eventusermodel屬於eventmodel包)。

  

  usermodel包把Excel文件映射成我們熟悉的結構,諸如Workbook、Sheet、Row、Cell等,它把整個結構以一組對象的形式保存在內存之中。eventusermodel要求用戶熟悉文件格式的底層結構,它的操作風格類似於XML的SAX API和AWT的事件模型(這就是eventusermodel名稱的起源),要掌握竅門才能用好。

  

  另外,eventusermodel的API只提供讀取文件的功能,也就是說不能用這個API來修改文件。

  

  三、通過usermodel讀取文件

  

  用HSSF的usermodel讀取文件很簡單。首先創建一個InputStream,然後創建一個HSSFWorkbook:

  

  InputStream myxls = new FileInputStream("workbook.xls"));

  HSSFWorkbook wb   = new HSSFWorkbook(myxls);

  

  有了HSSFWorkbook實例,接下來就可以提取工作表、工作表的行和列,例如:

  

  HSSFSheet sheet = wb.getSheetAt(0);    // 第一個工作表

  HSSFRow row   = sheet.getRow(2);    // 第三行

  HSSFCell cell  = row.getCell((short)3); // 第四個單元格

  

  上面這段代碼提取出第一個工作表第三行第四單元格。利用單元格對象可以獲得它的值,提取單元格的值時請注意它的類型:

  

  if (cell.getCellType() == HSSFCell.CELL_TYPE_STRING) {

  ("單元格是字符串,值是: " + cell.getStringCellValue());

  } else if (cell.getCellType() == HSSFCell.CELL_TYPE_NUMERIC) {

  ("單元格是數字,值是: " + cell.getCellValue());

  } else () {

  ("單元格的值不是字符串或數值。");

  }

  

  如果搞錯了數據類型,程序將遇到異常。特別地,用HSSF處理日期數據要小心。Excel內部以數值的形式保存日期數據,區別日期數據的唯一辦法是通過單元格的格式(如果你曾經在Excel中設置過日期格式,應該明白這是什麼意思)。

  

  因此,對於包含日期數據的單元格,cell.getCellType()將返回HSSFCell.CELL_TYPE_NUMERIC,不過利用工具函數HSSFDateUtil.isCellDateFormatted(cell)可以判斷出單元格的值是否為日期。isCellDateFormatted函數通過比較單元格的日期和Excel的內置日期格式得出結論??可以想象,按照這種判斷方法,很多時候isCellDateFormatted函數會返回否定的結論,存在一定的誤判可能。

  

  本文附錄包含了一個在Servlet環境中利用HSSF創建和返回Excel工作簿的實例。

  

  四、通過usermodel寫入文件

  

  寫入XLS文件比讀取XLS文件還要簡單。創建一個HSSFWorkbook實例,然後在適當的時候創建一個把文件寫入磁盤的OutputStream,但延遲到處理結束時創建OutputStream也可以:

  

  HSSFWorkbook wb = new HSSFWorkbook();

  FileOutputStream fileOut

  = new FileOutputStream("workbook.xls");

  wb.write(fileOut);

  fileOut.close();

  

  創建工作表及其內容必須從相應的父對象出發,例如:

  

  HSSFSheet sheet = wb.createSheet();

  HSSFRow row   = sheet.createRow((short)0);

  HSSFCell cell  = row.createCell((short)0);

  cell.setCellValue(1);

  row.createCell((short)1).setCellValue(1.2);

  row.createCell((short)2).setCellValue("一個字符串");

  row.createCell((short)3).setCellValue(true);

  

  如果要設置單元格的樣式,首先要創建一個樣式對象,然後把它指定給一個單元格??或者把它指定給多個具有相同樣式的單元格,例如,如果Excel表格中有一個摘要行,摘要行的數據必須是粗體、斜體,你可以創建一個summaryRowStyle樣式對象,然後把這個樣式指定給所有摘要行上的單元格。

  

  注意,CellFormat和CellStyle對象是工作簿對象的成員,單元格對象只是引用它們。

  ...

  HSSFCellStyle style = workbook.createCellStyle();

  style.setDataFormat

  (HSSFDataFormat.getBuiltinFormat("($#,##0_);[Red]($#,##0)"));

  style.setFillBackgroundColor(HSSFColor.AQUA.index);

  style.setFillPattern(HSSFCellStyle.BIG_SPOTS);

  ...

  someCell.setCellStyle(style);

  someOtherCell.setCellStyle(style);

  

  版本較新的HSSF允許使用數量有限的Excel公式。這一功能目前還是“Beta級質量”,正式使用之前務必仔細測試。指定公式的方式類如:someCell.setCellFormula(SUM(A1:A2:);。

  

  當前,公式中已經可以調用所有內建的函數或操作符,但邏輯操作符和函數(例如IF函數)除外,這部分功能目前還在開發之中。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved