概述

Java Excel API是成熟的开源Java API,使开发人员可以动态读取,写入和修改Excel电子表格。

一些功能

  • 从Excel 95、97、2000,XP和2003工作簿中读取数据
  • 读取和写入公式(仅限Excel 97和更高版本)
  • 生成Excel 2000格式的电子表格
  • 支持字体,数字和日期格式
  • 支持单元格的阴影,边框和着色
  • 修改现有工作表
  • 支持复制图表
  • 支持将图像插入和复制到电子表格中
    应该说以上功能已经能够大致满足我们的需要。最关键的是这套API是纯Java的,并不依赖Windows系统,即使运行在Linux下,它同样能够正确的处理Excel文件。另外需要说明的是,这套API对图形和图表的支持很有限,而且仅仅识别PNG格式。

jxl开发指南

官网: http://jexcelapi.sourceforge.net/

API帮助文档: http://jexcelapi.sourceforge.net/resources/javadocs/2_6_10/docs/index.html

介绍

jxl操作excel包括对象Workbook,Sheet ,Cell
一个excel就对应一个Workbook对象
一个Workbook可以有多个Sheet对象
一个Sheet对象可以有多个Cell对象

Maven依赖
<dependency>
      <groupId>net.sourceforge.jexcelapi</groupId>
      <artifactId>jxl</artifactId>
      <version>2.6.12</version>
</dependency>
读取Excel操作

通过Workbook,Sheet ,Cell这三个对象我们就可以实现Excel文件的读取工作。我们先想想一下读取步骤,不 管是什么样的Excel操作框架必定都要经历
1、 选取Excel文件得到工作薄
2、 选择工作表
3、 选择Cell
4、 读取信息

读取工作薄

选取Excel文件得到工作薄Workbook

Workbook workbook = Workbook.getWorkbook(new File("myexcel.xls"));
读取工作表

通过Workbook的getSheet方法选择第一个工作表(从0开始)

Sheet sheet = workbook.getSheet(0);
读取单元格

通过Sheet的getCell方法选择位置为C1的单元格(两个参数都从0开始)

Cell c2 = sheet.getCell(1,0);  //注意: 参数1为列索引,参数2为行索引   索引从零开始
读取单元格的值

通过Cell的getContents方法,把单元格中的信息以字符的形式读取出来

String stringc1 = c2.getContents();

Cell提供了一个getType方法

能够返回单元格的类型信息,同时JXL提供了一个CellType类用来预设Excel中的类型信息,而且JXL提供了一些 Cell类的子类用来分别用来表示各种类型的单元格,如LabelCell,NumberCell,DateCell分别表示字符、数 值、日期类型的单元格

if(cell.getType()== CellType.LABEL){
            LabelCell labelCell = (LabelCell) cell;
            String labelCellString = labelCell.getString();
        }
        if (cell.getType()==CellType.BOOLEAN){
            BooleanCell booleanCell = (BooleanCell) cell;
            boolean value = booleanCell.getValue();
        }
        if(cell.getType()== CellType.NUMBER){
            NumberCell numberCell = (NumberCell) cell;
            double value = numberCell.getValue();
        }
        if(cell.getType()== CellType.DATE){
            DateCell dateCell = (DateCell) cell;
            Date date = dateCell.getDate();
  }
释放资源

当你完成对Excel电子表格数据的处理后,一定要使用close()方法来关闭先前创建的对象,以释放读取数据表的过程中所占用的内存空间,在读取大量数据时显得尤为重要.

workbook.close();
示例代码
@Test
    public void readExcel() throws IOException, BiffException {

        File file = new File("src/myexcel.xls");

        Workbook workbook = Workbook.getWorkbook(file);

        Sheet sheet = workbook.getSheet(0);
        //获得总列数
        int columns = sheet.getColumns();
        //获得总行数
        int rows = sheet.getRows();
        
        System.out.println(rows + " 行  " + columns + "列");

        for (int row = 0; row < rows; row++) {
            for (int column = 0; column < columns; column++) {
                Cell cell = sheet.getCell(column, row); 
                String contents = cell.getContents();   //获取单元格的值
                System.out.print(contents+"    ");
            }
            System.out.println();
        }

        //释放资源
        workbook.close();
    }
写Excel操作

通过WritableWorkbook,WritableSheet,Label这三个对象我们就可以实现Excel文件的插入工作。我们先想 想一下插入,不管是什么样的Excel操作框架必定都要经历
1、 创建Exce工作薄
2、 创建工作表
3、 创建单元格

创建工作薄

API提供了两种方式来处理可写入的输出流,一种是直接生成本地文件,如果文件名不带全路径的话,缺省的文件会定位在当前目录,如果文件名带有全路径的话,则生成的Excel文件则会定位在相应的目录;另外一种是将Excel对象直接写入到输出流,例如:用户通过浏览器来访问web服务器,如果HTTP头设置正确的话,浏览器自动调用客户端的Excel应用程序,来显示动态生成的Excel电子表格。

创建可写入的Excel工作薄
WritableWorkbook workbook = Workbook.createWorkbook(new File(targetfile));

或者

将WritableWorkbook直接写入到输出流
OutputStream os = new FileOutputStream(targetfile);
WritableWorkbook workbook = Workbook.createWorkbook(os);
创建工作表
WritableSheet ws = workbook.createSheet("mysheet", 0);
创建单元格
添加文本类单元格对象
Label label = new Label(0, 0, "This is a Label cell");
ws.addCell(label);
添加带有字型Formatting的对象
//(WritableFont.FontName fn, int ps, WritableFont.BoldStyle bs, boolean italic)
//参数1:字体名  参数2:字体大小  参数3:加粗或不加粗  参数4: 是否斜体
WritableFont wf = new WritableFont(WritableFont.TIMES, 18, WritableFont.BOLD, true);
WritableCellFormat wcfF = new WritableCellFormat(wf);
Label labelCF = new Label(1, 0, "This is a Label Cell", wcfF);
ws.addCell(labelCF);
添加带有字体颜色Formatting的对象
WritableFont wfc = new WritableFont(WritableFont.ARIAL,10,WritableFont.NO_BOLD, false,
UnderlineStyle.NO_UNDERLINE, jxl.format.Colour.RED);
WritableCellFormat wcfFC = new WritableCellFormat(wfc);
Label labelCF = new Label(1, 0, "This is a Label Cell", wcfFC);
ws.addCell(labelCF);
添加Number对象
Number labelN = new jxl.write.Number(0, 1, 3.1415926);
ws.addCell(labelN);
添加带有formatting的Number对象
NumberFormat nf = new NumberFormat("#.##");
WritableCellFormat wcfN = new WritableCellFormat(nf);
Number labelNF = new Number(1, 1, 3.1415926, wcfN);
ws.addCell(labelNF);
添加Boolean对象
Boolean labelB = new jxl.write.Boolean(0, 2, false);
ws.addCell(labelB);
添加DateTime对象
DateTime labelDT = new DateTime(0, 3, new Date());
ws.addCell(labelDT);
添加带有formatting的DateFormat对象
DateFormat df = new DateFormat("yyyy-MM-dd hh:mm:ss");
WritableCellFormat wcfDF = new WritableCellFormat(df);
DateTime labelDTF = new DateTime(1, 3, new Date(), wcfDF);
ws.addCell(labelDTF);
添加公式单元格
Formula formula = new Formula(3,1,"SUM(A2:B2)");
ws.addCell(formula);
添加图像
WritableImage image=new WritableImage(1,5,10,10,new File("k8s.png"));
ws.addImage(image);

注意,API中注明只支持png文件。

合并单元格

通过writablesheet.mergeCells(int x,int y,int m,int n);来实现的。
表示将从第x+1列,y+1行到m+1列,n+1行合并 (四个点定义了两个坐标,左上角和右下角)结果是合并了m-x+1行,n-y+1列,两者乘积就是合并的单元格数量。

ws.mergeCells(5, 0, 8, 3);
label = new Label(5, 0, "合并了16个单元格");
ws.addCell(label);
添加单元格样式

主要是改变单元格背景、字体、颜色等等。

WritableCellFormat wcf = new WritableCellFormat();
wcf.setAlignment(Alignment.CENTRE); // 设置居中
wcf.setBorder(Border.ALL, BorderLineStyle.THIN); // 设置边框线
wcf.setBackground(jxl.format.Colour.RED); // 设置单元格的背景颜色
label = new Label(1, 5, "字体", wcf);
ws.addCell(label);
设置单元格字体
WritableFont writableFont = new WritableFont(WritableFont.createFont("楷书"), 20);
WritableCellFormat font = new WritableCellFormat(writableFont);
label = new Label(3, 2, "楷书", font);
ws.addCell(label);
写入到文件
workbook.write();
释放资源
workbook.close();
示例代码
@Test
    public void writeExcel() throws IOException, WriteException {

        WritableWorkbook workbook = Workbook.createWorkbook(new File("writeExcel.xls"));

        WritableSheet ws = workbook.createSheet("mysheet", 0);

        Label label = new Label(0, 0, "This is a Label cell");
        ws.addCell(label);

        WritableFont wf = new WritableFont(WritableFont.TIMES, 12, WritableFont.BOLD,             false);
        WritableCellFormat wcfF = new WritableCellFormat(wf);
        label = new Label(1, 0, "This is a Label Cell", wcfF);
        ws.addCell(label);

        WritableFont wfc = new WritableFont(WritableFont.ARIAL, 10, WritableFont.NO_BOLD,         false,UnderlineStyle.DOUBLE, Colour.RED);
        WritableCellFormat wcfFC = new WritableCellFormat(wfc);
        Label labelCF = new Label(1, 0, "This is a Label Cell", wcfFC);
        ws.addCell(labelCF);

        Number labelN = new Number(0, 1, 3.1415926);
        ws.addCell(labelN);

        NumberFormat nf = new NumberFormat("#.##");
        WritableCellFormat wcfN = new WritableCellFormat(nf);
        Number labelNF = new Number(1, 1, 3.1415926, wcfN);
        ws.addCell(labelNF);

        Boolean labelB = new jxl.write.Boolean(0, 2, false);
        ws.addCell(labelB);

        DateTime labelDT = new DateTime(0, 3, new Date());
        ws.addCell(labelDT);

        DateFormat df = new DateFormat("yyyy-MM-dd hh:mm:ss");
        WritableCellFormat wcfDF = new WritableCellFormat(df);
        DateTime labelDTF = new DateTime(1, 3, new Date(), wcfDF);
        ws.addCell(labelDTF);

        Formula formula = new Formula(3, 1, "SUM(A2:B2)");
        ws.addCell(formula);

        WritableImage image = new WritableImage(1, 5, 10, 10, new File("k8s.png"));
        ws.addImage(image);

        ws.mergeCells(5, 0, 8, 3);
        label = new Label(5, 0, "合并了16个单元格");
        ws.addCell(label);

        WritableCellFormat wcf = new WritableCellFormat();
        wcf.setAlignment(Alignment.CENTRE); // 设置居中
        wcf.setBorder(Border.ALL, BorderLineStyle.THIN); // 设置边框线
        wcf.setBackground(jxl.format.Colour.RED); // 设置单元格的背景颜色
        label = new Label(1, 5, "字体", wcf);
        ws.addCell(label);

        WritableFont writableFont = new WritableFont(WritableFont.createFont("楷书"), 20);
        WritableCellFormat font = new WritableCellFormat(writableFont);
        label = new Label(3, 2, "楷书", font);
        ws.addCell(label);

        //写入到文件
        workbook.write();
        //释放资源
        workbook.close();
    }
拷贝、更新Excel工作薄
@Test
    public void updateExcel() throws IOException, BiffException, WriteException {
        //创建只读的Excel工作薄的对象
        Workbook rw = Workbook.getWorkbook(new File("myexcel.xls"));
        //创建可写入的Excel工作薄对象
        WritableWorkbook wwb = Workbook.createWorkbook(new File("updateExcel.xls"), rw);
        //读取第一张工作表
        WritableSheet ws = wwb.getSheet(0);
        //获得第一个单元格对象
        WritableCell wc = ws.getWritableCell(0, 1);
        //判断单元格的类型, 做出相应的转化
        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();
    }