Java使用POI操作Excel

        最近项目频繁使用到Java对Excel的操作,在项目中使用到POI,下面实现了对Excel读和写,都是通过反射的方式实现,这样就更具有通用的效果了。需要注意的是将一个类的数据写入到Excel中,那么类中的属性要与Excel中的标题一一对应,比如:Excel标题的顺序是姓名、年龄、住址,那么类中的属性名也要是姓名、年龄、住址这个顺序。当然这是要Excel有标题的时候,如果没有标题,那么类中的属性顺序就无所谓了。使用到POI呢,最基本的就是要下载POI,下载链接为:http://poi.apache.org/download.html,接下来进入正题,如下:

写入Excel文件:

/**
	 * 创建Excel
	 * @param fileName 文件名称
	 * @param title Excel工作簿标题
	 * @param headers 表格头标题
	 * @param dataList 要写入的数据
	 */
	public static <T> void createExcel(String fileName,String title,String[] headers,List<T> dataList){
		//创建文件输出流
		FileOutputStream out=null;
		try {
			out=new FileOutputStream(getFile(fileName));
			//创建HSSFWorkbook
			HSSFWorkbook workbook=new HSSFWorkbook();
			//创建HSSFSheet
			HSSFSheet sheet=workbook.createSheet(title);
			//创建标题行
			HSSFRow titleRow=sheet.createRow(0);
			//设置行高
			titleRow.setHeight((short)400);
			//根据Workbook创建列样式
			HSSFCellStyle cellStyle=workbook.createCellStyle();
			//上下居中
			cellStyle.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);
			//遍历标题
			for(int i=0;i<headers.length;i++){
				//设置列宽
				sheet.setColumnWidth(i, 20*150);
				//创建列
				HSSFCell cell=titleRow.createCell(i);
				//设置列值
				cell.setCellValue(headers[i]);
				//设置样式
				cell.setCellStyle(cellStyle);
			}
			
			//处理数据行
			for(int i=0;i<dataList.size();i++){
				//创建数据行
				HSSFRow dataRow=sheet.createRow(i+1);
				//获取Class对象
				Class clazz=dataList.get(i).getClass();
				//获取对象中的所有字段
				Field[] fields=clazz.getDeclaredFields();
				for(int j=0;j<headers.length;j++){
					//创建列
					HSSFCell cell=dataRow.createCell(j);
					//获取属性名称
					String fieldName=fields[j+2].getName();
					//获取方法名称
					String methodName="get"+fieldName.substring(0,1).toUpperCase()+fieldName.substring(1);
					//获取方法
					Method method=clazz.getDeclaredMethod(methodName, new Class[]{});
					//获取值
					Object value=method.invoke(dataList.get(i), new Object[]{});
					//根据值类型设置单元格值
					if(null==value||"".equals(value)){
						cell.setCellValue("");
					}else if(value instanceof Integer){
						cell.setCellType(Cell.CELL_TYPE_NUMERIC);//数字单元格
						cell.setCellValue(Integer.valueOf(value.toString()));
					}else if(value instanceof BigDecimal){
						cellStyle.setDataFormat(HSSFDataFormat.getBuiltinFormat("0.00"));
						cell.setCellStyle(cellStyle);
						cell.setCellValue(value.toString());
					}else if(value instanceof Date){
						cellStyle.setDataFormat(workbook.createDataFormat().getFormat("yyyy-MM-dd"));
						cell.setCellStyle(cellStyle);
						cell.setCellValue((Date) value);
					}else{
						cell.setCellValue(value.toString());
					}
				}
			}
			//写入到文件中
			workbook.write(out);
		} catch (Exception e) {
			e.printStackTrace();
		}finally{
			//关闭流对象
			try {
				out.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
读取Excel文件:

/**
	 * 读取Excel
	 * @param clazz 将Excel数据读取到对应的Java类
	 * @param fileName 文件名
	 * @return
	 */
	public static <T> List<T> readExcel(Class<T> clazz,String fileName){
		//获取文件
		File file=getFile(fileName);
		//创建数据集合
		List<T> list=new ArrayList<T>();
		//声明输入流对象
		FileInputStream input=null;
		try {
			//创建输入流对象
			input=new FileInputStream(file);
			//创建Workbook
			HSSFWorkbook workbook=new HSSFWorkbook(input);
			//创建Sheet
			HSSFSheet sheet=workbook.getSheetAt(0);
			for(int i=1;i<=sheet.getLastRowNum();i++){
				//获取行
				HSSFRow row=sheet.getRow(i);
				//实例化对象
				T t=clazz.newInstance();
				//获取传入对象的所有字段
				Field[] fields=clazz.getDeclaredFields();
				for(int j=0;j<row.getLastCellNum();j++){
					Field field=fields[j+2];//获取Field对象
					field.setAccessible(true);//设置属性可访问
					//获取字段类型
					String type=field.getType().toString();
					//根据类型设置值
					if(type.endsWith("String")){
						field.set(t, row.getCell(j).getStringCellValue());
					}else if(type.endsWith("Integer")){
						field.set(t, ((Double)row.getCell(j).getNumericCellValue()).intValue());
					}else if(type.endsWith("Double")){
						field.set(t, (row.getCell(j).getNumericCellValue()));
					}else if(type.endsWith("Date")){
						field.set(t, row.getCell(j).getDateCellValue());
					}
					field.setAccessible(false);
				}
				//添加到集合
				list.add(t);
			}

		} catch (Exception e) {
			e.printStackTrace();
		}finally{
			//关闭流对象
			try {
				input.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return list;
	}



创建文件:

/**
	 * 获取文件
	 * @param fileName 文件名称
	 * @return
	 */
	private static File getFile(String fileName){
		boolean flg1=false;
		//文件路径
		String filePath=getCurrentPath();
		File dir=new File(filePath);
		File file=null;
		//如果目录不存在,则创建
		if(!dir.exists()){
			flg1=dir.mkdirs();
			//生成目录失败
			if(!flg1){
				System.out.println("目录生成失败!");
			}
		}else{
			file = new File(dir + File.separator + fileName);
			//判断文件是否存在
			if (!file.exists()) {
                try {
                	//创建文件
                    file.createNewFile();
                }
                catch (IOException e) {
                	System.out.println("文件创建失败!");
                }
            }
			return file;
		}
		return file;
	} 

测试读写Excel文件:

String[] headers={"姓名","年龄","联系电话","居住地址","出生日期"};
		//数据准备
		List<Student> dataList=new ArrayList<Student>();
		dataList.add(new Student(1,"张三", 23, "110", "东风东路", new Date()));
		dataList.add(new Student(2,"张三1", 23, "110", "东风东路", new Date()));
		dataList.add(new Student(3,"张三2", 23, "110", "东风东路", new Date()));
		dataList.add(new Student(4,"张三3", 23, "110", "东风东路", new Date()));
		dataList.add(new Student(5,"张三4", 23, "110", "东风东路", new Date()));
		//createFile("学生信息表");
		String fileName="学生信息表"+System.currentTimeMillis()+".xls";
		//写入Excel文件
		ExcelHandlerUtil.createExcel(fileName,"学生信息",headers, dataList);
		//读取Excel文件
		List<Student> list=ExcelHandlerUtil.readExcel(Student.class,"学生信息表1445676251183.xls");
		for (Student student : list) {
			System.out.println(student.getName()+"\t"+student.getBirthday());
		}
需要说明一点,在读写Excel的方法中,在获取属性Field对象时是这样的

Field field=fields[j+2];//获取Field对象
是因为在实体中是要从name开始读取或设置值,因为第一个和第二个属性是serialVersionUID、id,如果没有这两个就不用加2,如果只有一个就加1,下面是实体:

public class Student implements Serializable{
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	private Integer id;
	private String name;//姓名
	private Integer age;//年龄
	private String telephone;//联系电话
	private String address;//居住地址
	private Date birthday;//出生日期
	
	public Student() {
		super();
	}
	public Student(Integer id,String name, Integer age, String telephone, String address,
			Date birthday) {
		super();
		this.id=id;
		this.name = name;
		this.age = age;
		this.telephone = telephone;
		this.address = address;
		this.birthday = birthday;
	}
	
}
省略get和set方法,因为写入和读取都用到的是反射实现,所以就不是针对某一个实体,可以是任何实体,只要对应好关系即可。

源代码下载


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小老虎Love

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值