之前都是用csv文件的,簡單暴力,但是未免太過弱小,很多東西實現不了,所以正好有時間學一學一個非常流行的excel處理庫:jxl
讀取excel
JExcelApi支持從文件和輸入流讀取excel表格。要想讀取excel第一步你應該創建一個Workbook:
import java.io.File;
import java.util.Date;
import jxl.*;
...
Workbook workbook = Workbook.getWorkbook(new File("myfile.xls"));
(需要注意的是如果是來自輸入流創建的表格,你需要把http的header信息刪掉)
你聲明瞭一個workbook後你就可以通過下面的方法來訪問sheets(工作表的意思)了
sheets是從序號0開始的的,當然你也可以通過sheets的名字去取到sheets對象
Sheet sheet = workbook.getSheet(0);
取到了sheets對象之後,你就可以訪問裏面的元素了。可以使用getContents()方法返回string類型的內容,比如下面的例子,A1是一個文本類型,B2是數字類型,C2是日期類型,那麼可以這麼訪問(可以看出cells是再封裝了一層的,然後才調用getContents):
Cell a1 = sheet.getCell(0,0);
Cell b2 = sheet.getCell(1,1);
Cell c2 = sheet.getCell(2,1);
String stringa1 = a1.getContents();
String stringb2 = b2.getContents();
String stringc2 = c2.getContents();
// Do stuff with the strings etc
...
然而,如果你想要作爲一個具體類型訪問cells的話,比如數字、時間,那麼就需要進行轉換,並且提供了getType方法判斷,避免轉型錯誤。
String stringa1 = null;
double numberb2 = 0;
Date datec2 = null;
Cell a1 = sheet.getCell(0,0);
Cell b2 = sheet.getCell(1,1);
Cell c2 = sheet.getCell(2,1);
if (a1.getType() == CellType.LABEL)
{
LabelCell lc = (LabelCell) a1;
stringa1 = lc.getString();
}
if (b2.getType() == CellType.NUMBER)
{
NumberCell nc = (NumberCell) b2;
numberb2 = nc.getValue();
}
if (c2.getType() == CellType.DATE)
{
DateCell dc = (DateCell) c2;
datec2 = dc.getDate();
}
// Do stuff with dates and doubles
...
(cell對象分別轉成對應的類型封裝,再通過get方法獲取java裏面的對應類型)
當你完成所有工作後,使用close()方法釋放內存
// Finished - close the workbook and free up memory
workbook.close();
寫excel
這一部分是教你怎麼寫的簡單無格式的數據,比如沒有字體呀,小數點呀
和讀excel一樣,第一步是創建一個Workbook對象
import java.io.File;
import java.util.Date;
import jxl.*;
import jxl.write.*;
...
WritableWorkbook workbook = Workbook.createWorkbook(new File("output.xls"));
這句話是新創建一個名爲output.xls的workbook對象,這個api也可以直接從客戶端瀏覽器直接發送一個輸出流給服務器,如果http的頭信息設置正確的話,那麼就會成功打開excel文件了。
下一步,就要爲workbook創建sheet對象了,嗯可以看出是在第0個位置創建某個名字的sheet了。
WritableSheet sheet = workbook.createSheet("First Sheet", 0);
現在,就要把數據加到workbook裏面,下面是把數據加到sheet裏面去的簡單實例,需要把一個文本寫到a3位置,把數據3.14159寫到d5位置
Label label = new Label(0, 2, "A label record");
sheet.addCell(label);
Number number = new Number(3, 4, 3.1459);
sheet.addCell(number);
這裏有兩點要注意的,第一點,cell的位置是表格信息的一部分了,所以你之後更新cell的內容的時候位置也無法更改。
另外一點,cell的位置是從0開始計數的。
一旦你寫完新加的sheet和cell,請在workbook調用write()方法,然後關閉它,一定要調用write(),不然無法保存(類似output的flush方法了)。
...
// All sheets and cells added. Now write out the workbook
workbook.write();
workbook.close();
增加格式化信息
上面兩部分只是JExcelApi的用法,然而現在我們的excel展示的是默認的字體,並且只保留小數點後三位,那麼爲了給excel增加格式化信息,我們可以使用重載的構造方法去給我們的cell增加額外的格式化信息,就是字體和樣式了。
下面的代碼演示了創建字體爲arial,大小爲10的文本
// Create a cell format for Arial 10 point font
WritableFont arial10font = new WritableFont(WritableFont.ARIAL, 10);
WritableCellFormat arial10format = new WritableCellFormat (arial10font);
// Create the label, specifying content and format
Label label2 = new Label(1,0, "Arial 10 point label", arial10format);
sheet.addCell(label2);
這樣的話以後就可以複用這些樣式了。
同時,WritableFont 也提供了多個重載的方法,以便適應不同的格式
// Create a cell format for Times 16, bold and italic
WritableFont times16font = new WritableFont(WritableFont.TIMES, 16, WritableFont.BOLD, true);
WritableCellFormat times16format = new WritableCellFormat (times16font);
// Create the label, specifying content and format
Label label4 = new Label(3,0, "Times 16 bold italic label", times16format);
sheet.addCell(label4);
格式化數字
數字類型的格式化結構是類似的,不同類型的格式已經定義好了
WritableCellFormat integerFormat = new WritableCellFormat (NumberFormats.INTEGER);
Number number2 = new Number(0, 4, 3.141519, integerFormat);
sheet.addCell(number2);
WritableCellFormat floatFormat = new WritableCellFormat (NumberFormats.FLOAT);
Number number3 = new Number(1, 4, 3.141519, floatFormat);
sheet.addCell(number3);
上面的例子是分別在A5和B5寫入3.141519數字,但是因爲格式類型不同,那麼在A5展示的是3,而B5展示的是3.14
那麼你也可以自定義格式的,下面例子就是自定義展示的數字位數
NumberFormat fivedps = new NumberFormat("#.#####");
WritableCellFormat fivedpsFormat = new WritableCellFormat(fivedps);
Number number4 = new Number(2, 4, 3.141519, fivedpsFormat);
sheet.addCell(number4);
當然,你也可以和我們定義文本的格式對象一塊使用:
WritableCellFormat fivedpsFontFormat = new WritableCellFormat (times16font, fivedps);
Number number5 = new Number(3, 4, 3.141519, fivedpsFontFormat);
sheet.addCell(number5);
格式化日期
日期格式化也是類似數字類型格式化,使用自帶的ava.text.SimpleDateFormat類格式化,同時jxl也預置了幾個格式,定在在 jxl.write.DateFormat裏面
// Get the current date and time from the Calendar object
Date now = Calendar.getInstance().getTime();
DateFormat customDateFormat = new DateFormat ("dd MMM yyyy hh:mm:ss");
WritableCellFormat dateFormat = new WritableCellFormat (customDateFormat);
DateTime dateCell = new DateTime(0, 6, now, dateFormat);
sheet.addCell(dateCell);
和數字格式化一樣,文本格式化對象也可以應用在日期對象格式上
如果想要學習更多的擴展,那麼去學習實例的Write.java吧麪包括背景、顏色等的定義
複製和修改excel
這一部分是教你怎麼更新excel裏面的內容的
第一步還是讀取excel
import java.io.File;
import java.util.Date;
import jxl.*;
import jxl.write.*;
...
Workbook workbook = Workbook.getWorkbook(new File("myfile.xls"));
下面這一步會創建一個上一部打開的excel副本,並轉爲可寫的workbook對象
WritableWorkbook copy = Workbook.createWorkbook(new File("output.xls"), workbook);
那麼使用上面的方法去複製一個副本修改excel表格,是很有效率的,因爲不會把一些格式化的類型加載進來,但是這個方法會在內存創建兩個workbook對象,會佔用兩倍的內存。
一旦我們轉成可寫的workbook對象,我們會就能夠得到可寫的cell對象。下面的代碼就告訴你怎麼修改cell了
WritableSheet sheet2 = copy.getSheet(1);
WritableCell cell = sheet2.getWritableCell(1, 2);
if (cell.getType() == CellType.LABEL)
{
Label l = (Label) cell;
l.setString("modified cell");
}
我們不需要調用add()方法,一旦cell加載到sheet內,那麼裏面內容就是可以修改了的,通過setXXX方法去修改。
然而,cell的格式化是不可變的,下面就是從新定義一個格式化對象咯
WritableSheet sheet2 = copy.getSheet(1);
WritableCell cell = sheet2.getWritableCell(2, 4);
NumberFormat fivedps = new NumberFormat("#.#####");
WritableCellFormat cellFormat = new WritableCellFormat(fivedps);
cell.setFormat(cellFormat);
一旦是可修改的workbook對象,那麼也可以新增加cell。
最後別忘記了寫和關閉的操作
...
// All cells modified/added. Now write out the workbook
copy.write();
copy.close();
嗯,官方還給我們提供了寫的例子,在ReadWrite.java裏面,但是不要修改jxlrwtest.xls這個文件,不然會運行不了。