天天看點

Java讀取、寫入、處理Excel檔案中的資料

在日常工作中,我們常常會進行檔案讀寫操作,除去我們最常用的純文字檔案讀寫,更多時候我們需要對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;

效果:

Java讀取、寫入、處理Excel檔案中的資料

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中,有一批學生資訊資料如下圖:

Java讀取、寫入、處理Excel檔案中的資料

圖1   Excel中的示例資料

在建立Excel時,将Excel中的所在省,所在市做成了下拉菜單以供選擇,設定如下:

Java讀取、寫入、處理Excel檔案中的資料
Java讀取、寫入、處理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;

代碼執行結果如圖所示:

Java讀取、寫入、處理Excel檔案中的資料

圖4      執行結果

到這裡,Java修改Excel單元格的資料及格式便告一段落了,本節給出了一個較為簡單的場景進行了講述,目的在于引導大家學習Java修改Excel的常用流程和方法,若讀者能将Java操作Excel學得更深,往往可以發揮更大的作用。比如程式中利用HashMap來存儲對應關系,如果要将全國的省市納入進來,利用HashMap不是很好的做好,我們可以改成通過利用資料庫來達到同樣的效果,這裡的改進留給讀者。

讀到這裡,可能有部分讀者會産生疑問,這種操作,直接在Excel中,我們不是也可以操作嗎?為什麼通過Java來修改,是不是多此一舉了?其實不然,如果讀者将Java讀寫檔案結合起來,以及在将此程式稍微擴充一下,對每個Excel的所有頁簽進行周遊,那麼Java程式處理的資料裡和複雜度,遠遠不是單純的Excel能企及的。舉個簡單的場景(僅僅将上述場景進行擴充):

如果一個學院要統計該學院所有學生的資訊【格式和圖1一樣】,每個級發一個Excel,每個級不同專業的學生放在不同的頁簽中(sheet),如Excel樣式下圖所示:

Java讀取、寫入、處理Excel檔案中的資料

圖5      09級學生資訊統計表

Java讀取、寫入、處理Excel檔案中的資料

圖6      10級學生資訊統計表

最終,學院要根據收集上來的學生資訊導入到資料庫中,如果你是那個負責導入資料的人,你便通過Java讀寫Excel功能将所有的資料轉化成SQL語句,同時可以判斷出哪些同學資訊填寫錯誤,是不是這種應用變得更有意義了?