在日常工作中,我們常常會進行檔案讀寫操作,除去我們最常用的純文字檔案讀寫,更多時候我們需要對Excel中的資料進行讀取操作,本文将介紹Excel讀寫的常用方法,希望對大家學習Java讀寫Excel會有幫助。
在開始進行Java讀寫Excel前,我們需要先下一個jxl的jar包,這個jar包中提供了相關讀寫Excel的方法,在百度裡所搜一下jxl.jar下載下傳就會出現很多下載下傳位址了,這裡不再累述。随後我們将jxl.jar放到classpath下或者在工程的buildpath中添加jxl.jar後,便可以開始Java讀寫Excel的神秘之旅了。
1、Java讀取Excel資料
首先,建立一個xls檔案(如:jxltest.xls),然後在檔案中添加一些資料,Excel檔案建立完成後,我們便可以開始寫代碼讀取了:
代碼如下:
[java] view plaincopy
package jxl.zhanhj;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import jxl.Sheet;
import jxl.Workbook;
import jxl.read.biff.BiffException;
public class GetExcelInfo {
public static void main(String[] args) {
GetExcelInfo obj = new GetExcelInfo();
// 此處為我建立Excel路徑:E:/zhanhj/studysrc/jxl下
File file = new File("E:/zhanhj/studysrc/jxl/getExcleinfo.xls");
obj.readExcel(file);
}
// 去讀Excel的方法readExcel,該方法的入口參數為一個File對象
public void readExcel(File file) {
try {
// 建立輸入流,讀取Excel
InputStream is = new FileInputStream(file.getAbsolutePath());
// jxl提供的Workbook類
Workbook wb = Workbook.getWorkbook(is);
// Excel的頁簽數量
int sheet_size = wb.getNumberOfSheets();
for (int index = 0; index < sheet_size; index++) {
// 每個頁簽建立一個Sheet對象
Sheet sheet = wb.getSheet(index);
// sheet.getRows()傳回該頁的總行數
for (int i = 0; i < sheet.getRows(); i++) {
// sheet.getColumns()傳回該頁的總列數
for (int j = 0; j < sheet.getColumns(); j++) {
String cellinfo = sheet.getCell(j, i).getContents();
System.out.println(cellinfo);
}
}
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (BiffException e) {
} catch (IOException e) {
}
}
上面這個例子是一個很簡單讀取Excel并将各單元格的資料列印到控制台上,更多Excel操作方法,請參加jxl API。
下面我們再對上面的例子進行一個小小的擴充:
1、讀取一個目錄下的所有Excel檔案
2、讀取的每個Excel檔案的資料寫入到不同的txt中
import java.io.FileWriter;
import java.io.PrintWriter;
// 此處路徑指定到目錄而不是單個檔案
File file = new File("E:/zhanhj/studysrc/jxl");
if (file.isDirectory()) {
File[] files = file.listFiles();
for (File f : files)
// 如果還存在子目錄則繼續讀取子目錄下的Excel檔案
if (f.isDirectory()) {
File[] subfiles = f.listFiles();
for (File fi : subfiles) {
// 對檔案進行過濾,隻讀取Excel檔案,非Excel檔案不讀取,否則會出錯
if (fi.getName().indexOf(".xls") > 0) {
obj.readExcelWrite2TXT(fi);
}
} else {
// 對檔案進行過濾,隻讀取Excel檔案,非Excel檔案不讀取,否則會出錯
if (f.getName().indexOf(".xls") > 0) {
obj.readExcelWrite2TXT(f);
public void readExcelWrite2TXT(File file) {
// 建立檔案輸出流
FileWriter fw = null;
PrintWriter out = null;
// 指定生成txt的檔案路徑
String fileName = file.getName().replace(".xls", "");
fw = new FileWriter(file.getParent() + "/" + fileName + ".txt");
out = new PrintWriter(fw);
// 将從Excel中讀取的資料寫入到txt中
out.println(cellinfo);
} finally {
try {
// 記得關閉流
out.close();
fw.close();
// 由于此處用到了緩沖流,如果資料量過大,不進行flush操作,某些資料将依舊
// 存在于内從中而不會寫入檔案,此問題一定要注意
out.flush();
} catch (IOException e) {
e.printStackTrace();
下面我們來一起對Java讀取Excel流程做一個總結:
1、打開工作檔案Workbook,在此之前先用java的io流建立或者讀取檔案
2、打開工作表Sheet
3、讀行,然後讀列(行和列是從0開始的)
4、進行資料進行操作
接着上一節的内容,本節主要講述如何通過Java程式向Excel檔案中寫資料,包括:1、資料類型的控制;2、單元格及資料的格式化。
要快速上手,我們還是通過閱讀代碼來學習,這樣可以幫助大家建立一個更直覺的概念和認識。
1、寫入Excel及資料類型控制
程式描述:通過Java程式建立一個名為test.xls的檔案,并在Excel的第一行第一列寫一個字元串,在第一行第二列寫一個數字,在第一行第三列寫一個日期。
import java.util.Date;
import jxl.write.Label;
import jxl.write.WritableSheet;
import jxl.write.WritableWorkbook;
import jxl.write.Number;
import jxl.write.DateTime;
public class CreateExcel {
public static void main(String args[]) {
// 打開檔案
WritableWorkbook book = Workbook.createWorkbook(new File(
"test.xls"));
// 生成名為“sheet1”的工作表,參數0表示這是第一頁
WritableSheet sheet = book.createSheet("sheet1", 0);
// 在Label對象的構造子中指名單元格位置是第一列第一行(0,0),單元格内容為string
Label label = new Label(0, 0, "string");
// 将定義好的單元格添加到工作表中
sheet.addCell(label);
// 生成一個儲存數字的單元格,單元格位置是第二列,第一行,單元格的内容為1234.5
Number number = new Number(1, 0, 1234.5);
sheet.addCell(number);
// 生成一個儲存日期的單元格,單元格位置是第三列,第一行,單元格的内容為目前日期
DateTime dtime = new DateTime(2, 0, new Date());
sheet.addCell(dtime);
// 寫入資料并關閉檔案
book.write();
book.close();
} catch (Exception e) {
System.out.println(e);
幾個重要對象解析:
1、WritableWorkbook:用于建立打開Excel檔案
2、WritableSheet:用于建立Excel中的頁簽
3、Label:将單元格指定為文本型,并寫入字元串
4、Number:将單元格指定為數字型,并可寫入數字
5、DateTime:将單元格指定為日期型,并可寫入日期
掌握這幾個類及其方法後,我們便可以友善的向Excel進行寫入操作了,更多對象請參見jxl api。
2、寫入時單元格及資料的格式化
程式描述:在資料寫入到單元格後,對資料進行格式化,包括字型大小、顔色等
import jxl.CellType;
import jxl.format.Border;
import jxl.format.BorderLineStyle;
import jxl.format.Colour;
import jxl.format.VerticalAlignment;
import jxl.format.Alignment;
import jxl.write.DateFormat;
import jxl.write.NumberFormat;
import jxl.write.WritableCellFormat;
import jxl.write.WritableFont;
import jxl.write.WriteException;
WritableWorkbook book = Workbook
.createWorkbook(new File("test.xls"));
Label label = new Label(0, 0, "string",
getDataCellFormat(CellType.LABEL));
Number number = new Number(1, 0, 1234.5,
getDataCellFormat(CellType.NUMBER));
DateTime dtime = new DateTime(2, 0, new Date(),
getDataCellFormat(CellType.DATE));
public static WritableCellFormat getDataCellFormat(CellType type) {
WritableCellFormat wcf = null;
// 字型樣式
if (type == CellType.NUMBER || type == CellType.NUMBER_FORMULA) {// 數字
NumberFormat nf = new NumberFormat("#.00");
wcf = new WritableCellFormat(nf);
} else if (type == CellType.DATE) {// 日期
DateFormat df = new DateFormat("yyyy-MM-dd hh:mm:ss");
wcf = new WritableCellFormat(df);
} else {
WritableFont wf = new WritableFont(WritableFont.TIMES, 10,
WritableFont.NO_BOLD, false);
// 字型顔色
wf.setColour(Colour.RED);
wcf = new WritableCellFormat(wf);
// 對齊方式
wcf.setAlignment(Alignment.CENTRE);
wcf.setVerticalAlignment(VerticalAlignment.CENTRE);
// 設定上邊框
wcf.setBorder(Border.TOP, BorderLineStyle.THIN);
// 設定下邊框
wcf.setBorder(Border.BOTTOM, BorderLineStyle.THIN);
// 設定左邊框
wcf.setBorder(Border.LEFT, BorderLineStyle.THIN);
// 設定右邊框
wcf.setBorder(Border.RIGHT, BorderLineStyle.THIN);
// 設定背景色
wcf.setBackground(Colour.YELLOW);
// 自動換行
wcf.setWrap(true);
} catch (WriteException e) {
return wcf;
效果:

1、WritableCellFormat:用于格式化單元格
2、WritableFont:用于格式化字型
更多請參加jxl api。
到這裡本節的講解就結束了,下面我們可以總結出Excel的寫入流程:
1、用WritableWorkbook建立Excel檔案
2、用WritableSheet建立頁簽
3、用Label、Number、DateTime等建立單元格内容
4、在建立單元格内容時,我們可以給寫一個格式化方法,對單元格内容進行格式化
5、格式化主要包括2類:單元格格式化(WritableCellFormat)、值的格式化(WritableFont)
繼前兩節的Java讀取、寫入Excel後,本期将推出Java修改Excel中資料以及格式的方法和技巧,如果大家學習了前面的讀、寫Excel,相信學習本節内容将是不費吹灰之力啊,不過要靈活的運用還需多加努力呀。
好了,為了展示Java修改Excel的魅力,我們先來設計一個業務場景,這個場景是根據最近做過的一件事設計出來的:
在一張Excel中,有一批學生資訊資料如下圖:
圖1 Excel中的示例資料
在建立Excel時,将Excel中的所在省,所在市做成了下拉菜單以供選擇,設定如下:
圖2 所在省一覽 圖3 所在市一覽
從圖1我們會發現一個問題,王五的填寫所在省為:四川省,而所在市為:石家莊,大家都石家莊是河北的省會,是以王五的這種情況屬于Excel中的錯誤資料,那麼下面我們來做一件事:将Excel中所有出現省市關系弄錯了的,在Excel中進行标注出來!!
import java.io.*;
import java.util.HashMap;
import jxl.*;
public class UpdateExcel {
WritableWorkbook book = null;
HashMap<String, String> map = new HashMap<String, String>();
map = getPCKV();
// Excel獲得檔案
Workbook wb = Workbook.getWorkbook(new File("update_test.xls"));
// 打開一個檔案的副本,并且指定資料寫回到原檔案
book = Workbook.createWorkbook(new File("update_test.xls"), wb);
Sheet sheet = book.getSheet(0);
WritableSheet wsheet = book.getSheet(0);
int colunms = sheet.getColumns();
// 不讀表頭
for (int i = 1; i < sheet.getRows(); i++) {
StringBuffer pcin = new StringBuffer();
// 将省市組合起來與HashMap進行比對
String province = sheet.getCell(4, i).getContents().trim();
String city = sheet.getCell(5, i).getContents().trim();
pcin = pcin.append(province).append("-").append(city);
// 如果不比對,則在該行的最後加入标注資訊
if (!map.containsValue(pcin.toString())) {
Label label = new Label(colunms, i, "省市選擇出錯",
getDataCellFormat());
wsheet.addCell(label);
book.close();
// 設定标注的格式為黃底紅字
public static WritableCellFormat getDataCellFormat() {
WritableFont wf = new WritableFont(WritableFont.TIMES, 10,
WritableFont.BOLD, false);
// 字型顔色
wf.setColour(Colour.RED);
wcf = new WritableCellFormat(wf);
// 省市對應關系Map
public static HashMap<String, String> getPCKV() {
map.put("01", "河北省-石家莊");
map.put("02", "河北省-秦皇島");
map.put("03", "河北省-唐山");
map.put("04", "四川省-成都");
map.put("05", "四川省-綿陽");
map.put("06", "四川省-達州");
map.put("07", "廣西省-桂林");
map.put("08", "廣西省-南甯");
map.put("09", "廣西省-柳州");
return map;
代碼執行結果如圖所示:
圖4 執行結果
到這裡,Java修改Excel單元格的資料及格式便告一段落了,本節給出了一個較為簡單的場景進行了講述,目的在于引導大家學習Java修改Excel的常用流程和方法,若讀者能将Java操作Excel學得更深,往往可以發揮更大的作用。比如程式中利用HashMap來存儲對應關系,如果要将全國的省市納入進來,利用HashMap不是很好的做好,我們可以改成通過利用資料庫來達到同樣的效果,這裡的改進留給讀者。
讀到這裡,可能有部分讀者會産生疑問,這種操作,直接在Excel中,我們不是也可以操作嗎?為什麼通過Java來修改,是不是多此一舉了?其實不然,如果讀者将Java讀寫檔案結合起來,以及在将此程式稍微擴充一下,對每個Excel的所有頁簽進行周遊,那麼Java程式處理的資料裡和複雜度,遠遠不是單純的Excel能企及的。舉個簡單的場景(僅僅将上述場景進行擴充):
如果一個學院要統計該學院所有學生的資訊【格式和圖1一樣】,每個級發一個Excel,每個級不同專業的學生放在不同的頁簽中(sheet),如Excel樣式下圖所示:
圖5 09級學生資訊統計表
圖6 10級學生資訊統計表
最終,學院要根據收集上來的學生資訊導入到資料庫中,如果你是那個負責導入資料的人,你便通過Java讀寫Excel功能将所有的資料轉化成SQL語句,同時可以判斷出哪些同學資訊填寫錯誤,是不是這種應用變得更有意義了?