LinkinPark
当你的才华撑不起你野心时,那么请潜下心继续学习,心无旁骛,愿多年以后你们我都能成为自己想象的模样。

  • 用POI创建单元格,使用「HSSFCell」类
该类包含三个构造方法。 
protected HSSFCell(Workbook book, Sheet sheet, int row, CellValueRecordInterface cval)
protected HSSFCell(Workbook book, Sheet sheet, int row, short col)
protected HSSFCell(Workbook book, Sheet sheet, int row, short col, int type)
同之前一样,虽然有三个构造方法,但都是protected类型的,所以直接用构造方法创建单元格行不通,只能通过行来创建单元格。 


  • 创建单元格
在一个工作表里创建一个单元格,必须用「HSSFRow」类的「createCell」方法。 
使用方法如下: 
HSSFWorkbook workbook = new HSSFWorkbook();
HSSFSheet sheet = workbook.createSheet();
HSSFRow row = sheet.createRow(0);
HSSFCell cell = row.createCell((short)2);

  • 读取现有单元格
要读取某一行现有的单元格,使用「HSSFRow」类的「getCell」方法』。
使用方法如下: 
HSSFWorkbook workbook = new HSSFWorkbook();
HSSFSheet sheet = workbook.createSheet();
HSSFRow row = sheet.getRow(0);
HSSFCell cell = row.getCell((short)2);

  • 行里创建单元格
下面来看看如何在取得现有行或者在新创建的行里,再创建一个单元格。用POI来创建的话,使用「HSSFRow」类的「createCell」方法。 
public HSSFCell createCell(short column):
(short column)创建指定列号的单元格。列号和行号一样,也是从0开始数的。创建的单元格以「HSSFCell」类的对象返回,关于「HSSFCell」类的介绍,我们放在下面几章进行。 
package linkin;


import java.io.FileOutputStream;
import java.io.IOException;


import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;


public class Linkin
{
	public static void main(String[] args)
	{
		HSSFWorkbook workbook = new HSSFWorkbook();


		HSSFSheet sheet = workbook.createSheet();
		HSSFRow row = sheet.createRow(1);//创建序号为1的行,第2行


		HSSFCell cell = row.createCell(2);//创建序号为2的单元格,第二行第3格
		cell.setCellValue("test");//写入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());
			}
		}
	}


}

  • 读取单元格
如果要从现有的行里取得某一个单元格,POI提供了「HSSFRow」类的「getCell」方法。 
public HSSFCell getCell(short cellnum):
(short cellnum)取得指定列号的单元格。如果是不存在的单元格,会返回「null」。 
package linkin;


import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;


public class Linkin
{
	public static void main(String[] args)
	{
		HSSFWorkbook workbook = new HSSFWorkbook();


		HSSFSheet sheet = workbook.createSheet();
		HSSFRow row = sheet.createRow(1);//创建第二行


		HSSFCell cell = row.createCell((short) 2);//创建第二行第三格
		cell.setCellValue("test");//第二行第三格写入test


		for (int i = 0; i < 3; i++)
		{
			HSSFCell c = row.getCell((short) i);
			if (c == null)
			{
				System.out.println("第" + i + "列单元格不存在");
			}
			else
			{
				System.out.println("第" + i + "列单元格获取成功");
			}
		}
	}


}

  • 读取有值的Excel表格
package linkin;


import java.io.FileInputStream;
import java.io.IOException;


import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;


public class Linkin
{
	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);//取得第一张sheet
		HSSFRow row = sheet.getRow(1);//第2行


		for (int i = 0; i < 3; i++)
		{
			HSSFCell c = row.getCell((short) i);
			if (c == null)
			{
				System.out.println("第" + i + "列单元格不存在");
			}
			else
			{
				System.out.println("第" + i + "列单元格取得成功");
				System.out.println("单元格的值:" + c.getStringCellValue());//getStringCellValue()取得单元格的值
			}
		}
	}


}


  • POI向单元格写入值
前面介绍了如何用POI获取单元格的值,这一节介绍如何用POI向单元格里设定值。和之前获取值一样,对于不同类型的值,写入的方法也是不同的。 
                  方法
boolean setCellValue(boolean value)
date setCellValue(java.util.Calendar value)
date setCellValue(java.util.Date value)
numeric setCellValue(double value)
string setCellValue(java.lang.String value)
方法名称相同,但参数类型不同,这样的方法有5个。关于日期型的方法,有Calender型和Date型两种。 
当然,POI也可以写入Error值和计算式。 
方法
error value setCellErrorValue(byte value)
Formula setCellFormula(java.lang.String formula)
先统一看一下各种方法的Doc文档说明吧。 
setCellValue(boolean value)
写入boolean型使用「setCellValue(boolean value)」方法。 
1,public void setCellValue(boolean value)如果对象单元格不是boolean型的话,则自动转换为boolean型写入。 

2,public void setCellValue(java.util.Calendar value)写入Calendar型使用「setCellValue(java.util.Calendar value)」方法。 Calendar型的值是作为数值型写入的,如何想表示为日期型的话,需要做格式转换处理。如果对象单元格不是数值型的话,则自动转换为数值型写入。 

3,public void setCellValue(java.util.Date value)写入Date型使用「setCellValue(java.util.Date value)」方法。 Date型的值是作为数值型写入的,如何想表示为日期型的话,需要做格式转换处理。如果对象单元格不是数值型的话,则自动转换为数值型写入。 

4,public void setCellValue(double value)写入数值型使用「setCellValue(double value)」方法。 如果对象单元格不是数值型的话,则自动转换为数值型写入。 

5,public void setCellValue(java.lang.String value)写入字符串型使用「setCellValue(java.lang.String value)」方法。 注意:要写入中文等文字的话,必须要先使用「setEncoding」方法进行转换。如果对象单元格不是字符串型的话,则自动转换为字符串型写入。还有,如果写入的值是”null”的话,则单元格为空白。 

6,setCellErrorValuepublic void setCellErrorValue(byte value)写入Error型使用「setCellErrorValue(byte value)」方法。 如果对象单元格不是Error型的话,则自动转换为Error型写入。 

7,public void setCellFormula(java.lang.String formula)写入计算式使用「setCellFormula」方法。 写入计算式方法的参数虽然是字符串,但Doc文档里一点说明也没有。 

package linkin;


import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Calendar;
import java.util.Date;


import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFErrorConstants;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;


public class Linkin
{
	public static void main(String[] args)
	{
		HSSFWorkbook workbook = new HSSFWorkbook();


		HSSFSheet sheet = workbook.createSheet();
		HSSFRow row = sheet.createRow(1);//创建第二行


		HSSFCell cell1 = row.createCell((short) 0);//2,1格
		cell1.setCellValue(true);//写入true


		HSSFCell cell2 = row.createCell((short) 1);//2,2格
		Calendar cal = Calendar.getInstance();//Calendar???
		cell2.setCellValue(cal);//写入Calendar型对象cal


		HSSFCell cell3 = row.createCell((short) 2);//2,3格
		Date date = new Date(); //日期型
		cell3.setCellValue(date);//写入日期型


		HSSFCell cell4 = row.createCell((short) 3);//2,4格
		cell4.setCellValue(150);//写入150


		HSSFCell cell5 = row.createCell((short) 4);//2.5格
		cell5.setCellValue("hello");//写入hello


		HSSFRow row2 = sheet.createRow(2);//第三行


		HSSFCell cell6 = row2.createCell((short) 0);//3,1格


		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());
			}
		}
	}


}


  • POI获取单元格类值类型
在获取单元格值的时候,不同类型,使用的方法也不一样,所以获取之前,必须要知道类型。这一节就来介绍如何知道单元格里的值是何类型。 
要获取单元格值的类型,使用「HSSFCell」类的「getCellType」方法。 注意:数值型和日期型都是「CELL_TYPE_NUMERIC 
下面就是类型和定义值的一览表。 
Cell type 定义值 值(int)
Blank CELL_TYPE_BLANK 3
Boolean CELL_TYPE_BOOLEAN 4
Error CELL_TYPE_ERROR 5
Formula CELL_TYPE_FORMULA 2
Numeric CELL_TYPE_NUMERIC 0

String CELL_TYPE_STRING 1


package linkin;


import java.io.FileInputStream;
import java.io.IOException;


import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;


public class Linkin
{
	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) 0);
		System.out.println("A:2=" + getType(cell.getCellType()));


		cell = row.getCell((short) 1);
		System.out.println("B:2=" + getType(cell.getCellType()));


		cell = row.getCell((short) 2);
		System.out.println("C:2=" + getType(cell.getCellType()));


		cell = row.getCell((short) 3);
		System.out.println("D:2=" + getType(cell.getCellType()));


		cell = row.getCell((short) 4);
		System.out.println("E:2=" + getType(cell.getCellType()));
	}


	public static String getType(int type)
	{
		if (type == HSSFCell.CELL_TYPE_BLANK)
		{
			return "CELL_TYPE_BLANK";
		}
		else if (type == HSSFCell.CELL_TYPE_BOOLEAN)
		{
			return "CELL_TYPE_BOOLEAN";
		}
		else if (type == HSSFCell.CELL_TYPE_ERROR)
		{
			return "CELL_TYPE_ERROR";
		}
		else if (type == HSSFCell.CELL_TYPE_FORMULA)
		{
			return "CELL_TYPE_FORMULA";
		}
		else if (type == HSSFCell.CELL_TYPE_NUMERIC)
		{
			return "CELL_TYPE_NUMERIC";
		}
		else if (type == HSSFCell.CELL_TYPE_STRING)
		{
			return "CELL_TYPE_STRING";
		}
		else
		{
			return "Not defined";
		}
	}


}



  • 日期型检查
到底是数值型还是日期型,可以通过「org.apache.poi.hssf.usermodel.HSSFDateUtil」类的「isCellDateFormatted」方法来检证。 
public static boolean isCellDateFormatted(HSSFCell cell)

因为这个方法是静态的,可以直接调用如下所示。 

if (HSSFDateUtil.isCellDateFormatted(cell)){
    /* 日期型 */
}

package linkin;


import java.io.FileInputStream;
import java.io.IOException;


import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFDateUtil;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;


public class Linkin
{
	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) 0);
		System.out.println("A:2=" + getType(cell));


		cell = row.getCell((short) 1);
		System.out.println("B:2=" + getType(cell));


		cell = row.getCell((short) 2);
		System.out.println("C:2=" + getType(cell));


		cell = row.getCell((short) 3);
		System.out.println("D:2=" + getType(cell));


		cell = row.getCell((short) 4);
		System.out.println("E:2=" + getType(cell));
	}


	public static String getType(HSSFCell cell)
	{
		int type = cell.getCellType();


		if (type == HSSFCell.CELL_TYPE_BLANK)
		{
			return "CELL_TYPE_BLANK";
		}
		else if (type == HSSFCell.CELL_TYPE_BOOLEAN)
		{
			return "CELL_TYPE_BOOLEAN";
		}
		else if (type == HSSFCell.CELL_TYPE_ERROR)
		{
			return "CELL_TYPE_ERROR";
		}
		else if (type == HSSFCell.CELL_TYPE_FORMULA)
		{
			return "CELL_TYPE_FORMULA";
		}
		else if (type == HSSFCell.CELL_TYPE_NUMERIC)
		{
			//检查日期类型
			if (HSSFDateUtil.isCellDateFormatted(cell))
			{
				return "CELL_TYPE_DATE";
			}
			else
			{
				return "CELL_TYPE_NUMERIC";
			}
		}
		else if (type == HSSFCell.CELL_TYPE_STRING)
		{
			return "CELL_TYPE_STRING";
		}
		else
		{
			return "Not defined";
		}
	}
}

  • POI获取单元格类的值
这一节介绍如何获取单元格的值。在POI里,对于不同类型的单元格的值,所调用的方法是不一样的。 
函数名
boolean型 getBooleanCellValue()
java.util.Date型 getDateCellValue()
byte型 getErrorCellValue()
double型 getNumericCellValue()
java.lang.String型 getStringCellValue()
java.lang.String型 getCellFormula()
如果单元格里是String型的值,调用方法「getStringCellValue」,数值型的话,则调用「getNumericCellValue」。再一起来看看其它方法。 

1,public boolean getBooleanCellValue()获取boolean型的値,调用「getBooleanCellValue」方法。如果调用这个方法来获取字符串,数值型的值的话,会发生Exception异常,如果对象单元格里不含值,则返回「false」。 

2,public java.util.Date getDateCellValue()获取日期Date型时,调用「getDateCellValue」方法。 如果用这个方法来获取字符串时,会有Exception异常发生,如果对象单元格里不含值,则返回「null」。 

3,public byte getErrorCellValue()单元格如果是Error值,比如#VALUE!等,这时可以使用「getErrorCellValue」方法。 字符串,数值型,布尔型的值用这个方法的话,会产生异常,而单元格里值为空时则返回「0」。 
对于单元格的Error值类型,在POI里的「org.apache.poi.hssf.usermodel.HSSFErrorConstants」有定义列表如下: 
常量名 错误代码 Excel里的Error值
public static final byte ERROR_DIV0 7 #DIV/0!
public static final byte ERROR_NA 42 #N/A
public static final byte ERROR_NAME 29 #NAME?
public static final byte ERROR_NULL 0 #NULL!
public static final byte ERROR_NUM 36 #NUM!
public static final byte ERROR_REF 23 #REF!
public static final byte ERROR_VALUE 15 #VALUE!
所以这里要注意了,Excel的ERROR.TYPE函数所返回的值,和POI所定义的是不一样的。 
4,public double getNumericCellValue()读取数值型时,调用「getNumericCellValue」方法。 用这个方法来读取字符串类型时,会有Exception发生,如果单元格里值为空时则返回「0」。 

5,public java.lang.String getStringCellValue()字符串类型取得时,使用「getStringCellValue」方法。 同样的,用这个方法来读取数值型时,也会有异常Exception发生。单元格值为空时,则返回空白。 

6,public java.lang.String getCellFormula()读取单元格里的计算式时,使用「getCellFormula」方法。单元格里如果是计算式的话,则把计算式作为字符串来获取。关于具体内容,在最新文档里,竟然没有,不知道为什么。 

package linkin;


import java.io.FileInputStream;
import java.io.IOException;


import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;


public class Linkin
{
	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) 0);
		System.out.println(cell.getNumericCellValue());


		cell = row.getCell((short) 1);
		System.out.println(cell.getStringCellValue());


		cell = row.getCell((short) 2);
		System.out.println(cell.getBooleanCellValue());


		cell = row.getCell((short) 3);
		System.out.println(cell.getErrorCellValue());


		cell = row.getCell((short) 4);
		System.out.println(cell.getDateCellValue());
	}
}

  • POI获取行单元格相关信息
有时可能你想要知道行里面单元格的具体信息,比方说,该行实际上有多少单元格,最初的单元格在什么位置,最后的单元格又在哪里?用POI也可以实现。
要取得某一行实际存在的单元格的总数,使用「HSSFRow」类的「getPhysicalNumberOfCells」方法。 

1,public int getPhysicalNumberOfCells()要想知道最初的单元格的位置,可以使用「HSSFRow」类的「getFirstCellNum」方法。 

2,public short getFirstCellNum()你也可以使用「HSSFRow」类的「getLastCellNum」方法来获取最后的单元格的位置,但这里要注意一点,如果单元格存在,如下面的API文档所说,获取的值是实际列号再加上1,在以前的版本可不是这样的。 

3,public short getLastCellNum()需要注意的是,POI在获取最初单元格位置和最后单元格位置时,返回的值并不是某一行特有的,而是针对所有的行。也就是说,上面的两个方法,针对所有的行,返回一个最小的列号和最大的列号。因此,不管对于哪一行,实行上面的两个方法,返回的值都是一样的。 
package linkin;


import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;


public class Linkin
{
	public static void main(String[] args)
	{
		HSSFWorkbook workbook = new HSSFWorkbook();


		HSSFSheet sheet = workbook.createSheet();
		HSSFRow row = sheet.createRow(1);


		System.out.println("创建单元格前的状态:");
		System.out.println("First:" + row.getFirstCellNum());
		System.out.println("Last:" + row.getLastCellNum());
		System.out.println("Total:" + row.getPhysicalNumberOfCells() + "\n");


		row.createCell((short) 1);


		System.out.println("创建第二列(列号为1)单元格:");
		System.out.println("First:" + row.getFirstCellNum());
		System.out.println("Last:" + row.getLastCellNum());
		System.out.println("Total:" + row.getPhysicalNumberOfCells() + "\n");


		row.createCell((short) 3);


		System.out.println("创建第四列(列号为3)单元格:");
		System.out.println("First:" + row.getFirstCellNum());
		System.out.println("Last:" + row.getLastCellNum());
		System.out.println("Total:" + row.getPhysicalNumberOfCells() + "\n");
	}
}

一行当中没有单元格的情况下,调用「getFirstCellNum」方法和「getLastCellNum」方法,返回值都是「-1」。有单元格时,调用「getLastCellNum」方法,返回的值总是实际列号再加上1(实际第几列)。 


  • 从现有的Excel文件读取单元格信息
package linkin;


import java.io.FileInputStream;
import java.io.IOException;


import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;


public class Linkin
{
	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);


		System.out.println("First:" + row.getFirstCellNum());
		System.out.println("Last:" + row.getLastCellNum());
		System.out.println("Total:" + row.getPhysicalNumberOfCells() + "\n");


		row = sheet.getRow(2);


		System.out.println("First:" + row.getFirstCellNum());
		System.out.println("Last:" + row.getLastCellNum());
		System.out.println("Total:" + row.getPhysicalNumberOfCells() + "\n");
	}
}


posted on 2015-05-31 01:07  LinkinPark  阅读(856)  评论(0编辑  收藏  举报