POI操作EXCEL文件的简单封装
程序员文章站
2022-06-07 14:44:31
...
近期看了下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
测试类POITest.java
其他工具类(存放数据的实体类)
Employee.java
用来存放员工数据
Organization.java
用来存放员工所属的组织部门
OrgType.java
用来存放员工所属组织部门的部门类型
Area.java
用来存放员工的籍贯信息
(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; } }
上一篇: HDU 2544 ( 最短路 )
下一篇: 关于explode()的分隔符有关问题