显示标签为“JAVA POI Excel操作 apache HSSF HSSFWorkBook 示例程序 Excel文件 Sheet Row Column”的博文。显示所有博文
显示标签为“JAVA POI Excel操作 apache HSSF HSSFWorkBook 示例程序 Excel文件 Sheet Row Column”的博文。显示所有博文

2009年9月20日星期日

Sheet里行的读取


要取得Sheet里的某一行,可以使用「HSSFSheet」类的「getRow」方法。
getRow
public HSSFRow getRow(int rownum)
Returns the logical row (not physical) 0-based. If you ask for a row 
that is not defined you get a null. This is to say row 4 represents 
the fifth row on a sheet. 
 
Parameters:
  rownum - row to get 
Returns:
  HSSFRow representing the rownumber or null if its not defined on the 
    sheet
利用行号取得指定的行。如果行不存在,则返回NULL。

示例程序

动手做做看。
import java.io.*;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFRow;
 
public class POISample{
  public static void main(String[] args){
    HSSFWorkbook workbook = new HSSFWorkbook();
 
    HSSFSheet sheet = workbook.createSheet();
 
    HSSFRow row = sheet.createRow(1);
 
    for (int i = 0 ; i < 3 ; i++){
      HSSFRow r = sheet.getRow(i);
      if (r  == null){
        System.out.println("第" + i + "行不存在。");
      }else{
        System.out.println("第" + i + "行取得成功。");
      }
    }
  }
}
上面的程序里,先创建一个Sheet,然后创建第二行(行号为1)。最后读取第一行到第三行的三行。结果如下。

第0行不存在。
第1行取得成功。
第2行不存在。
这和予想的一样。

读取有值的行

按照下图准备一个Excel文件。



import java.io.*;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFRow;
 
public class POISample{
  public static void main(String[] args){
    FileInputStream in = null;
    HSSFWorkbook workbook = null;
 
    try{
      in = new FileInputStream("sample.xls");
      POIFSFileSystem fs = new POIFSFileSystem(in);
      workbook = new HSSFWorkbook(fs);
    }catch(IOException e){
      System.out.println(e.toString());
    }finally{
      try{
        in.close();
      }catch (IOException e){
        System.out.println(e.toString());
      }
    }
 
    HSSFSheet sheet = workbook.getSheetAt(0);
 
    for (int i = 0 ; i < 3 ; i++){
      HSSFRow r = sheet.getRow(i);
      if (r  == null){
        System.out.println("第" + i + "行不存在。");
      }else{
        System.out.println("第" + i + "行取得成功。");
      }
    }
  }
}
结果如下。
第0行取得成功。
第1行取得成功。
第2行不存在。
从上面的例子可以看出,如果当前行有值的话,那么读取这一行时肯定存在。

从取得的行里获取单元格的值。

这一次从已经取得的行里获取单元格的值。仍然使用刚才的Excel文件。用getRow方法先取得行对象,再从单元格里获取值。
import java.io.*;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFCell;
 
public class POISample{
  public static void main(String[] args){
    FileInputStream in = null;
    HSSFWorkbook workbook = null;
 
    try{
      in = new FileInputStream("sample.xls");
      POIFSFileSystem fs = new POIFSFileSystem(in);
      workbook = new HSSFWorkbook(fs);
    }catch(IOException e){
      System.out.println(e.toString());
    }finally{
      try{
        in.close();
      }catch (IOException e){
        System.out.println(e.toString());
      }
    }
 
    HSSFSheet sheet = workbook.getSheetAt(0);
 
    HSSFRow row = sheet.getRow(1);
 
    HSSFCell cell = row.getCell((short)1);
    System.out.println(cell.getStringCellValue());
  }
}
结果如下。
sample
可以看出,把第二行第二列的值取出来了。

在现有的行上创建行

最后,再来试试看,在现有的行上,用「createRow」方法创建一行看看会是什么结果。还是使用刚才的Excel文件,在第二行上创建一行,再把值取出来。
import java.io.*;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFCell;
 
public class POISample{
  public static void main(String[] args){
    FileInputStream in = null;
    HSSFWorkbook workbook = null;
 
    try{
      in = new FileInputStream("sample.xls");
      POIFSFileSystem fs = new POIFSFileSystem(in);
      workbook = new HSSFWorkbook(fs);
    }catch(IOException e){
      System.out.println(e.toString());
    }finally{
      try{
        in.close();
      }catch (IOException e){
        System.out.println(e.toString());
      }
    }
 
    HSSFSheet sheet = workbook.getSheetAt(0);
 
    HSSFRow row = sheet.createRow(1);
 
    HSSFCell cell = row.getCell((short)1);
 
    System.out.println(cell.getStringCellValue());
  }
}
结果如下。
Exception in thread "main" java.lang.NullPointerException
        at POISample.main(POISample.java:35)
发生了空指针异常。本来对于已经存在的行用「createRow」方法进行创建行操作,可能你会以为会复制原来的行,但事实并非如此。
让我们在原来程序的基础上再稍作一些变化,已经存在的行用「createRow」方法进行创建行操作后,再在该行的空白单元格设上值,保存为新的文件。
import java.io.*;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFCell;
 
public class POISample{
  public static void main(String[] args){
    FileInputStream in = null;
    HSSFWorkbook workbook = null;
 
    try{
      in = new FileInputStream("sample.xls");
      POIFSFileSystem fs = new POIFSFileSystem(in);
      workbook = new HSSFWorkbook(fs);
    }catch(IOException e){
      System.out.println(e.toString());
    }finally{
      try{
        in.close();
      }catch (IOException e){
        System.out.println(e.toString());
      }
    }
 
    HSSFSheet sheet = workbook.getSheetAt(0);
 
    HSSFRow row = sheet.createRow(1);
 
    HSSFCell cell = row.createCell((short)3);
    cell.setCellValue("news");
 
    FileOutputStream out = null;
    try{
      out = new FileOutputStream("sample2.xls");
      workbook.write(out);
    }catch(IOException e){
      System.out.println(e.toString());
    }finally{
      try {
        out.close();
      }catch(IOException e){
        System.out.println(e.toString());
      }
    }
  }
}
执行上面程序后,打开新的Excel文件如下。























对于已经存在的行再用「createRow」方法执行的话,那从原来行里有值的单元格取值时会发生空指针异常。但如果新创建一个单元格再设值的话,那之前单元格的值也会被保留下来。虽然是猜测,不过大家可以自己亲自动手来验证一下。

Sheet里行的创建

之前仅仅新建了Sheet,虽然可以看到新建的Sheet里有无数的单元格,但还不能直接往这些单元格设值。要想往这些单元格里设值,你还必须创建行。
因此,再来看看行创建的方法。
在Sheet里创建行,使用「HSSFSheet」类的「createRow」方法。
createRow
public HSSFRow createRow(int rownum)
Create a new row within the sheet and return the high level representation 
 
Parameters:
  rownum - row number 
Returns:
  High level HSSFRow object representing a row in the sheet
创建指定行号的行。行号是从0开始的整数,最大是65535。创建行所返回的值是「HSSFRow」类对象,关于「HSSFRow」类定义的说明,以后再详细说。
创建方法很多,要说详细挺复杂。比方说,即使第一行(行号为0)和第二行不创建,也能直接创建第三行。

示例程序

亲自动手做一下吧。
import java.io.*;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFCell;
 
public class POISample{
  public static void main(String[] args){
    HSSFWorkbook workbook = new HSSFWorkbook();
 
    HSSFSheet sheet = workbook.createSheet();
 
    HSSFRow row = sheet.createRow(2);
 
    /* 下記はセルを作成し、セルに値を代入しています */
    HSSFCell cell = row.createCell((short)0);
    cell.setCellValue("test");
 
    FileOutputStream out = null;
    try{
      out = new FileOutputStream("sample.xls");
      workbook.write(out);
    }catch(IOException e){
      System.out.println(e.toString());
    }finally{
      try {
        out.close();
      }catch(IOException e){
        System.out.println(e.toString());
      }
    }
  }
}
在上面的程序里,生成一个Sheet,然后单独创建了第三行(行号为2),接着又创建了一个单元格,最后给这个单元格设了值。执行后,打开「sample.xls」文件看看。






















可以看到,在第三行第一列,值已经被设定好了。

HSSFSheet类定义

用POI来作成一个Sheet,可以用「HSSFSheet」类,它的类定义如下。
  • java.lang.Object
  • org.apache.poi.hssf.usermodel.HSSFSheet
  • public class HSSFSheet extends java.lang.Object
它有两个构造方法。
构建器
protected HSSFSheet(Workbook book)
Creates new HSSFSheet - called by HSSFWorkbook to create a sheet from scratch.
protected HSSFSheet(Workbook book, Sheet sheet)
Creates an HSSFSheet representing the given Sheet object.
虽然有两个构建器,但都是protected的,所以要新建Sheet,只能通过Workbook。

新建Sheet

在Workbook里新建Sheet时,还是使用「HSSFWorkbook」类的「createSheet」的方法,详细可以参照「在Workbook里创建Sheet」。
使用方法如下。
HSSFWorkbook workbook = new HSSFWorkbook();
HSSFSheet sheet = workbook.createSheet();

读取现有的Sheet

对于在Workbook已经存在的Sheet来说,可以用「HSSFWorkbook」类的「getSheet」方法来读取。
getSheet
public HSSFSheet getSheet(java.lang.String name)
Get sheet with the given name 
 
Parameters:
  name - of the sheet 
Returns:
  HSSFSheet with the name provided or null if it does not exist

参数为Sheet名称。
使用方法如下。
HSSFWorkbook workbook = new HSSFWorkbook();
HSSFSheet sheet = workbook.getSheet("sheet1")
不用Sheet名而用Sheet的序列号来取得Sheet的话,可以用「HSSFWorkbook」类的「getSheetAt」方法。
getSheetAt
public HSSFSheet getSheetAt(int index)
Get the HSSFSheet object at the given index. 
 
Parameters:
  index - of the sheet number (0-based physical & logical) 
Returns:
  HSSFSheet at the provided index
使用方法如下。
HSSFWorkbook workbook = new HSSFWorkbook();
HSSFSheet sheet = workbook.getSheetAt(1);