sparta-紫杉 2010-9-28 9:32
JXL官網(http://jexcelapi.sourceforge.net/)
POI官網(http://poi.apache.org/)
注: 目前JXL暫不能支持Excel2007格式。 但POI是可以的。
一、環境
jxl.jar(2.4.2), eclipse3.4.2, jdk1.4.2, oracle9.2.0.1, weblogic8.12。
jxl為開源項目,在對Excle操作時比較方便。
二、背景
在系統項目中,是使用Jxl來讀Excle,以完成從Excle的內容導入到系統數據庫的功能。
但在“成本管理 - 維修費導入”功能中, 用戶需要下載相關的“示例文件”。 “示例文件”中為了實現用戶的“選擇錄入”
(即通過Excel的 數據-有效性-序列 實現用戶下拉選擇相關的內容進行輸入),提前預置了兩列基礎數據,分別為
“維修費類別名稱”和“服務商名稱”, 這兩列數據在數據庫中是不斷更新的, 而這種更新需要及時反映到該“示例文件”的Excel中,
就是說, 數據庫中的數據和示例文件中的數據是相同的,才能使用戶可以選擇錄入完整的數據。
基于上述需要,需要對Jxl對Excel的讀、寫及更新操作進行研究。
三、 Jxl讀Excel的完整代碼

public static void main(String[] args)
{
String filePath = "c:/維修費示例數據格式表.xls";

try
{
Workbook wb = Workbook.getWorkbook( new File( filePath ) );
int sheetCount = wb.getNumberOfSheets();
//逐個sheet表讀數據

for ( int i = 0; i < sheetCount; i++)
{
Sheet sheet = wb.getSheet(i);

if( null != sheet )
{
//逐行逐列讀取數據
int cols = sheet.getColumns();
int rows = sheet.getRows();

for(int j = 0; j < cols; j++)
{

for( int k = 0; k < rows; k++)
{
//顯示各行列數據
System.out.println( sheet.getCell( j, k ).getContents() );
}
}
}
}

} catch (BiffException e)
{
// TODO Auto-generated catch block
e.printStackTrace();

} catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
四、Jxl更新Excel的完整代碼
這里的更新,指的是對已有的Excel文件的某個Sheet表中的某個或某些單元格進行更新(前提是這些單元格里面已經有數據了)。
更新Excle,吐血推薦需要重點注意的兩點:
1、在對單元格進行setString之后,要進行Write(),否則不會寫入(具體表現為被操作的Excle文件提示“文件格式不對”無法打開,文件遭損壞)。
2、是在Excel中的單元格不能為空(是已經有數據了), 若為空,則會提示數據類型不對異常無法更新。
不過,可以通過在需要更新的單元格中預置一個或多個空格就可以了(Jxl默認對存在的空格視為Lable),可以允許更新。
代碼如下:

/** *//**
* 與{@link #SynchronizationUpdate()}相配套,
* 以完成"服務商名稱"在"示例文件"中與數據庫的同步更新。
*
* @param filePath
* 示例文件Excel的完整路徑。
*
*@author sparta 2010-9-26
*
*@return void
*/

public void UpdateServiceProviders( String filePath )
{
CmResultSet rs = null;

//定義存放"服務商"名稱的變量
ArrayList ServicesList = new ArrayList();

// 提取"服務商"的名稱并排序
String sql = "select distinct qymc from htgl_fwsgl_fwsjbxx " +
"where (fwdwid,xh) in " +
"(select fwdwid,max(xh) from htgl_fwsgl_fwsjbxx " +
"where (whfwdwstate=0 or whfwdwstate=4) " +
"group by fwdwid) order by qymc";


try
{

ConnectDB connectDB = new ConnectDB();
rs = connectDB.getRs(sql, null);

// 提取"服務商"名稱并暫放到List中,以備更新到Excel中。

while (rs.next())
{

ServicesList.add(rs.getString(0));
}

} catch (Exception ex)
{
ex.printStackTrace();
logger.error("::::::::::::數據庫連接失效,維修費導入-同步更新'示例文件'的"
+ "'服務商名稱'失敗!");
return;
}


try
{
Workbook wb = Workbook.getWorkbook(new File(filePath));

File targetFile = new File(filePath);
WritableWorkbook wwb = Workbook.createWorkbook(targetFile, wb);

WritableSheet sheet = wwb.getSheet("DB");


if (null != sheet)
{

for (int i = 0; i < ServicesList.size(); i++)
{

WritableCell cell = sheet.getWritableCell( 3, i );

//單元格中若為空,則不允許更新

if ( cell.getType() == CellType.LABEL )
{
Label l = (Label) cell;
l.setString( ServicesList.get(i).toString() );

}
}
}
// 更新到Excel(必須)。
wwb.write();

// 在使用后釋放文件流。
wwb.close();
wb.close();


} catch (Exception e)
{
e.printStackTrace();
logger.error("::::::::::::寫入Excel出現錯誤,維修費導入-同步更新"
+ "'示例文件'的'服務商名稱'失敗!");
}
}
五、Jxl寫Excle的完整代碼
這里的寫,指的是建立Sheet,或增加單元格,完全是在一個新的文件、或新的Sheet、或新的單元格中操作。

public static void main(String[] args)
{
String filePath = "c:/維修費示例數據格式表.xls";

try
{
//建立工作薄
WritableWorkbook wb = Workbook.createWorkbook( new File( filePath ) );
//建立sheet表
WritableSheet sheet = wb.createSheet("DB2", 2);
//增加單元格并寫入數據

try
{
sheet.addCell( new Label(0, 1, "書目ID") );
sheet.addCell( new Label(1, 1, "ISBN") );
sheet.addCell( new Label(2, 1, "定價") );
sheet.addCell( new Label(3, 1, "書名") );

} catch (RowsExceededException e)
{
e.printStackTrace();

} catch (WriteException e)
{
e.printStackTrace();
}
//寫入工作簿
wb.write();
//關閉工作薄

try
{
wb.close();

} catch (WriteException e)
{
e.printStackTrace();
}

} catch (IOException e)
{
e.printStackTrace();
}

}
哈哈,就這么多了,涵蓋了Jxl讀、寫、更新Excle2003的相關代碼,希望看到的人能夠獲得一點啟示,就會心滿意足。
-東營 sparta-紫杉 原創,轉載請注明出處 :)
http://www.tkk7.com/SpartaYew/
SpartaYew@163.com
QQ:22086526