`
lightgjc1
  • 浏览: 1301 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

POI操作EXCEL文件的简单封装

阅读更多
近期看了下POI,写了一些小例子,结合反射技术对EXCEL的导入到出进行了简单封装,主要实现功能如下:
(1)导入EXCEL文档到List<Map<String,String>>中
(2)导出List<Map<String,String>>类型数据到EXCEL中
(3)导出List<Object>类型的数据到EXCEL中
其中第(3)个方法使用了相应的格式规范加反射,具体使用时只要配置好List中对象的取值方法名,可以实现很大程度上的复用
注:支持对象的深度导出,即List中存放对象的取值方法返回值是另一个对象的引用,最终需要的值在这个引用对象中
多余的话就不说了,上代码(Demo工程放到了文章后面的附件中):
POI封装类(主类)MyPOI.java
package com.lightgjc1.poi;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

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 MyPOI {
	
	/**
	 * 导入Excel文件
	 * 		内容以List<Map<String K,String V>>的方式存放
	 * @param excelFile	:	Excel文件对象
	 * @param strKeys	:	Map的Key列表,Value为相应的sheet一行中各列的值
	 * @return
	 */
	public static List<Map<String,String>> importExcelToMap(File excelFile, String strKeys) {
		String[] strKey = strKeys.split(",");
		List<Map<String,String>> listMap = new ArrayList<Map<String,String>>();
		
		int i = 1;
		try {
			HSSFWorkbook workbook = new HSSFWorkbook(new FileInputStream(excelFile));
			HSSFSheet sheet = workbook.getSheetAt(0);
			while (true) {
				HSSFRow row = sheet.getRow(i);
				if (row == null)
					break;
				
				Map<String,String> map = new HashMap<String,String>();
				for(int keyIndex = 0; keyIndex < strKey.length; keyIndex++){
					map.put(strKey[keyIndex], row.getCell(keyIndex).getStringCellValue());
				}
				listMap.add(map);
				
				i++;
			}
		} catch (Exception e) {
			e.printStackTrace();
			
			System.out.println("导入中断,错误位置:第"+ i +"行数据!");
		}
		
		return listMap;
	}
	
	/**
	 * 导出Excel文件
	 * 		数据源的数据格式为List<Map<String K,String V>>
	 * @param objList	:	Excel数据源
	 * @param title		:	新建Sheet的名称
	 * @param strTitle	:	Sheet各列的标题(第一行各列的名称)
	 * @param strBody	:	Sheet各列的取值方法名(各列的值在objClass中get方法名称)
	 * @param outputPath:	Excel文档保存路径
	 */
	public static void exportExcelByMap(List<Map<String,String>> objList, String title, String strTitle, String strBody, String outputPath) {
		// 创建工作簿(Excel文件)
		HSSFWorkbook workbook = new HSSFWorkbook();
		
		// 创建Excel工作簿的第一个Sheet页
		HSSFSheet sheet = workbook.createSheet(title);
		
		// 创建Sheet页的文件头(第一行)
		createTitle(sheet, strTitle);
		
		// 创建Sheet页的文件体(后续行)
		String[] strArray = strBody.split(",");
		for(int objIndex = 0; objIndex < objList.size(); objIndex++) {
			Map map = objList.get(objIndex);
			HSSFRow row = sheet.createRow(objIndex + 1); 
			for(int i = 0; i < strArray.length; i++) {
				HSSFCell cell = row.createCell(i);
				cell.setCellType(HSSFCell.CELL_TYPE_STRING);
				cell.setCellValue(map.get(strArray[i]).toString());
			}
		}
		
		// 保存Excel文件
		saveExcelFile(workbook, outputPath);
	}
	
	/**
	 * 导出Excle文档
	 * 
	 * @param objList	:	Excel数据源
	 * @param objClass	:	Excel数据源中的数据类型
	 * @param title		:	新建Sheet的名称
	 * 				ex:	title = "员工表";
	 * @param strTitle	:	Sheet各列的标题(第一行各列的名称)
	 * 				ex:	strTitle = "员工代码,员工姓名,性别,出生日期,籍贯,所属机构,联系电话,电子邮件,助记码";
	 * @param strBody	:	Sheet各列的取值方法名(各列的值在objClass中get方法名称)
	 * 				ex:	strBody = "getCode,getName,getSex,getBirthday,getHomeplace.getName,getOrg.getShortName,getContactTel,getEmail,getZjm";
	 * @param outputPath:	Excel文档保存路径
	 */
	public static void exportExcelByObject(List objList, Class objClass, String title, String strTitle, String strBody, String outputPath) {
			// 初始化工作簿
			HSSFWorkbook workbook = initWorkbook(objList, objClass, title, strTitle, strBody);
			// 保存Excel文件
			saveExcelFile(workbook, outputPath);
	}
	/**
	 * 初始化工作簿
	 * 
	 * @param objList	:	Excel数据源
	 * @param objClass	:	Excel数据源中的数据类型
	 * @param title		:	新建Sheet的名称
	 * @param strTitle	:	Sheet各列的标题(第一行各列的名称)
	 * @param strBody	:	Sheet各列的取值方法名(各列的值在objClass中get方法名称)
	 */
	private static HSSFWorkbook initWorkbook(List objList, Class objClass, String title, String strTitle, String strBody){
		// 创建工作簿(Excel文件)
		HSSFWorkbook workbook = new HSSFWorkbook();
		
		// 创建Excel工作簿的第一个Sheet页
		HSSFSheet sheet = workbook.createSheet(title);
		
		// 创建Sheet页的文件头(第一行)
		createTitle(sheet, strTitle);
		
		// 创建Sheet页的文件体(后续行)
		createBody(objList, objClass, sheet, strBody);
		
		return workbook;
	}
	
	/**
	 * 创建Excel当前sheet页的头信息
	 * 
	 * @param sheet		:	Excel工作簿的一个sheet
	 * @param strTitle	:	sheet头信息列表(sheet第一行各列值)
	 */
	private static void createTitle(HSSFSheet sheet, String strTitle){
		HSSFRow row = sheet.createRow(0); // 创建该页的一行
		HSSFCell cell = null;
		
		String[] strArray = strTitle.split(",");
		
		for(int i = 0; i < strArray.length; i++) {
			cell = row.createCell(i); // 创建该行的一列
			cell.setCellType(HSSFCell.CELL_TYPE_STRING);
			cell.setCellValue(strArray[i]);
		}
		
	}
	
	/**
	 * 创建Excel当前sheet页的体信息
	 * 
	 * @param objList	:	Excel数据源
	 * @param objClass	:	Excel数据源中的数据类型
	 * @param sheet		:	Excel工作簿的sheet页
	 * @param strBody	:	Sheet各列的取值方法名(各列的值在objClass中get方法名称)
	 */
	private static void createBody(List objList, Class objClass, HSSFSheet sheet, String strBody){
		String[] targetMethod = strBody.split(",");
		Method[] ms = objClass.getMethods();
		
		// 循环objList对象列表(生成sheet的行)
		for(int objIndex = 0; objIndex < objList.size(); objIndex++){
			Object obj = objList.get(objIndex);
			HSSFRow row = sheet.createRow(objIndex + 1);
			// 循环strBody目标方法数组(生成sheet的列)
			for(int strIndex = 0; strIndex < targetMethod.length; strIndex++) {
				String targetMethodName = targetMethod[strIndex];
				// 循环ms方法数组,找到目标方法(strBody中指定的方法)并调用
				for(int i = 0; i < ms.length; i++) {
					Method srcMethod = ms[i];
					int len = targetMethodName.indexOf(".") < 0 ? targetMethodName.length() : targetMethodName.indexOf(".");
					if (srcMethod.getName().equals(targetMethodName.substring(0, len))) {
						HSSFCell cell = row.createCell(strIndex);
						cell.setCellType(HSSFCell.CELL_TYPE_STRING);
						try {
							// 如果方法返回一个引用类型的值
							if (targetMethodName.contains(".")) {
								cell.setCellValue(referenceInvoke(targetMethodName, obj));
							// 如果方法返回一个普通属性
							} else {
								cell.setCellValue((srcMethod.invoke(obj)).toString());
							}
						} catch (Exception e) {
							e.printStackTrace();
						}
					}
				}
			}
		}
		
	}
	
	/**
	 * 方法返回的是一个对象的引用(如:getHomeplace.getName类型的方法序列)
	 * 		按方法序列逐层调用直到最后放回基本类型的值
	 * 
	 * @param targetMethod	:	obj对象所包含的方法列
	 * @param obj			:	待处理的对象
	 * @return
	 */							//getHomeplace.getName   emp(obj)
	private static String referenceInvoke(String targetMethod, Object obj) {						
		// 截取方法序列的第一个方法(即截取属于obj对象的方法:getHomeplace())
		String refMethod = targetMethod.substring(0, targetMethod.indexOf("."));
		// 获得后续方法序列(getName())
		targetMethod = targetMethod.substring(targetMethod.indexOf(".") + 1);
		try {
			// 获得第一个方法的执行结果(即obj方法执行的结果:obj.getHomeplace())
			obj = obj.getClass().getMethod(refMethod).invoke(obj);
		} catch (Exception e) {
			e.printStackTrace();
		} 
		
		// 如果方法序列没到最后一节
		if (targetMethod.contains(".")) {
			return referenceInvoke(targetMethod, obj);
		// 如果方法序列到达最后一节
		} else {
			try {
				// 通过obj对象获得该方法链的最后一个方法并调用
				Method tarMethod = obj.getClass().getMethod(targetMethod);
				return tarMethod.invoke(obj).toString();
			} catch (Exception e) {
				e.printStackTrace();
				throw new RuntimeException(e);
			}
		}
		
	}
	
	/**
	 * 保存Excel文件
	 * 
	 * @param workbook	:	Excel工作簿
	 * @param outputPath:	Excel文件保存路径
	 */
	private static void saveExcelFile(HSSFWorkbook workbook, String outputPath) {
		try {
			FileOutputStream fos = new FileOutputStream(outputPath);
			workbook.write(fos);
			
			fos.flush();
			fos.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}


测试类POITest.java
package com.lightgjc1.test;

import java.io.File;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

import junit.framework.TestCase;

import com.lightgjc1.domain.Area;
import com.lightgjc1.domain.Employee;
import com.lightgjc1.domain.OrgType;
import com.lightgjc1.domain.Organization;
import com.lightgjc1.poi.MyPOI;

public class POITest extends TestCase {
	public void testImportAndExportExcel(){
		String strKeys = "setCode,setName,setSex,setBirthday,setHomeplace,setOrg,setContactTel";
		List<Map<String,String>> listMap = MyPOI.importExcelToMap(new File("D:\\employee.xls"), strKeys);
		
		String[] keys = strKeys.split(",");
		for(Map map : listMap) {
			for(int i = 0; i < keys.length; i++) {
				System.out.print(map.get(keys[i]) +" ");
			}
			System.out.println();
			System.out.println("----------------");
		}
		
		String title = "员工表";
		String strTitle = "员工代码,员工姓名,性别,出生日期,籍贯,所属机构,机构类型";
		String strBody = "setCode,setName,setSex,setBirthday,setHomeplace,setOrg,setContactTel";
		String outputPath = "D:\\employee2.xls";
		MyPOI.exportExcelByMap(listMap, title, strTitle, strBody, outputPath);
	}
	
	public void testExportExcel(){
		List objList = initData();
		Class objClass = Employee.class;
		String title = "员工表";
		String strTitle = "员工代码,员工姓名,性别,出生日期,籍贯,所属机构,机构类型";
		String strBody = "getCode,getName,getSex,getBirthday,getHomeplace.getName,getOrg.getShortName,getOrg.getOrgType.getName";
		String outputPath = "D:\\employee.xls";
		
		MyPOI.exportExcelByObject(objList, objClass, title, strTitle, strBody, outputPath);
	}
	
	private List initData(){
		List empList = new ArrayList();
		
		Employee emp = null;
		for(int i = 0; i < 10; i++) {
			emp = new Employee();
			emp.setCode(i +"号");
			emp.setName(i +"号");
			emp.setSex(i % 2 == 0 ? "女" : "男");
			emp.setBirthday(new Date());
			
			
			Area area = new Area();
			area.setName(i +"市");
			emp.setHomeplace(area);
			
			
			OrgType orgType = new OrgType();
			orgType.setName("机构类型"+ i);
			
			Organization org = new Organization();
			org.setOrgType(orgType);
			org.setShortName("机构"+ i);
			
			emp.setOrg(org);
			
			
			empList.add(emp);
		}
		
		return empList;
	}
}


其他工具类(存放数据的实体类)
Employee.java
用来存放员工数据
package com.lightgjc1.domain;

import java.util.Date;

public class Employee {

	private String id;
	
	private String code;
	
	private String name;
	
	private String sex;
	
	private Date birthday;
	
	private String email;
	
	private String contactTel;
	
	private String zjm;
	
	private Organization org = new Organization();
	
	private Area homeplace;

	public String getId() {
		return id;
	}

	public void setId(String id) {
		this.id = id;
	}

	public String getCode() {
		return code;
	}

	public void setCode(String code) {
		this.code = code;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getSex() {
		return sex;
	}

	public void setSex(String sex) {
		this.sex = sex;
	}

	public Date getBirthday() {
		return birthday;
	}

	public void setBirthday(Date birthday) {
		this.birthday = birthday;
	}

	public String getEmail() {
		return email;
	}

	public void setEmail(String email) {
		this.email = email;
	}

	public String getContactTel() {
		return contactTel;
	}

	public void setContactTel(String contactTel) {
		this.contactTel = contactTel;
	}

	public String getZjm() {
		return zjm;
	}

	public void setZjm(String zjm) {
		this.zjm = zjm;
	}

	public Organization getOrg() {
		return org;
	}

	public void setOrg(Organization org) {
		this.org = org;
	}

	public Area getHomeplace() {
		return homeplace;
	}

	public void setHomeplace(Area homeplace) {
		this.homeplace = homeplace;
	}
	
	
}


Organization.java
用来存放员工所属的组织部门
package com.lightgjc1.domain;

import java.util.Set;

public class Organization {

	private String id;
	
	private String code;
	
	private String fullName;
	
	private String shortName;
	
	private String manager;
	
	private String desc;

	//*-----1
	private OrgType orgType;
	
	//*-----1
	private Organization parent;
	
	//1-----*
	private Set<Organization> children; 
	
	public String getId() {
		return id;
	}

	public void setId(String id) {
		this.id = id;
	}

	public String getCode() {
		return code;
	}

	public void setCode(String code) {
		this.code = code;
	}

	public String getFullName() {
		return fullName;
	}

	public void setFullName(String fullName) {
		this.fullName = fullName;
	}

	public String getShortName() {
		return shortName;
	}

	public void setShortName(String shortName) {
		this.shortName = shortName;
	}

	public String getManager() {
		return manager;
	}

	public void setManager(String manager) {
		this.manager = manager;
	}

	public String getDesc() {
		return desc;
	}

	public void setDesc(String desc) {
		this.desc = desc;
	}

	public OrgType getOrgType() {
		return orgType;
	}

	public void setOrgType(OrgType orgType) {
		this.orgType = orgType;
	}

	public Organization getParent() {
		return parent;
	}

	public void setParent(Organization parent) {
		this.parent = parent;
	}

	public Set<Organization> getChildren() {
		return children;
	}

	public void setChildren(Set<Organization> children) {
		this.children = children;
	}
	
}


OrgType.java
用来存放员工所属组织部门的部门类型
package com.lightgjc1.domain;

public class OrgType {

	private String id;
	
	//如果使用数值类型作为主键,建议使用包装类
	//private Integer id;
	//private int id;
	
	private String code;
	
	private String name;

	public String getId() {
		return id;
	}

	public void setId(String id) {
		this.id = id;
	}

	public String getCode() {
		return code;
	}

	public void setCode(String code) {
		this.code = code;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}
	
}


Area.java
用来存放员工的籍贯信息
package com.lightgjc1.domain;

import java.util.Set;

public class Area {

	private String id;
	
	private String code;
	
	private String name;
	
	private Area parent;
	
	private Set<Area> children;

	public String getId() {
		return id;
	}

	public void setId(String id) {
		this.id = id;
	}

	public String getCode() {
		return code;
	}

	public void setCode(String code) {
		this.code = code;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public Area getParent() {
		return parent;
	}

	public void setParent(Area parent) {
		this.parent = parent;
	}

	public Set<Area> getChildren() {
		return children;
	}

	public void setChildren(Set<Area> children) {
		this.children = children;
	}
	
}
分享到:
评论

相关推荐

    POI操作Excel的封装

    在这个场景中,"POI操作Excel的封装"指的是对POI API进行的高级抽象和简化,以便于开发人员更方便地处理Excel文件。通过反射和约定,可以创建一个易于使用的API,隐藏底层复杂的POI细节。 反射是Java编程语言中的一...

    poi读取excel文件

    附带的`ExcelUtil.java`源码文件,通常是一个工具类,封装了使用Apache POI读取Excel文件的关键操作,比如打开文件、遍历工作表、读取单元格数据等。这样的工具类可以简化开发过程,避免重复编写基础代码。 使用...

    基于POI的Excel操作Java类

    为更方便的使用POI的API来操作Excel(2003)文件,对POI中针对Excel文件的读写进行了简单封装。此类中包含以下功能: 1.根据模板创建Excel文件 2.获取及更新Excel文件内容 3.创建、复制Sheet 4.设置Sheet名称 ... ...

    基于poi的excel导入导出封装

    在"基于poi的excel导入导出封装"这个主题中,我们将深入探讨如何使用Apache POI库来实现Excel文件的导入和导出功能。 **一、Apache POI基本概念** 1. **工作簿(Workbook)**: 在Apache POI中,工作簿是Excel文件...

    基于poi对excel操作的简单封装和必要的poi3.17包

    基于poi对excel操作的简单封装及必要的poi3.17包。针对excel文件或输入流,按行或者单元格解析处理,提供简单的通用单元格数据获取方法(数字类单元格返回Double, 日期返回Date, 公式返回计算后的结果,其它返回...

    使用POI,实现excel文件导出,图片url导出文件,图片和excel文件导出压缩包

    本文将深入探讨如何使用POI库来实现Excel文件的导出,以及如何将图片URL转换为图片文件并与其他文件一起打包成压缩包。 首先,让我们了解一下Apache POI。POI是Java开发者的开源API,它允许程序创建、修改和显示...

    Java 使用poi导入excel 并使用xml做数据验证

    导入数据的过程中,首先需要创建一个`Workbook`对象来代表Excel文件,然后通过`Sheet`对象来操作单个工作表,接着是`Row`和`Cell`对象来处理每一行和每一列的数据。使用POI读取Excel数据的基本步骤如下: 1. 加载...

    java中poi读写excel封装工具类(兼容office2003和2007等版本)

    Java中的Apache POI库是处理Microsoft Office文档的强大工具,尤其在读写Excel文件方面。它不仅支持旧版的Excel文件格式(.xls,用于Office 2003及更早版本),还支持新版本的Excel文件格式(.xlsx,自Office 2007起...

    poi导出excel demo

    在本示例中,"poi导出excel demo"指的是使用Apache POI库创建和导出Excel文件的演示。这个项目可能包含了一个或多个Java源代码文件,展示了如何使用POI API来生成Excel工作簿、工作表、单元格等内容。 Apache POI ...

    poi简单的封装工具

    【标题】"poi简单的封装工具"涉及到的主要知识点是Java中的Apache POI库,这是一个用于处理Microsoft Office格式文件的开源库,特别适用于Excel文件的操作。在Java编程中,Apache POI库提供了一种方便的方式来创建、...

    POI操作excel封装工具类

    支持对excel的两中格式操作,封装了往单元格插入数据(支持书写单元格引用或者单元格坐标)、设置和获取sheet及workbook、往excel特定位置插入图片、获取excel中所有的图片、复制sheet、移除sheet、复制sheet中的...

    Excel POI读取封装(文件+示范代码)

    Excel POI读取封装(文件+示范代码) package org.excel.service; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileWriter; import java.io.IOException; import java....

    poi读取大文件Excel,使用xml格式解析,速度实测50mb文件13s,可指定sheet页内容,带工具类和测试类

    在处理大型Excel文件时,传统的HSSF和XSSF模型可能会遇到性能瓶颈,因为它们将整个工作簿加载到内存中。为了解决这个问题,POI提供了SXSSF(Streaming Usermodel API)和XSSFEventUserModel API。这里的主题是利用...

    poi 操作 excel 2007 demo 及poi类库

    在Java世界中,POI库是处理Excel文件的首选工具,尤其对于读写Excel 2007(.xlsx)这种基于OpenXML格式的文件,POI提供了强大的支持。下面将详细介绍如何使用Apache POI操作Excel 2007以及相关的类库。 首先,"poi-...

    java使用POI导出 Excel工具类

    java使用POI导出 Excel+图片工具类 ,里面含有poi jar包,只调用接口即可直接保存Excel。使用的时候需先把数据封装,具体包装需根据实际导出数据进行处理。文件demo中只提供包装格式。

    用poi解析Excel文件

    这篇博客文章“用poi解析Excel文件”将深入探讨如何使用Apache POI库来操作Excel数据。 首先,Apache POI提供了HSSF和XSSF两个API,分别用于处理老版本的.xls文件(BIFF8格式)和新版本的.xlsx文件(OOXML格式)。...

    springmvc+POI的Excel文件导入导出

    总结起来,"SpringMvc+POI的Excel文件导入导出"涉及到的关键技术包括Spring MVC的文件上传处理、Apache POI的Excel读写操作、以及模板填充和导出。通过熟练掌握这些技术,开发者能够高效地处理企业级应用中的Excel...

    poi excel转换成bean

    标题“poi excel转换成bean”涉及到的关键技术是使用Apache POI从Excel文件中读取数据并将其映射到Java Bean对象中。这个过程在处理大量结构化数据时特别有用,例如导入数据库或进行数据分析。 首先,我们需要理解...

    POI实现excel导入导出

    1. **创建Workbook对象**:这是处理Excel文件的基本单元。你可以使用`WorkbookFactory.create(InputStream)`或`WorkbookFactory.create(File)`来创建一个Workbook实例,取决于你是否有文件的物理路径或只是输入流。 ...

Global site tag (gtag.js) - Google Analytics