JXL包大解析;Java程式生成excel檔案和解析excel檔案內容

y_keven發表於2013-08-07

最近需求變化,需要把excel匯入 我以前沒有做過,所以我查了一些資料 和參考別人的程式碼
以下是多種方式:

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import jxl.Workbook;
import jxl.format.UnderlineStyle;
import jxl.write.Label;
import jxl.write.WritableFont;
import jxl.write.WritableSheet;
import jxl.write.WritableWorkbook;
import jxl.write.WriteException;
import jxl.write.biff.RowsExceededException;

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;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;


public class ExcelOpt {
/**
* 生成一個Excel檔案 jxl
* @param fileName 要生成的Excel檔名
* @jxl.jar 版本:2.6
*/
public static void writeExcel(String fileName){
WritableWorkbook wwb = null;
try {
//首先要使用Workbook類的工廠方法建立一個可寫入的工作薄(Workbook)物件
wwb = Workbook.createWorkbook(new File(fileName));

} catch (IOException e) {
e.printStackTrace();
}
if(wwb!=null){
//建立一個可寫入的工作表
//Workbook的createSheet方法有兩個引數,第一個是工作表的名稱,第二個是工作表在工作薄中的位置
WritableSheet ws = wwb.createSheet("工作表名稱", 0);

//下面開始新增單元格
for(int i=0;i<10;i++){
for(int j=0;j<5;j++){
//這裡需要注意的是,在Excel中,第一個參數列示列,第二個表示行
Label labelC = new Label(j, i, "這是第"+(i+1)+"行,第"+(j+1)+"列");
try {
//將生成的單元格新增到工作表中
ws.addCell(labelC);
} catch (RowsExceededException e) {
e.printStackTrace();
} catch (WriteException e) {
e.printStackTrace();
}

}
}

try {
//從記憶體中寫入檔案中
wwb.write();
//關閉資源,釋放記憶體
wwb.close();
} catch (IOException e) {
e.printStackTrace();
} catch (WriteException e) {
e.printStackTrace();
}
}
}

/**
* 生成一個Excel檔案POI
* @param inputFile 輸入模板檔案路徑
* @param outputFile 輸入檔案存放於伺服器路徑
* @param dataList 待匯出資料
* @throws Exception
* @roseuid:
*/

public static void exportExcelFile(String inputFile,String outputFile,List dataList) throws Exception{
//用模板檔案構造poi
POIFSFileSystem fs = new POIFSFileSystem(new FileInputStream(inputFile));
//建立模板工作表
HSSFWorkbook templatewb = new HSSFWorkbook(fs);
//直接取模板第一個sheet物件
HSSFSheet templateSheet = templatewb.getSheetAt(1);
//得到模板的第一個sheet的第一行物件 為了得到模板樣式
HSSFRow templateRow = templateSheet.getRow(0);

//HSSFSheet timplateSheet = templatewb.getSheetAt(1);
//取得Excel檔案的總列數
int columns = templateSheet.getRow((short) 0)
.getPhysicalNumberOfCells();
// Debug.println("columns is : " + columns); //=========================
//建立樣式陣列
HSSFCellStyle styleArray[] = new HSSFCellStyle[columns];

//一次性建立所有列的樣式放在陣列裡
for (int s = 0; s < columns; s++) {
//得到陣列例項
styleArray[s] = templatewb.createCellStyle();
}
//迴圈對每一個單元格進行賦值
//定位行
for (int rowId = 1; rowId < dataList.size(); rowId++) {
//依次取第rowId行資料 每一個資料是valueList
List valueList = (List) dataList.get(rowId - 1);
//定位列
for (int columnId = 0; columnId < columns; columnId++) {
//依次取出對應與colunmId列的值
//每一個單元格的值
String dataValue = (String) valueList.get(columnId);
//取出colunmId列的的style
//模板每一列的樣式
HSSFCellStyle style = styleArray[columnId];
//取模板第colunmId列的單元格物件
//模板單元格物件
HSSFCell templateCell = templateRow.getCell((short) columnId);
//建立一個新的rowId行 行物件
//新建的行物件
HSSFRow hssfRow = templateSheet.createRow(rowId);
//建立新的rowId行 columnId列 單元格物件
//新建的單元格物件
HSSFCell cell = hssfRow.createCell((short) columnId);
//如果對應的模板單元格 樣式為非鎖定
if (templateCell.getCellStyle().getLocked() == false) {
//設定此列style為非鎖定
style.setLocked(false);
//設定到新的單元格上
cell.setCellStyle(style);
}
//否則樣式為鎖定
else {
//設定此列style為鎖定
style.setLocked(true);
//設定到新單元格上
cell.setCellStyle(style);
}
//設定編碼
cell.setEncoding(HSSFCell.ENCODING_UTF_16);
//Debug.println("dataValue : " + dataValue);
//設定值 統一為String
cell.setCellValue(dataValue);
}
}
//設定輸入流
FileOutputStream fOut = new FileOutputStream(outputFile);
//將模板的內容寫到輸出檔案上
templatewb.write(fOut);
fOut.flush();

//操作結束,關閉檔案
fOut.close();

}

/**
* 匯出資料為XLS格式
* @param fos 生成Excel檔案Path
* @param bo 要匯入的資料
*/
public static void writeExcelBo(String fos, java.util.List ve)
{
jxl.write.WritableWorkbook wwb;
try
{
wwb= Workbook.createWorkbook(new File(fos));
jxl.write.WritableSheet ws= wwb.createSheet("上市新書", 10);
ws.addCell(new jxl.write.Label(0, 1, "書名"));
ws.addCell(new jxl.write.Label(1, 1, "作者"));
ws.addCell(new jxl.write.Label(2, 1, "定價"));
ws.addCell(new jxl.write.Label(3, 1, "出版社"));
int bookSize=ve.size();
BookVO book = new BookVO();
for (int i= 0; i < bookSize; i++)
{
book= (BookVO)ve.get(i);
ws.addCell(new jxl.write.Label(0, i + 2, "" + book.getBookName()));
ws.addCell(new jxl.write.Label(1, i + 2, book.getBookAuthor()));
ws.addCell(new jxl.write.Label(2, i + 2, "" + book.getBookPrice()));
ws.addCell(new jxl.write.Label(3, i + 2, book.getBookConcern()));

}
// jxl.write.WritableFont wfc=
//new jxl.write.WritableFont(WritableFont.ARIAL,255,WritableFont.BOLD,false,UnderlineStyle.NO_UNDERLINE,jxl.format.Colour.BLACK);
//jxl.write.WritableCellFormat wcfFC= new jxl.write.WritableCellFormat(wfc);
ws.addCell(new jxl.write.Label(0, 0, "2007年07月即將上市新書!"));
wwb.write();
// 關閉Excel工作薄物件
wwb.close();
} catch (IOException e){
} catch (RowsExceededException e){

} catch (WriteException e){
}
}

public static void main(String[] args) {
writeExcel("c:\\Test測試Excel.xls");
System.out.println("OK");
ArrayList list = new ArrayList();

for (int i = 0; i < 10; i++) {
BookVO book = new BookVO();
book.setBookName("WebWork in action+"+i);
book.setBookAuthor("唐勇+"+i);
book.setBookPrice("39元+"+i);
book.setBookConcern("飛思科技+"+i);
list.add(book);
}

writeExcelBo("c:\\上市新書.xls",list);
System.err.println("Book OK!!!");

}

}
=================摘要=====================
java如何操作Excel(資料匯入匯出)(轉)

jxl.jar,可以到http://sourceforge.net/project/showfiles.php?group_id=79926下載。

一.讀取Excel檔案內容

java 程式碼
/**讀取Excel檔案的內容
* @param file 待讀取的檔案
* @return
*/
public static String readExcel(File file){
StringBuffer sb = new StringBuffer();

Workbook wb = null;
try {
//構造Workbook(工作薄)物件
wb=Workbook.getWorkbook(file);
} catch (BiffException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}

if(wb==null)
return null;

//獲得了Workbook物件之後,就可以通過它得到Sheet(工作表)物件了
Sheet[] sheet = wb.getSheets();

if(sheet!=null&&sheet.length>0){
//對每個工作表進行迴圈
for(int i=0;i
//得到當前工作表的行數
int rowNum = sheet[i].getRows();
for(int j=0;j
//得到當前行的所有單元格
Cell[] cells = sheet[i].getRow(j);
if(cells!=null&&cells.length>0){
//對每個單元格進行迴圈
for(int k=0;k
//讀取當前單元格的值
String cellValue = cells[k].getContents();
sb.append(cellValue+"\t");
}
}
sb.append("\r\n");
}
sb.append("\r\n");
}
}
//最後關閉資源,釋放記憶體
wb.close();
return sb.toString();
}
二.寫入Excel檔案

這裡有很多格式了,比如文字內容加粗,加上某些顏色等,可以參考jxl的api.
同時還推薦一篇不錯的文章:http://www.ibm.com/developerworks/cn/java/l-javaExcel/?ca=j-t10

java 程式碼
/**生成一個Excel檔案
* @param fileName 要生成的Excel檔名
*/
public static void writeExcel(String fileName){
WritableWorkbook wwb = null;
try {
//首先要使用Workbook類的工廠方法建立一個可寫入的工作薄(Workbook)物件
wwb = Workbook.createWorkbook(new File(fileName));
} catch (IOException e) {
e.printStackTrace();
}
if(wwb!=null){
//建立一個可寫入的工作表
//Workbook的createSheet方法有兩個引數,第一個是工作表的名稱,第二個是工作表在工作薄中的位置
WritableSheet ws = wwb.createSheet("sheet1", 0);

//下面開始新增單元格
for(int i=0;i<10;i++){
for(int j=0;j<5;j++){
//這裡需要注意的是,在Excel中,第一個參數列示列,第二個表示行
Label labelC = new Label(j, i, "這是第"+(i+1)+"行,第"+(j+1)+"列");
try {
//將生成的單元格新增到工作表中
ws.addCell(labelC);
} catch (RowsExceededException e) {
e.printStackTrace();
} catch (WriteException e) {
e.printStackTrace();
}

}
}

try {
//從記憶體中寫入檔案中
wwb.write();
//關閉資源,釋放記憶體
wwb.close();
} catch (IOException e) {
e.printStackTrace();
} catch (WriteException e) {
e.printStackTrace();
}
}
}
三.在一個Excel檔案中查詢是否包含某一個關鍵字

java 程式碼
/**搜尋某一個檔案中是否包含某個關鍵字
* @param file 待搜尋的檔案
* @param keyWord 要搜尋的關鍵字
* @return
*/
public static boolean searchKeyWord(File file,String keyWord){
boolean res = false;

Workbook wb = null;
try {
//構造Workbook(工作薄)物件
wb=Workbook.getWorkbook(file);
} catch (BiffException e) {
return res;
} catch (IOException e) {
return res;
}

if(wb==null)
return res;

//獲得了Workbook物件之後,就可以通過它得到Sheet(工作表)物件了
Sheet[] sheet = wb.getSheets();

boolean breakSheet = false;

if(sheet!=null&&sheet.length>0){
//對每個工作表進行迴圈
for(int i=0;i
if(breakSheet)
break;

//得到當前工作表的行數
int rowNum = sheet[i].getRows();

boolean breakRow = false;

for(int j=0;j
if(breakRow)
break;
//得到當前行的所有單元格
Cell[] cells = sheet[i].getRow(j);
if(cells!=null&&cells.length>0){
boolean breakCell = false;
//對每個單元格進行迴圈
for(int k=0;k
if(breakCell)
break;
//讀取當前單元格的值
String cellValue = cells[k].getContents();
if(cellValue==null)
continue;
if(cellValue.contains(keyWord)){
res = true;
breakCell = true;
breakRow = true;
breakSheet = true;
}
}
}
}
}
}
//最後關閉資源,釋放記憶體
wb.close();

return res;
}
四.往Excel中插入圖片圖示

插入圖片的實現很容易,參看以下程式碼:

java 程式碼
/**往Excel中插入圖片
* @param dataSheet 待插入的工作表
* @param col 圖片從該列開始
* @param row 圖片從該行開始
* @param width 圖片所佔的列數
* @param height 圖片所佔的行數
* @param imgFile 要插入的圖片檔案
*/
public static void insertImg(WritableSheet dataSheet, int col, int row, int width,
int height, File imgFile){
WritableImage img = new WritableImage(col, row, width, height, imgFile);
dataSheet.addImage(img);
}
以上程式碼的註釋已經很清楚了,大概也就不用再解釋了,我們可以用如下程式驗證:

java 程式碼
try {
//建立一個工作薄
WritableWorkbook workbook = Workbook.createWorkbook(new File("D:/test1.xls"));
//待插入的工作表
WritableSheet imgSheet = workbook.createSheet("Images",0);
//要插入的圖片檔案
File imgFile = new File("D:/1.png");
//圖片插入到第二行第一個單元格,長寬各佔六個單元格
insertImg(imgSheet,0,1,6,6,imgFile);
workbook.write();
workbook.close();
catch (IOException e) {
e.printStackTrace();
catch (WriteException e) {
e.printStackTrace();
但是jxl只支援png格式的圖片,jpg格式和gif格式都不支援
========================================================
jxl.jar包簡介/java操作excel jxl.jar下載地址

jxl.jar 包簡介
下載地址:
http://www.andykhan.com/jexcelapi/ 當前的最高版本是2.6。

真實下載地址:

http://www.andykhan.com/jexcelapi/download.html


作者的網站上對它的特徵有如下描述:
● 支援Excel 95-2000的所有版本
● 生成Excel 2000標準格式
● 支援字型、數字、日期操作
● 能夠修飾單元格屬性
● 支援影象和圖表
應該說以上功能已經能夠大致滿足我們的需要。最關鍵的是這套API是純Java的,並不依賴Windows系統,即使執行在Linux下,它同樣能夠正確的處理Excel檔案。另外需要說明的是,這套API對圖形和圖表的支援很有限,而且僅僅識別PNG格式。
搭建環境
將下載後的檔案解包,得到jxl.jar,放入classpath,安裝就完成了。
基本操作
一、建立檔案
擬生成一個名為“測試資料.xls”的Excel檔案,其中第一個工作表被命名為“第一頁”,大致效果如下:
程式碼(CreateXLS.java):
//生成Excel的類
import java.io.*;
import jxl.*;
import jxl.write.*;
public class CreateXLS
{
public static void main(String args[])
{
try
{
//開啟檔案
WritableWorkbook book=
Workbook.createWorkbook(new File(“測試.xls”));
//生成名為“第一頁”的工作表,引數0表示這是第一頁
WritableSheet sheet=book.createSheet(“第一頁”,0);
//在Label物件的構造子中指名單元格位置是第一列第一行(0,0)
//以及單元格內容為test
Label label=new Label(0,0,”test”);
//將定義好的單元格新增到工作表中
sheet.addCell(label);
/*生成一個儲存數字的單元格
必須使用Number的完整包路徑,否則有語法歧義
單元格位置是第二列,第一行,值為789.123*/
jxl.write.Number number = new jxl.write.Number(1,0,789.123);
sheet.addCell(number);
//寫入資料並關閉檔案
book.write();
book.close();
}catch(Exception e)
{
System.out.println(e);
}
}
}
編譯執行後,會在當前位置產生一個Excel檔案。
三、讀取檔案
以剛才我們建立的Excel檔案為例,做一個簡單的讀取操作,程式程式碼如下:
//讀取Excel的類
import java.io.*;
import jxl.*;
public class ReadXLS
{
public static void main(String args[])
{
try
{
Workbook book=
Workbook.getWorkbook(new File(“測試.xls”));
//獲得第一個工作表物件
Sheet sheet=book.getSheet(0);
//得到第一列第一行的單元格
Cell cell1=sheet.getCell(0,0);
String result=cell1.getContents();
System.out.println(result);
book.close();
}catch(Exception e)
{
System.out.println(e);
}
}
}
程式執行結果:test
四、修改檔案
利用jExcelAPI可以修改已有的Excel檔案,修改Excel檔案的時候,除了開啟檔案的方式不同之外,其他操作和建立Excel是一樣的。下面的例子是在我們已經生成的Excel檔案中新增一個工作表:
//修改Excel的類,新增一個工作表
import java.io.*;
import jxl.*;
import jxl.write.*;
public class UpdateXLS
{
public static void main(String args[])
{
try
{
//Excel獲得檔案
Workbook wb=Workbook.getWorkbook(new File(“測試.xls”));
//開啟一個檔案的副本,並且指定資料寫回到原檔案
WritableWorkbook book=
Workbook.createWorkbook(new File(“測試.xls”),wb);
//新增一個工作表
WritableSheet sheet=book.createSheet(“第二頁”,1);
sheet.addCell(new Label(0,0,”第二頁的測試資料”));
book.write();
book.close();
}catch(Exception e)
{
System.out.println(e);
}
}
}
執行結果如圖:
高階操作
一、 資料格式化
在Excel中不涉及複雜的資料型別,能夠比較好的處理字串、數字和日期已經能夠滿足一般的應用。
1、 字串格式化
字串的格式化涉及到的是字型、粗細、字號等元素,這些功能主要由WritableFont和WritableCellFormat類來負責。假設我們在生成一個含有字串的單元格時,使用如下語句,為方便敘述,我們為每一行命令加了編號:

WritableFont font1=
new WritableFont(WritableFont.TIMES,16,WritableFont.BOLD); 或//設定字型格式為excel支援的格式 WritableFont font3=new WritableFont(WritableFont.createFont("楷體_GB2312"),12,WritableFont.NO_BOLD );① WritableCellFormat format1=new WritableCellFormat(font1); ② Label label=new Label(0,0,”data 4 test”,format1) ③ 其中①指定了字串格式:字型為TIMES,字號16,加粗顯示。WritableFont有非常豐富的構造子,供不同情況下使用,jExcelAPI的java-doc中有詳細列表,這裡不再列出。 ②處程式碼使用了WritableCellFormat類,這個類非常重要,通過它可以指定單元格的各種屬性,後面的單元格格式化中會有更多描述。 ③處使用了Label類的構造子,指定了字串被賦予那種格式。 在WritableCellFormat類中,還有一個很重要的方法是指定資料的對齊方式,比如針對我們上面的例項,可以指定:

//把水平對齊方式指定為居中

format1.setAlignment(jxl.format.Alignment.CENTRE);

//把垂直對齊方式指定為居中

format1.setVerticalAlignment(jxl.format.VerticalAlignment.CENTRE);

//設定自動換行
format1.setWrap(true);



二、單元格操作
Excel中很重要的一部分是對單元格的操作,比如行高、列寬、單元格合併等,所幸jExcelAPI提供了這些支援。這些操作相對比較簡單,下面只介紹一下相關的API。
1、 合併單元格
WritableSheet.mergeCells(int m,int n,int p,int q);
作用是從(m,n)到(p,q)的單元格全部合併,比如:
WritableSheet sheet=book.createSheet(“第一頁”,0);
//合併第一列第一行到第六列第一行的所有單元格
sheet.mergeCells(0,0,5,0);
合併既可以是橫向的,也可以是縱向的。合併後的單元格不能再次進行合併,否則會觸發異常。
2、 行高和列寬
WritableSheet.setRowView(int i,int height);
作用是指定第i+1行的高度,比如:
//將第一行的高度設為200
sheet.setRowView(0,200);
WritableSheet.setColumnView(int i,int width);
作用是指定第i+1列的寬度,比如:
//將第一列的寬度設為30
sheet.setColumnView(0,30);
五、操作圖片
public static void write()throws Exception{
WritableWorkbook wwb=Workbook.createWorkbook(new File("c:/1.xls"));
WritableSheet ws=wwb.createSheet("Test Sheet 1",0);
File file=new File("C:\\jbproject\\PVS\\WebRoot\\weekhit\\1109496996281.png");
WritableImage image=new WritableImage(1, 4, 6, 18,file);
ws.addImage(image);
wwb.write();
wwb.close();
}
很簡單和插入單元格的方式一樣,不過就是引數多了些,WritableImage這個類繼承了Draw,上面只是他構造方法的一種,最後一個引數不用了說了,前面四個引數的型別都是double,依次是 x, y, width, height,注意,這裡的寬和高可不是圖片的寬和高,而是圖片所要佔的單位格的個數,因為繼承的Draw所以他的型別必須是double,具體裡面怎麼實現的我還沒細看:)因為著急趕活,先完成功能,其他的以後有時間慢慢研究。以後會繼續寫出在使用中的心得給大家。
讀:
讀的時候是這樣的一個思路,先用一個輸入流(InputStream)得到Excel檔案,然後用jxl中的Workbook得到工作薄,用Sheet從工作薄中得到工作表,用Cell得到工作表中得某個單元格.
InputStream->Workbook->Sheet->Cell,就得到了excel檔案中的單元格
程式碼:
String path="c:\\excel.xls";//Excel檔案URL
InputStream is = new FileInputStream(path);//寫入到FileInputStream
jxl.Workbook wb = Workbook.getWorkbook(is); //得到工作薄
jxl.Sheet st = wb.getSheet(0);//得到工作薄中的第一個工作表
Cell cell=st.getCell(0,0);//得到工作表的第一個單元格,即A1
String content=cell.getContents();//getContents()將Cell中的字元轉為字串
wb.close();//關閉工作薄
is.close();//關閉輸入流

我們可以通過Sheet的getCell(x,y)方法得到任意一個單元格,x,y和excel中的座標對應.
例如A1對應(0,0),A2對應(0,1),D3對應(3,2).Excel中座標從A,1開始,jxl中全部是從0開始.
還可以通過Sheet的getRows(),getColumns()方法得到行數列數,並用於迴圈控制,輸出一個sheet中的所有內容.
寫:
往Excel中寫入內容主要是用jxl.write包中的類.
思路是這樣的:
OutputStream<-WritableWorkbook<-WritableSheet<-Label
這裡面Label代表的是寫入Sheet的Cell位置及內容.
程式碼:
OutputStream os=new FileOutputStream("c:\\test.xls");//輸出的Excel檔案URL
WritableWorkbook wwb = Workbook.createWorkbook(os);//建立可寫工作薄
WritableSheet ws = wwb.createSheet("sheet1", 0);//建立可寫工作表
Label labelCF=new Label(0, 0, "hello");//建立寫入位置和內容
ws.addCell(labelCF);//將Label寫入sheet中
Label的建構函式Label(int x, int y,String aString)xy意同讀的時候的xy,aString是寫入的內容.
WritableFont wf = new WritableFont(WritableFont.TIMES, 12, WritableFont.BOLD, false);//設定寫入字型
WritableCellFormat wcfF = new WritableCellFormat(wf);//設定CellFormat
Label labelCF=new Label(0, 0, "hello");//建立寫入位置,內容和格式
Label的另一建構函式Label(int c, int r, String cont, CellFormat st)可以對寫入內容進行格式化,設定字型及其它的屬性.
現在可以寫了
wwb.write();
寫完後關閉
wwb.close();
輸出流也關閉吧
os.close;
OK,只要把讀和寫結合起來,就可以在N個Excel中讀取資料寫入你希望的Excel新表中,還是比較方便的.

下面是程式一例:

程式程式碼:sql = "select * from tablename";
rs = stmt.executeQuery(sql);

//新建Excel檔案
String filePath=request.getRealPath("aaa.xls");
File myFilePath=new File(filePath);
if(!myFilePath.exists())
myFilePath.createNewFile();
FileWriter resultFile=new FileWriter(myFilePath);
PrintWriter myFile=new PrintWriter(resultFile);
resultFile.close();

//用JXL向新建的檔案中新增內容
OutputStream outf = new FileOutputStream(filePath);
jxl.write.WritableWorkbook wwb = Workbook.createWorkbook(outf);
jxl.write.WritableSheet ws = wwb.createSheet("sheettest", 0);

int i=0;
int j=0;

for (int k = 0; k < rs.getMetaData().getColumnCount(); k++) {
ws.addCell(new Label(k,0,rs.getMetaData().getColumnName(k+1)));
}

while(rs.next()){
out.println(rs.getMetaData().getColumnCount());

for (int k = 0; k < rs.getMetaData().getColumnCount(); k++) {
ws.addCell(new Label(k,j+i+1,rs.getString(k+1)));
}

i++;
}
wwb.write();
wwb.close();
}catch(Exception e){e.printStackTrace();}
finally{

rs.close();
conn.close();
}

response.sendRedirect("aaa.xls");
==============================================
1 /**
2 * QuickExcel.java
3 * 作者:楊慶成
4 * Created on 2004年11月22日, 下午4:05
5 * 在實際應用中經常要將資料庫中的表匯入Excel
6 * 本人在Apache的POI基礎上寫了一個簡單的類
7 * 有不當指出請指正,謝謝!
8 *
9 */
10
11package yqc.poi;
12
13import java.sql.*;
14import java.util.*;
15import java.io.*;
16import java.io.ByteArrayInputStream;
17import java.io.FileInputStream;
18import java.io.FileOutputStream;
19import java.io.IOException;
20
21import org.apache.poi.hssf.usermodel.*;
22import org.apache.poi.poifs.filesystem.POIFSFileSystem;
23import org.apache.poi.hssf.record.*;
24import org.apache.poi.hssf.model.*;
25import org.apache.poi.hssf.usermodel.*;
26import org.apache.poi.hssf.util.*;import yqc.sql.*;
27
28/**//**
29 *
30 * @author Administrator
31 */
32public class QuickExcel {
33
34 /**//** Creates a new instance of QuickExcel */
35 private QuickExcel(String file){
36 _file=file;
37 }
38
39 private void open()throws IOException{
40 InputStream stream = null;
41 Record[] records = null;
42 POIFSFileSystem fs =
43 new POIFSFileSystem(new FileInputStream(_file));
44 _wb = new HSSFWorkbook(fs);
45 }
46
47 private void create(){
48 _wb=new HSSFWorkbook();
49 }
50
51 public static QuickExcel newInstance (String file){
52 QuickExcel qe=new QuickExcel(file);
53 qe.create();
54 return qe;
55 }
56
57 public static QuickExcel openInstance(String file) throws IOException {
58 QuickExcel qe=new QuickExcel(file);
59 qe.open();
60 return qe;
61 }
62
63 public void close(){
64 try{
65 FileOutputStream fileOut = new FileOutputStream(_file);
66 _wb.write(fileOut);//把Workbook物件輸出到檔案workbook.xls中
67 fileOut.close();
68 }
69 catch (Exception ex){
70 System.out.println(ex.getMessage());
71 }
72 }
73
74 private void removeSheet(String sheetName){
75 int i=_wb.getSheetIndex("sheetName");
76 if (i>=0) _wb.removeSheetAt(i);
77 }
78
79 public int fillSheet (ResultSet rs,String sheetName)throws SQLException {
80 HSSFSheet st= _wb.createSheet(sheetName);
81 ResultSetMetaData rsmd= rs.getMetaData();
82 int index=0;
83 int result=0;
84 HSSFRow row=st.createRow(index++);
85 for(int i=1;i<=rsmd.getColumnCount();++i){
86 HSSFCell cell=row.createCell((short)(i-1));
87 cell.setCellValue(rsmd.getColumnName(i));
88 }
89 while(rs.next()) {
90 result++;
91 row=st.createRow(index++);
92 for(int i=1;i<=rsmd.getColumnCount();++i){
93 HSSFCell cell=row.createCell((short)(i-1));
94 cell.setEncoding(cell.ENCODING_UTF_16);
95 cell.setCellValue(rs.getString(i));
96 }
97 }
98 return result;
99}
100
101 public static void main(String[] args){
102 try{
103 QuickConnection qc=new MssqlConnection("jdbc:microsoft:sqlserver://192.168.0.100:1433;DatabaseName=ls");
104 QuickExcel qe=QuickExcel.newInstance("a.xls");
105 qc.connect();
106 String sql="select * from ls.dbo.radio1_emcee";
107 ResultSet rs=qc.getStatement().executeQuery(sql);
108 qe.fillSheet(rs,"MT");
109 qe.close();
110 qe=QuickExcel.openInstance("a.xls");
111 qe.fillSheet(rs,"MO");
112 qe.close();
113 qc.close();
114 }
115 catch (SQLException ex){
116 System.out.println(ex.getMessage());
117 }
118 catch (IOException ex){
119 System.out.println(ex.getMessage());
120 }
121 }
122
123 HSSFWorkbook _wb;
124 String _file="new.xls";
125}
===================================
/**匯出資料為XLS格式
* @param fos 生成Excel檔案Path
* @param bo 要匯入的資料
*/
public void writeExcelBo(FileOutputStream fos, java.util.Vector ve)
{
jxl.write.WritableWorkbook wwb;
try
{
wwb= Workbook.createWorkbook(fos);
jxl.write.WritableSheet ws= wwb.createSheet("booksheet", 10);
ws.addCell(new jxl.write.Label(0, 1, "書目ID"));
ws.addCell(new jxl.write.Label(1, 1, "ISBN"));
ws.addCell(new jxl.write.Label(2, 1, "定價"));
ws.addCell(new jxl.write.Label(3, 1, "書名"));
ws.addCell(new jxl.write.Label(4, 1, "原書名"));
ws.addCell(new jxl.write.Label(5, 1, "副題名"));
ws.addCell(new jxl.write.Label(6, 1, "著者"));
ws.addCell(new jxl.write.Label(7, 1, "譯者"));
ws.addCell(new jxl.write.Label(8, 1, "版次"));
ws.addCell(new jxl.write.Label(9, 1, "出版地"));
ws.addCell(new jxl.write.Label(10, 1, "出版社"));
ws.addCell(new jxl.write.Label(11, 1, "出版日期"));
ws.addCell(new jxl.write.Label(12, 1, "頁數"));
ws.addCell(new jxl.write.Label(13, 1, "書高"));
ws.addCell(new jxl.write.Label(14, 1, "裝幀"));
ws.addCell(new jxl.write.Label(15, 1, "叢書名"));
ws.addCell(new jxl.write.Label(16, 1, "一般性附註項"));
ws.addCell(new jxl.write.Label(17, 1, "簡介"));
ws.addCell(new jxl.write.Label(18, 1, "主題詞"));
ws.addCell(new jxl.write.Label(19, 1, "中圖法分類"));
ws.addCell(new jxl.write.Label(20, 1, "更新日期"));
ws.addCell(new jxl.write.Label(21, 1, "本數"));
book=new Book[ve.size()];
for (int i= 0; i < ve.size(); i++)
{
book[i]= (Book)ve.get(i);
ws.addCell(new jxl.write.Label(0, i + 2, "" + book[i].getBookId()));
ws.addCell(new jxl.write.Label(1, i + 2, book[i].getIsbn()));
ws.addCell(new jxl.write.Label(2, i + 2, "" + book[i].getPrice()));
ws.addCell(new jxl.write.Label(3, i + 2, book[i].getBookTitle()));
ws.addCell(new jxl.write.Label(4, i + 2, book[i].getOldFilename()));
ws.addCell(new jxl.write.Label(5, i + 2, book[i].getSubTitle()));
ws.addCell(new jxl.write.Label(6, i + 2, book[i].getWriter()));
ws.addCell(new jxl.write.Label(7, i + 2, book[i].getTranscribe()));
ws.addCell(new jxl.write.Label(8, i + 2, "" + book[i].getVersion()));
ws.addCell(new jxl.write.Label(9, i + 2, book[i].getPublishCity()));
ws.addCell(new jxl.write.Label(10, i + 2, book[i].getPublisher()));
ws.addCell(new jxl.write.Label(11, i + 2, book[i].getPublishDate().toString()));
ws.addCell(new jxl.write.Label(12, i + 2, "" + book[i].getPage()));
ws.addCell(new jxl.write.Label(13, i + 2, "" + book[i].getHight()));
ws.addCell(new jxl.write.Label(14, i + 2, book[i].getInstall()));
ws.addCell(new jxl.write.Label(15, i + 2, book[i].getSeries()));
ws.addCell(new jxl.write.Label(16, i + 2, book[i].getNotes()));
ws.addCell(new jxl.write.Label(17, i + 2, book[i].getPrecisnotes()));
ws.addCell(new jxl.write.Label(18, i + 2, book[i].getSubject()));
ws.addCell(new jxl.write.Label(19, i + 2, book[i].getCls().replaceAll("_", "")));
ws.addCell(new jxl.write.Label(20, i + 2, book[i].getUpdatedate().toString()));
ws.addCell(new jxl.write.Label(21, i + 2, "0"));
}
jxl.write.WritableFont wfc=
new jxl.write.WritableFont(
WritableFont.ARIAL,
255,
WritableFont.BOLD,
false,
UnderlineStyle.NO_UNDERLINE,
jxl.format.Colour.BLACK);
jxl.write.WritableCellFormat wcfFC= new jxl.write.WritableCellFormat(wfc);
ws.addCell(new jxl.write.Label(0, 0, "為保證您提交定單的穩定和正確,匯入定單時候請勿更改此表格式(請勿更改書目ID,訂購本數自行新增!)"));
wwb.write();
//關閉Excel工作薄物件
wwb.close();
} catch (IOException e)
{} catch (RowsExceededException e)
{} catch (WriteException e)
{}
}

//匯入EXCEL
if (f.getName().indexOf(".xls") > 0)
{
try
{
fis= new FileInputStream(f);
BookBean bob= new BookBean();
UserBean usb= new UserBean();
jxl.Workbook rwb= Workbook.getWorkbook(fis);
jxl.Sheet sh= rwb.getSheet(0);
int rowCount= sh.getRows();
SimpleDateFormat sdf= new SimpleDateFormat("dd/MM/yyyy");
book= new Book[rowCount - 1];
for (int i= 1; i < rowCount; i++)
{
book[i - 1]= new Book();
jxl.Cell[] ce= sh.getRow(i);
book[i - 1].setIsbn(ce[0].getContents().toString());
book[i - 1].setSeries(ce[1].getContents().toString());
book[i - 1].setBookTitle(ce[2].getContents().toString());
book[i - 1].setWriter(ce[3].getContents().toString());
book[i - 1].setTranscribe(ce[4].getContents().toString());
book[i - 1].setPublisher(ce[5].getContents().toString());
book[i - 1].setPublishDate(sdf.parse(ce[6].getContents().toString(), new ParsePosition(0)));
book[i-1].setVersion(Integer.parseInt(ce[7].getContents().toString()));
book[i-1].setPage(Integer.parseInt(ce[8].getContents().toString()));
book[i-1].setCls(ce[9].getContents().toString());
book[i-1].setPrecisnotes(ce[10].getContents().toString());
book[i-1].setInstall(ce[11].getContents().toString());
book[i-1].setPrice(Float.parseFloat(ce[12].getContents().toString()));
book[i-1].setUserid(usb.getUser().getUserid());
getVector().addElement(book[i - 1]);
}
rwb.close();
fis.close();
} catch (FileNotFoundException e)
{} catch (BiffException e)
{} catch (IOException e)
{} catch (NumberFormatException e)
{
ShowMessage("資料匯入失敗,請按照本軟體要求的EXCEL格式匯入定單");
}
}
=================================================

文件選項


級別: 初級

Rubber (mailto:userid@us.ibm.com?subject=利用JAVA操作EXCEL檔案&cc=userid@us.ibm.com),

2003 年 1 月 11 日

使用Windows作業系統的朋友對Excel(電子表格)一定不會陌生,但是要使用Java語言來操縱Excel檔案並不是一件容易的事。在Web應用日益盛行的今天,通過Web來操作Excel檔案的需求越來越強烈,目前較為流行的操作是在JSP或Servlet 中建立一個CSV (comma separated values)檔案,並將這個檔案以MIME,text/csv型別返回給瀏覽器,接著瀏覽器呼叫Excel並且顯示CSV檔案。這樣只是說可以訪問到Excel檔案,但是還不能真正的操縱Excel檔案,本文將給大家一個驚喜,向大家介紹一個開放原始碼專案,Java Excel API,使用它大家就可以方便地操縱Excel檔案了。

JAVA EXCEL API簡介

Java Excel是一開放原始碼專案,通過它Java開發人員可以讀取Excel檔案的內容、建立新的Excel檔案、更新已經存在的Excel檔案。使用該API非Windows作業系統也可以通過純Java應用來處理Excel資料表。因為是使用Java編寫的,所以我們在Web應用中可以通過JSP、Servlet來呼叫API實現對Excel資料表的訪問。

現在釋出的穩定版本是V2.0,提供以下功能:

  • 從Excel 95、97、2000等格式的檔案中讀取資料;
  • 讀取Excel公式(可以讀取Excel 97以後的公式);
  • 生成Excel資料表(格式為Excel 97);
  • 支援字型、數字、日期的格式化;
  • 支援單元格的陰影操作,以及顏色操作;
  • 修改已經存在的資料表;

現在還不支援以下功能,但不久就會提供了:

  1. 不能夠讀取圖表資訊;
  2. 可以讀,但是不能生成公式,任何型別公式最後的計算值都可以讀出;



回頁首


應用示例

1 從Excel檔案讀取資料表

Java Excel API既可以從本地檔案系統的一個檔案(.xls),也可以從輸入流中讀取Excel資料表。讀取Excel資料表的第一步是建立Workbook(術語:工作薄),下面的程式碼片段舉例說明了應該如何操作:(完整程式碼見ExcelReading.java)

import java.io.*;
                        import jxl.*;
                        … … … …
                        try
                        {
                        //構建Workbook物件, 只讀Workbook物件
                        //直接從本地檔案建立Workbook
                        //從輸入流建立Workbook
                        InputStream is = new FileInputStream(sourcefile);
                        jxl.Workbook rwb = Workbook.getWorkbook(is);
                        }
                        catch (Exception e)
                        {
                        e.printStackTrace();
                        }
                        

一旦建立了Workbook,我們就可以通過它來訪問Excel Sheet(術語:工作表)。參考下面的程式碼片段:

//獲取第一張Sheet表
                        Sheet rs = rwb.getSheet(0);
                        

我們既可能通過Sheet的名稱來訪問它,也可以通過下標來訪問它。如果通過下標來訪問的話,要注意的一點是下標從0開始,就像陣列一樣。

一旦得到了Sheet,我們就可以通過它來訪問Excel Cell(術語:單元格)。參考下面的程式碼片段:

//獲取第一行,第一列的值
                        Cell c00 = rs.getCell(0, 0);
                        String strc00 = c00.getContents();
                        //獲取第一行,第二列的值
                        Cell c10 = rs.getCell(1, 0);
                        String strc10 = c10.getContents();
                        //獲取第二行,第二列的值
                        Cell c11 = rs.getCell(1, 1);
                        String strc11 = c11.getContents();
                        System.out.println("Cell(0, 0)" + " value : " + strc00 + "; type : " + c00.getType());
                        System.out.println("Cell(1, 0)" + " value : " + strc10 + "; type : " + c10.getType());
                        System.out.println("Cell(1, 1)" + " value : " + strc11 + "; type : " + c11.getType());
                        

如果僅僅是取得Cell的值,我們可以方便地通過getContents()方法,它可以將任何型別的Cell值都作為一個字串返回。示例程式碼中Cell(0, 0)是文字型,Cell(1, 0)是數字型,Cell(1,1)是日期型,通過getContents(),三種型別的返回值都是字元型。

如果有需要知道Cell內容的確切型別,API也提供了一系列的方法。參考下面的程式碼片段:

String strc00 = null;
                        double strc10 = 0.00;
                        Date strc11 = null;
                        Cell c00 = rs.getCell(0, 0);
                        Cell c10 = rs.getCell(1, 0);
                        Cell c11 = rs.getCell(1, 1);
                        if(c00.getType() == CellType.LABEL)
                        {
                        LabelCell labelc00 = (LabelCell)c00;
                        strc00 = labelc00.getString();
                        }
                        if(c10.getType() == CellType.NUMBER)
                        {
                        NmberCell numc10 = (NumberCell)c10;
                        strc10 = numc10.getValue();
                        }
                        if(c11.getType() == CellType.DATE)
                        {
                        DateCell datec11 = (DateCell)c11;
                        strc11 = datec11.getDate();
                        }
                        System.out.println("Cell(0, 0)" + " value : " + strc00 + "; type : " + c00.getType());
                        System.out.println("Cell(1, 0)" + " value : " + strc10 + "; type : " + c10.getType());
                        System.out.println("Cell(1, 1)" + " value : " + strc11 + "; type : " + c11.getType());
                        

在得到Cell物件後,通過getType()方法可以獲得該單元格的型別,然後與API提供的基本型別相匹配,強制轉換成相應的型別,最後呼叫相應的取值方法getXXX(),就可以得到確定型別的值。API提供了以下基本型別,與Excel的資料格式相對應,如下圖所示:




每種型別的具體意義,請參見Java Excel API Document。

當你完成對Excel電子表格資料的處理後,一定要使用close()方法來關閉先前建立的物件,以釋放讀取資料表的過程中所佔用的記憶體空間,在讀取大量資料時顯得尤為重要。參考如下程式碼片段:

//操作完成時,關閉物件,釋放佔用的記憶體空間
                        rwb.close();
                        

Java Excel API提供了許多訪問Excel資料表的方法,在這裡我只簡要地介紹幾個常用的方法,其它的方法請參考附錄中的Java Excel API Document。

Workbook類提供的方法

1. int getNumberOfSheets()
獲得工作薄(Workbook)中工作表(Sheet)的個數,示例:

jxl.Workbook rwb = jxl.Workbook.getWorkbook(new File(sourcefile));
                        int sheets = rwb.getNumberOfSheets();
                        

2. Sheet[] getSheets()
返回工作薄(Workbook)中工作表(Sheet)物件陣列,示例:

jxl.Workbook rwb = jxl.Workbook.getWorkbook(new File(sourcefile));
                        Sheet[] sheets = rwb.getSheets();
                        

3. String getVersion()
返回正在使用的API的版本號,好像是沒什麼太大的作用。

jxl.Workbook rwb = jxl.Workbook.getWorkbook(new File(sourcefile));
                        String apiVersion = rwb.getVersion();
                        

Sheet介面提供的方法

1) String getName()
獲取Sheet的名稱,示例:

jxl.Workbook rwb = jxl.Workbook.getWorkbook(new File(sourcefile));
                        jxl.Sheet rs = rwb.getSheet(0);
                        String sheetName = rs.getName();
                        

2) int getColumns()
獲取Sheet表中所包含的總列數,示例:

jxl.Workbook rwb = jxl.Workbook.getWorkbook(new File(sourcefile));
                        jxl.Sheet rs = rwb.getSheet(0);
                        int rsColumns = rs.getColumns();
                        

3) Cell[] getColumn(int column)
獲取某一列的所有單元格,返回的是單元格物件陣列,示例:

jxl.Workbook rwb = jxl.Workbook.getWorkbook(new File(sourcefile));
                        jxl.Sheet rs = rwb.getSheet(0);
                        Cell[] cell = rs.getColumn(0);
                        

4) int getRows()
獲取Sheet表中所包含的總行數,示例:

jxl.Workbook rwb = jxl.Workbook.getWorkbook(new File(sourcefile));
                        jxl.Sheet rs = rwb.getSheet(0);
                        int rsRows = rs.getRows();
                        

5) Cell[] getRow(int row)
獲取某一行的所有單元格,返回的是單元格物件陣列,示例子:

jxl.Workbook rwb = jxl.Workbook.getWorkbook(new File(sourcefile));
                        jxl.Sheet rs = rwb.getSheet(0);
                        Cell[] cell = rs.getRow(0);
                        

6) Cell getCell(int column, int row)
獲取指定單元格的物件引用,需要注意的是它的兩個引數,第一個是列數,第二個是行數,這與通常的行、列組合有些不同。

jxl.Workbook rwb = jxl.Workbook.getWorkbook(new File(sourcefile));
                        jxl.Sheet rs = rwb.getSheet(0);
                        Cell cell = rs.getCell(0, 0);
                        

2 生成新的Excel工作薄

下面的程式碼主要是向大家介紹如何生成簡單的Excel工作表,在這裡單元格的內容是不帶任何修飾的(如:字型,顏色等等),所有的內容都作為字串寫入。(完整程式碼見ExcelWriting.java)

與讀取Excel工作表相似,首先要使用Workbook類的工廠方法建立一個可寫入的工作薄(Workbook)物件,這裡要注意的是,只能通過API提供的工廠方法來建立Workbook,而不能使用WritableWorkbook的建構函式,因為類WritableWorkbook的建構函式為protected型別。示例程式碼片段如下:

import java.io.*;
                        import jxl.*;
                        import jxl.write.*;
                        … … … …
                        try
                        {
                        //構建Workbook物件, 只讀Workbook物件
                        //Method 1:建立可寫入的Excel工作薄
                        jxl.write.WritableWorkbook wwb = Workbook.createWorkbook(new File(targetfile));
                        //Method 2:將WritableWorkbook直接寫入到輸出流
                        /*
                        OutputStream os = new FileOutputStream(targetfile);
                        jxl.write.WritableWorkbook wwb = Workbook.createWorkbook(os);
                        */
                        }
                        catch (Exception e)
                        {
                        e.printStackTrace();
                        }
                        

API提供了兩種方式來處理可寫入的輸出流,一種是直接生成本地檔案,如果檔名不帶全路徑的話,預設的檔案會定位在當前目錄,如果檔名帶有全路徑的話,則生成的Excel檔案則會定位在相應的目錄;另外一種是將Excel物件直接寫入到輸出流,例如:使用者通過瀏覽器來訪問Web伺服器,如果HTTP頭設定正確的話,瀏覽器自動呼叫客戶端的Excel應用程式,來顯示動態生成的Excel電子表格。

接下來就是要建立工作表,建立工作表的方法與建立工作薄的方法幾乎一樣,同樣是通過工廠模式方法獲得相應的物件,該方法需要兩個引數,一個是工作表的名稱,另一個是工作表在工作薄中的位置,參考下面的程式碼片段:

//建立Excel工作表
                        jxl.write.WritableSheet ws = wwb.createSheet("Test Sheet 1", 0);
                        

"這鍋也支好了,材料也準備齊全了,可以開始下鍋了!",現在要做的只是例項化API所提供的Excel基本資料型別,並將它們新增到工作表中就可以了,參考下面的程式碼片段:

//1.新增Label物件
                        jxl.write.Label labelC = new jxl.write.Label(0, 0, "This is a Label cell");
                        ws.addCell(labelC);
                        //新增帶有字型Formatting的物件
                        jxl.write.WritableFont wf = new jxl.write.WritableFont(WritableFont.TIMES, 18, WritableFont.BOLD, true);
                        jxl.write.WritableCellFormat wcfF = new jxl.write.WritableCellFormat(wf);
                        jxl.write.Label labelCF = new jxl.write.Label(1, 0, "This is a Label Cell", wcfF);
                        ws.addCell(labelCF);
                        //新增帶有字型顏色Formatting的物件
                        jxl.write.WritableFont wfc = new jxl.write.WritableFont(WritableFont.ARIAL, 10, WritableFont.NO_BOLD, false,
                        UnderlineStyle.NO_UNDERLINE, jxl.format.Colour.RED);
                        jxl.write.WritableCellFormat wcfFC = new jxl.write.WritableCellFormat(wfc);
                        jxl.write.Label labelCFC = new jxl.write.Label(1, 0, "This is a Label Cell", wcfFC);
                        ws.addCell(labelCF);
                        //2.新增Number物件
                        jxl.write.Number labelN = new jxl.write.Number(0, 1, 3.1415926);
                        ws.addCell(labelN);
                        //新增帶有formatting的Number物件
                        jxl.write.NumberFormat nf = new jxl.write.NumberFormat("#.##");
                        jxl.write.WritableCellFormat wcfN = new jxl.write.WritableCellFormat(nf);
                        jxl.write.Number labelNF = new jxl.write.Number(1, 1, 3.1415926, wcfN);
                        ws.addCell(labelNF);
                        //3.新增Boolean物件
                        jxl.write.Boolean labelB = new jxl.write.Boolean(0, 2, false);
                        ws.addCell(labelB);
                        //4.新增DateTime物件
                        jxl.write.DateTime labelDT = new jxl.write.DateTime(0, 3, new java.util.Date());
                        ws.addCell(labelDT);
                        //新增帶有formatting的DateFormat物件
                        jxl.write.DateFormat df = new jxl.write.DateFormat("dd MM yyyy hh:mm:ss");
                        jxl.write.WritableCellFormat wcfDF = new jxl.write.WritableCellFormat(df);
                        jxl.write.DateTime labelDTF = new jxl.write.DateTime(1, 3, new java.util.Date(), wcfDF);
                        ws.addCell(labelDTF);
                        

這裡有兩點大家要引起大家的注意。第一點,在構造單元格時,單元格在工作表中的位置就已經確定了。一旦建立後,單元格的位置是不能夠變更的,儘管單元格的內容是可以改變的。第二點,單元格的定位是按照下面這樣的規律(column, row),而且下標都是從0開始,例如,A1被儲存在(0, 0),B1被儲存在(1, 0)。

最後,不要忘記關閉開啟的Excel工作薄物件,以釋放佔用的記憶體,參見下面的程式碼片段:

//寫入Exel工作表
                        wwb.write();
                        //關閉Excel工作薄物件
                        wwb.close();
                        

這可能與讀取Excel檔案的操作有少少不同,在關閉Excel物件之前,你必須要先呼叫write()方法,因為先前的操作都是儲存在快取中的,所以要通過該方法將操作的內容儲存在檔案中。如果你先關閉了Excel物件,那麼只能得到一張空的工作薄了。

3 拷貝、更新Excel工作薄

接下來簡要介紹一下如何更新一個已經存在的工作薄,主要是下面二步操作,第一步是構造只讀的Excel工作薄,第二步是利用已經建立的Excel工作薄建立新的可寫入的Excel工作薄,參考下面的程式碼片段:(完整程式碼見ExcelModifying.java)

//建立只讀的Excel工作薄的物件
                        jxl.Workbook rw = jxl.Workbook.getWorkbook(new File(sourcefile));
                        //建立可寫入的Excel工作薄物件
                        jxl.write.WritableWorkbook  wwb = Workbook.createWorkbook(new File(targetfile), rw);
                        //讀取第一張工作表
                        jxl.write.WritableSheet ws = wwb.getSheet(0);
                        //獲得第一個單元格物件
                        jxl.write.WritableCell wc = ws.getWritableCell(0, 0);
                        //判斷單元格的型別, 做出相應的轉化
                        if(wc.getType() == CellType.LABEL)
                        {
                        Label l = (Label)wc;
                        l.setString("The value has been modified.");
                        }
                        //寫入Excel物件
                        wwb.write();
                        //關閉可寫入的Excel物件
                        wwb.close();
                        //關閉只讀的Excel物件
                        rw.close();
                        

之所以使用這種方式構建Excel物件,完全是因為效率的原因,因為上面的示例才是API的主要應用。為了提高效能,在讀取工作表時,與資料相關的一些輸出資訊,所有的格式資訊,如:字型、顏色等等,是不被處理的,因為我們的目的是獲得行資料的值,既使沒有了修飾,也不會對行資料的值產生什麼影響。唯一的不利之處就是,在記憶體中會同時儲存兩個同樣的工作表,這樣當工作表體積比較大時,會佔用相當大的記憶體,但現在好像記憶體的大小並不是什麼關鍵因素了。

一旦獲得了可寫入的工作表物件,我們就可以對單元格物件進行更新的操作了,在這裡我們不必呼叫API提供的add()方法,因為單元格已經於工作表當中,所以我們只需要呼叫相應的setXXX()方法,就可以完成更新的操作了。

盡單元格原有的格式化修飾是不能去掉的,我們還是可以將新的單元格修飾加上去,以使單元格的內容以不同的形式表現。

新生成的工作表物件是可寫入的,我們除了更新原有的單元格外,還可以新增新的單元格到工作表中,這與示例2的操作是完全一樣的。

最後,不要忘記呼叫write()方法,將更新的內容寫入到檔案中,然後關閉工作薄物件,這裡有兩個工作薄物件要關閉,一個是隻讀的,另外一個是可寫入的。


相關文章