其实刚开始是看Excel转数据库这个需求怎么写的,但是看完之后发现,重中之重在于Excel文件的解析,抛去这个知识点
之外,就是一些简单的流操作和文件格式的解析,由于这些都不难,就觉得没有写的必要了,于是。。。就想到总结一下
如何将各种文件解析为javaBean。
1.XML---->javaBean列表
这个之前的博客有专门讲到,这里就不啰嗦了,请戳==>XML文件的解析。
2.Excel----->javaBean列表
这个其实分两步:
①首先对Excel文件进行解析,因为表格内容由row*col个方块组成,标题加上真正的数据嘛,所以现在将他们取出来
放到一个List中去,那么这个List的长度是显而易见的
package com.eco; import java.io.File; import java.io.FileInputStream; import java.io.InputStream; import java.util.ArrayList; import java.util.List; import jxl.Sheet; import jxl.Workbook; public class AnalyseFileUtil { public static List excelToList(File file) { List list = new ArrayList(); try { InputStream is = new FileInputStream(file.getAbsolutePath()); // jxl提供的Workbook类 Workbook wb = Workbook.getWorkbook(is); // Excel的页签数量 int sheet_size = wb.getNumberOfSheets(); for (int index = 0; index < sheet_size; index++) { // 每个页签创建一个Sheet对象 Sheet sheet = wb.getSheet(index); // sheet.getRows()返回该页的总行数 for (int i = 0; i < sheet.getRows(); i++) { // sheet.getColumns()返回该页的总列数 for (int j = 0; j < sheet.getColumns(); j++) { String cellinfo = sheet.getCell(j, i).getContents(); list.add(cellinfo); } } } } catch (Exception e) { e.printStackTrace(); } return list; } }
不难想象现在拿到的list是个什么造型~~~
②接下来就要对这个很长很长的list进行处理了:
这里呢,又分三步,
第一、新建与Excel标题字段相对应的javaBean,这里为方便起见,将所有成员变量都设置成String类型,代码省略;
第二、写一个利用反射来调用之前javaBean指定Set方法的工具(方法),代码简单,我顺便贴上;
/* * 利用反射执行javaBean的指定setter方法 * * @pram obj javaBean的实例化对象 * * @pram attr javaBean的成员变量 * * @pram value 为这个变量赋值 */ public static void reflectSet(Object obj, String attr, String value) { try { Method[] m = obj.getClass().getMethods(); for (int i = 0; i < m.length; i++) { if (("set" + attr).toLowerCase().equals( m[i].getName().toLowerCase())) { m[i].invoke(obj, new Object[] { value }); } } } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } }
参数:obj(javaBean对应的实例化对象)、attr(你想要调用的setter方法的具体成员变量名称)、vaule(为这个变量赋值)
e.g:
User user =new User();
reflectSet(user,"name","桔子桑");
这样调用了user的setName(String str)方法,使得该user对象的name属性值为“桔子桑”。
第三、将之前Excel导出来的字符串List真正转化为javaBean形式的List,当然长度变成了之前的1/col;
/* * 将excel解析所得list转为相应的javaBean列表 * * @pram input excel解析所得list * * @pram col excel的标题字段数量(javaBean的成员变量数目) * * excel有4列那么对应的javaBean就有4个对应的成员变量 */ public static List excellistToBean(List input, int col, Class cls) throws InstantiationException, IllegalAccessException { List output = new ArrayList(); int count = input.size() / col; int start; int part; String val; String[] pram = new String[col]; for (int n = 0; n < col; n++) { pram[n] = input.get(n).toString(); } for (int i = 1; i < count; i++) { start = i * col; Object user = cls.newInstance(); for (int j = 0; j < col; j++) { part = start + j; val = input.get(part).toString(); AnalyseFileUtil.reflectSet(user, pram[j], val); } output.add(user); } return output; }
这样就实现了,传进三个参数(input为之前的字符串List,col是成员变量的个数也就是Excel表的标题字段个数,cls是与
javaBean相对应的类类型)返回一个javaBean的List了。
下面看测试结果:
package com.eco; import java.io.File; import java.util.List; public class Test { public static void main(String[] args) { File file = new File("test1.xls"); List input = AnalyseFileUtil.excelToList(file); List list = AnalyseFileUtil.excellistToBean(input, 4,User.class);//Excel有4列,自然col参数为4 System.out.println(list); } }
结果显示:
[User [id=1, name=jack, sex=男, age=23], User [id=2, name=tom, sex=女, age=24], User [id=3, name=rose, sex=女, age=34], User [id=4, name=eco, sex=男, age=23], User [id=5, name=eric, sex=男, age=26], User [id=6, name=mseo, sex=女, age=24], User [id=7, name=queeen, sex=女, age=21], User [id=8, name=rock, sex=男, age=22]]
3.javaBean----->Excel
这里用到了jxl包和spring包
①建表头方法
/* * 创建excel表头 * * @pram file excel的导出路径 * * @pram keySortArray 字段排序后的数组,例如:["1","2","3","4"] * * @pram titleMap 表头的map,且map的key与keySortArray一一对应 */ protected static void createExcelTitle(File file, Object[] keySortArray, Map titleMap) { if (file == null) { throw new IllegalArgumentException("文件不存在,无法创建Excel表格。"); } if (keySortArray == null) { throw new IllegalArgumentException("keySortArray 为null,请初始化后在操作。"); } if (titleMap == null) { throw new IllegalArgumentException("titleMap 为 null,无法创建。"); } WritableWorkbook book = null; try { book = Workbook.createWorkbook(file); // 生成名为“第一页”的工作表,参数0表示这是第一页 WritableSheet sheet1 = book.createSheet("sheet1", 0); int n = 0; // 添加标题行 Label label = null; for (Object keyObj : keySortArray) { if (titleMap.containsKey(keyObj)) { label = new Label(n++, 0, titleMap.get(keyObj).toString()); sheet1.addCell(label); } } } catch (IOException e) { throw new IllegalArgumentException("Excel的Sheet工作簿标题写入失败:" + e.getMessage()); } catch (RowsExceededException e) { throw new IllegalArgumentException("Excel的Sheet工作簿标题写入失败:" + e.getMessage()); } catch (WriteException e) { throw new IllegalArgumentException("Excel的Sheet工作簿标题写入失败:" + e.getMessage()); } finally { try { book.write(); book.close(); book = null; } catch (Exception e) { throw new IllegalArgumentException("Excel文件写入失败,可能因为该文件正在被打开中:" + e.getMessage()); } } }
②添加表内容方法
/* * 生成excel表内容 * * @pram keySortArray 字段顺序数组 * * @pram fieldMap 表头map对应的javaBean成员变量map * * @list javaBean列表 * * @pram cls javaBean的类类型 */ protected static void createExcelContent(File file, Object[] keySortArray, Map fieldMap, List list, Class cls) { if (file == null) { throw new IllegalArgumentException("文件不存在,无法创建Excel表格。"); } if (keySortArray == null) { throw new IllegalArgumentException("keySortArray 为null,请初始化后在操作。"); } if (fieldMap == null) { throw new IllegalArgumentException("fieldMap 为 null,无法生成。"); } if (list == null) { throw new IllegalArgumentException("数据列表 为 null,无法读取数据。"); } if (cls == null) { throw new IllegalArgumentException("Class 为 null,无法进行类的映射关系。"); } WritableWorkbook book = null; try { // Excel获得文件 Workbook wb = Workbook.getWorkbook(file); // 打开一个文件的副本,并且指定数据写回到原文件 book = Workbook.createWorkbook(file, wb); // 生成名为“第一页”的工作表,参数0表示这是第一页 WritableSheet sheet1 = book.getSheet("sheet1"); int cols = 0; int rows = 1; BeanWrapper bw = null; Label label = null; for (Object obj : list) { bw = new BeanWrapperImpl(cls.cast(obj)); for (Object keyObj : keySortArray) { if (fieldMap.containsKey(keyObj)) { try { label = new Label(cols++, rows, obj2Str(bw.getPropertyValue(fieldMap.get( keyObj).toString()))); sheet1.addCell(label); } catch (org.springframework.beans.NotReadablePropertyException ex) { label = new Label(cols, rows, "找不到属性为'" + fieldMap.get(keyObj) + "'的方法"); sheet1.addCell(label); } } } cols = 0; rows++; } } catch (IOException e) { throw new IllegalArgumentException("Excel的Sheet工作簿内容写入失败1:" + e.getMessage()); } catch (RowsExceededException e) { throw new IllegalArgumentException("Excel的Sheet工作簿内容写入失败2:" + e.getMessage()); } catch (WriteException e) { throw new IllegalArgumentException("Excel的Sheet工作簿内容写入失败3:" + e.getMessage()); } catch (BiffException e) { throw new IllegalArgumentException("源Excel文件读取失败4:" + e.getMessage()); } finally { try { book.write(); book.close(); book = null; } catch (Exception e) { throw new IllegalArgumentException("Excel文件写入失败,可能因为该文件正在被打开中:" + e.getMessage()); } } }
③为以上两个方法提供参数,继而生成excel
/* * 将javaBean列表导出到对应的excel * * @pram list javaBean列表 * * @pram field2TitleMap map.put("02", "sname|学生姓名")或者map.put("02", "sname") * 前者表示javaBean的sname对应生成表的学生姓名,后者表示javaBean的sname对应生成表的sname * * @pram filePath 导出的excel文件目录 * * @pram cls javaBean的类类型 */ public static void listBeanToExcel(List list, Map field2TitleMap, String filePath, Class cls) { if (list == null) { throw new IllegalArgumentException("ListRange 未被初始化"); } if (field2TitleMap == null) { throw new IllegalArgumentException("field2TitleMap 未被初始化"); } if (filePath == null) { throw new IllegalArgumentException("filePath 未被初始化"); } if (cls == null) { throw new IllegalArgumentException("Class 未被初始化"); } Object[] keySortArray = field2TitleMap.keySet().toArray(); Arrays.sort(keySortArray); // javaBean变量名称Map Map<Object, String> fieldMap = new HashMap<Object, String>(); // 字段中文描述Map Map<Object, String> titleMap = new HashMap<Object, String>(); // 初始化字段名称与字段描述信息 Iterator iter = field2TitleMap.entrySet().iterator(); String[] valArr; Map.Entry entry; Object key; Object val; while (iter.hasNext()) { entry = (Map.Entry) iter.next(); key = entry.getKey(); val = entry.getValue(); if (val != null) { valArr = (val.toString()).split("\|"); if (valArr.length == 2) { fieldMap.put(key, valArr[0]); titleMap.put(key, valArr[1]); } else { fieldMap.put(key, val.toString()); titleMap.put(key, val.toString()); } } } // 创建Excel文件 File file = new File(filePath); // 创建表头 createExcelTitle(file, keySortArray, titleMap); // 生成文件内容 createExcelContent(file, keySortArray, fieldMap, list, cls); }
④测试
Map map = new HashMap(); map.put("01", "id"); map.put("02", "name"); map.put("03", "sex"); map.put("04", "age"); AnalyseFileUtil.listBeanToExcel(list, map, "test3.xls", User.class);
这样就可以将javaBean列表导出到excel文件(test.xls)了