poi读取excel的辅助类
补充:对于这个工具已经转为一个工程项目,采用的是saxreader方式,支持大数据文件的读取。具体可以参照 github上的源码,使用可以简单参照wiki。项目wiki地址https://git.oschina.net/bingyulei007/bingExcel/wikis/
另外,项目旨在解决简单的excel文件读取与excel文件导出,对于样式要求过高的还是推荐使用原生的poi。另外在BingExcel中,改进了反射的转换部分(对于同一个实体类,反射读取属性进行了缓存,大大提高了速度),并支持注册全局及局部的converter。
这个并没有彻底完善,只是项目中用到,不过平常的实体类与excel03的转换基本满足了,这里不在整理,主要用于以后改进使用。util是基于poi3.8写的
先提交上测试代码:
1.生成一个excel的文件并加入表头。
@Test public void testCreatTop(){ String path = "F:/mytest/module1.xls"; //create一个file,就是用file类的createNewfile方法 File file=com.bing.jpatest.util.FileUtil.createFile(path); HSSFWorkbook wb=new HSSFWorkbook(); HSSFSheet sheet=wb.createSheet(); sheet.setDefaultColumnWidth(12);//默认宽读 sheet.setDefaultRowHeight((short) (20*20));//默认高度 sheet.setColumnWidth(2, 20*256);//可以设置指定列的高度或宽度 String[] arr={"组织结构","ioex","In","合集"}; //创建表头,其实关键是最后一个参数,我这里就是设置如果是true的话,加上北京等效果,创建的表头是按照数组的顺序 ExcelHanderUtil.writeLineToSheet(wb, sheet, arr, 0, true); }
2.自动写入list数据,这里可以模仿数据库查询出的结果,写进excel
@Test public void testExcelutil() { String path = "F:/mytest/module1.xls"; //创建一个file,就是用file类的createNewfile方法,我只是封装了而已 File file=com.bing.jpatest.util.FileUtil.createFile(path); HSSFWorkbook wb=new HSSFWorkbook(); HSSFSheet sheet=wb.createSheet(); sheet.setDefaultColumnWidth(12);//默认宽读 sheet.setDefaultRowHeight((short) (20*20));//默认高度 sheet.setColumnWidth(2, 20*256);//可以设置指定列的高度或宽度 String[] arr={"组织结构","ioex","In","合集"}; try { //创建表头 ExcelHanderUtil.writeLineToSheet(wb, sheet, arr, 0, true); Person p1=new Person("jone",6); Person p2=new Person("jone2",26); p2.setBirthday(new Date()); Person p3=new Person("jon003",63); List<Person> list=new ArrayList<Person>(); list.add(p1); list.add(p2); list.add(p3); //读取属性的顺序 String [] arr2={"name","age","birthday"}; try { //里面有很多类似的重载,这里是加入一个list对象,写入多行数据 ExcelHanderUtil.writeLinesToSheet(sheet, list, arr2, 1); } catch (NoSuchFieldException | SecurityException | NoSuchMethodException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) { e.printStackTrace(); } ExcelHanderUtil.writetoWb03(wb, file); } catch (IOException e) { e.printStackTrace(); } }
里面的person类很简单,主要用于测试
package com.bing.test; import java.util.Date; public class Person{ private String name; private int age; private Date birthday; public Date getBirthday() { return birthday; } public void setBirthday(Date birthday) { this.birthday = birthday; } public Person() { super(); } public Person(String string, int i) { this.name=string; this.age=i; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } }
输出结果如下图:
3.读取excel到实体bean,还用步骤2输出的excel来练习
@Test public void testLoadExcelTo() throws FileNotFoundException, IOException, InstantiationException, IllegalAccessException, NoSuchMethodException, SecurityException, NoSuchFieldException, IllegalArgumentException, InvocationTargetException, ParseException{ String path = "F:/mytest/module1.xls"; String[] colunms={"name","age","birthday"}; //ExcelHanderUtil.readExcelToEntity(file, colunms, classType, fromRow) List<Person> list=ExcelHanderUtil.readSheetToEntity(wb.getSheetAt(0), colunms, Person.class, 1); System.out.println(list.size()); SimpleDateFormat format=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); System.out.println(format.format(list.get(1).getBirthday())); }
4.当然里面还有其他常用的方法,如检验一下表格结构是不是符合规范等
String[] arr={"组织结构","ioex","In","合集"}; HSSFWorkbook wb=new HSSFWorkbook(new FileInputStream(path)); boolean re=ExcelHanderUtil.validOrder(arr, wb.getSheetAt(0)); System.out.println(re);
附上,utli的源码。
package com.bing.jpatest.util; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Calendar; import java.util.Date; import java.util.List; import java.util.Map; import org.apache.poi.hssf.usermodel.HSSFCell; import org.apache.poi.hssf.usermodel.HSSFCellStyle; import org.apache.poi.hssf.usermodel.HSSFDataFormat; import org.apache.poi.hssf.usermodel.HSSFDateUtil; import org.apache.poi.hssf.usermodel.HSSFFont; import org.apache.poi.hssf.usermodel.HSSFRichTextString; 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.hssf.util.HSSFColor; import org.apache.poi.ss.usermodel.CellStyle; import org.apache.poi.ss.util.CellRangeAddress; import org.w3c.dom.ls.LSInput; import com.google.gson.JsonArray; import com.google.gson.JsonObject; /** * 操作excel的类,需要poi3.8的jar包<br>maven地址,目前仅支持03版本 *<p> <dependency><br> * <groupId>org.apache.poi</groupId><br> * <artifactId>poi</artifactId><br> * <version>3.8</version><br> *</dependency> *</p> * @author shizhongtao * * 2015 2015-4-24 下午5:49:55 * * @author shizhongtao * * 2015 2015-4-27 下午4:08:15 */ public class ExcelHanderUtil { /** * 把excel写到指定文件中 * * @param wb * @param path * @throws IOException */ public static void writetoWb03(HSSFWorkbook wb, File file) throws IOException { FileOutputStream fileOut = new FileOutputStream(file); writeStremtoWb03(wb, fileOut);// 创建时候需要调用 } /** * 把excel写到指定路径 * * @param wb * @param path * @throws IOException */ public static void writetoWb03(HSSFWorkbook wb, String path) throws IOException { FileOutputStream fileOut = new FileOutputStream(path); writeStremtoWb03(wb, fileOut); } /** * 把excel写到输出流里面, * * @param wb * @param fileOut * @throws IOException */ public static void writeStremtoWb03(HSSFWorkbook wb, OutputStream fileOut) throws IOException { wb.write(fileOut);// 把Workbook对象输出到文件workbook.xls中 fileOut.close(); } /** * 创建Sheet工作薄 * * @param wb * @param name * 唯一指定的sheet名称 * @return 返回创建的HSSFSheet, 如果名字是null或者已经被占用抛出异常 * @throws IllegalArgumentException * if the name is null or invalid or workbook already contains a * sheet with this name */ public static HSSFSheet createSheet(HSSFWorkbook wb, String name) { HSSFSheet sheet = wb.createSheet(name); return sheet; } /** * 创建Sheet工作薄 * * @param wb * @return 返回创建的HSSFSheet */ public static HSSFSheet createSheet(HSSFWorkbook wb) { return wb.createSheet(); } /** * 插入一个对象到表格 * * @param <T> * 对象类型 * @param sheet * @param obj * 带插入对象 * @param arr * key值的数组,用来规定插入顺序 * @param rowIndex * @throws InvocationTargetException * @throws IllegalArgumentException * @throws IllegalAccessException * @throws NoSuchMethodException * @throws SecurityException * @throws NoSuchFieldException */ public static <T> void writeLineToSheet(HSSFSheet sheet, Class<T> clz, T obj, String[] arr, int rowIndex) throws NoSuchFieldException, SecurityException, NoSuchMethodException, IllegalAccessException, IllegalArgumentException, InvocationTargetException { HSSFRow row = sheet.createRow(rowIndex); writeLineToRow(getValuesByOrder(clz, obj, arr), row); } private static <T> Object[] getValuesByOrder(Class<T> clz, T obj, String[] arr) throws NoSuchFieldException, SecurityException, NoSuchMethodException, IllegalAccessException, IllegalArgumentException, InvocationTargetException { Object[] values = new Object[arr.length]; for (int i = 0; i < arr.length; i++) { String getMethodName = "get" + toUpFirst(arr[i]); Method method = clz.getDeclaredMethod(getMethodName); Object value = method.invoke(obj); values[i] = value; } return values; } /** * 插入一个map对象到表格 * * @param sheet * @param map * 带插入对象 * @param arr * key值的数组,用来规定插入顺序 * @param rowIndex */ public static void writeLineToSheet(HSSFSheet sheet, Map<String, Object> map, String[] arr, int rowIndex) { HSSFRow row = sheet.createRow(rowIndex); Object[] values = new Object[arr.length]; for (int i = 0; i < arr.length; i++) { values[i] = map.get(arr[i]); } writeLineToRow(values, row); } /** * 写入一行数据到sheet表 * * @param sheet * @param arr * String类型的数组 * @param rowIndex * 行下标 */ public static void writeLineToSheet(HSSFSheet sheet, Iterable<Object> arr, int rowIndex) { HSSFRow row = sheet.createRow(rowIndex); writeLineToRow(arr, row); } /** * 写入一行数据到sheet表 * * @param sheet * @param arr * String类型的数组 * @param rowIndex * 行下标 */ public static void writeLineToSheet(HSSFSheet sheet, String[] arr, int rowIndex) { writeLineToSheet(null, sheet, arr, rowIndex, false); } /** * 写入一行数据到sheet表 * * @param wb * 表格 * @param sheet * @param arr * String类型的数组 * @param rowIndex * 行下标 * @param isBOLD * 是否加粗 */ public static void writeLineToSheet(HSSFWorkbook wb, HSSFSheet sheet, String[] arr, int rowIndex, boolean isBOLD) { HSSFRow row = sheet.createRow(rowIndex); HSSFCellStyle style = null; if (isBOLD) { style = wb.createCellStyle(); // 设置这些样式 style.setFillForegroundColor(HSSFColor.GREY_25_PERCENT.index); style.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND); style.setBorderBottom(HSSFCellStyle.BORDER_THIN); style.setBorderLeft(HSSFCellStyle.BORDER_THIN); style.setBorderRight(HSSFCellStyle.BORDER_THIN); style.setBorderTop(HSSFCellStyle.BORDER_THIN); style.setAlignment(HSSFCellStyle.ALIGN_CENTER); // 生成一个字体 HSSFFont font = wb.createFont(); font.setColor(HSSFColor.BLACK.index); font.setFontHeightInPoints((short) 14); font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD); // 把字体应用到当前的样式 style.setFont(font); } writeLineToRow(arr, row, style); } /** * 读取多个数据到sheet * * @param iterable * @param arr * @param statrtIndex * 开始行数的下标,0为第一行 * @throws InvocationTargetException * @throws IllegalArgumentException * @throws IllegalAccessException * @throws NoSuchMethodException * @throws SecurityException * @throws NoSuchFieldException */ public static <T> void writeLinesToSheet(HSSFSheet sheet, Iterable<T> iterable, String[] arr, int statrtIndex) throws NoSuchFieldException, SecurityException, NoSuchMethodException, IllegalAccessException, IllegalArgumentException, InvocationTargetException { for (T t : iterable) { Class<T> clazz = (Class<T>) t.getClass(); writeLineToSheet(sheet, clazz, t, arr, statrtIndex); statrtIndex++; } } /** * 写一组数据到单元格 * * @param obj * @param row * @throws IllegalArgumentException * if columnIndex < 0 or greater than 255, the maximum number of * columns supported by the Excel binary format (.xls) */ public static void writeLineToRow(Object[] obj, HSSFRow row) { for (int i = 0; i < obj.length; i++) { if (null == obj[i]) { row.createCell(i); } else if (Double.class.isInstance(obj[i])) { row.createCell(i).setCellValue((double) obj[i]); } else if (Integer.class.isInstance(obj[i])) { row.createCell(i).setCellValue((int) obj[i]); } else if (Boolean.class.isInstance(obj[i])) { row.createCell(i).setCellValue((boolean) obj[i]); } else if (Date.class.isInstance(obj[i])) { HSSFCell cell = row.createCell(i); HSSFSheet sheet = row.getSheet(); HSSFWorkbook wb = sheet.getWorkbook(); HSSFDataFormat format = wb.createDataFormat(); HSSFCellStyle cellStyle = wb.createCellStyle(); cellStyle.setDataFormat(format.getFormat("yyyy/m/d hh:mm:ss")); cell.setCellStyle(cellStyle); cell.setCellValue((Date) obj[i]); } else if (Calendar.class.isInstance(obj[i])) { row.createCell(i).setCellValue((Calendar) obj[i]); } else if (String.class.isInstance(obj[i])) { row.createCell(i).setCellValue((String) obj[i]); } else { row.createCell(i).setCellValue(obj[i].toString()); } } } /** * @param arr * @param row * @throws IllegalArgumentException * if columnIndex < 0 or greater than 255, the maximum number of * columns supported by the Excel binary format (.xls) */ public static void writeLineToRow(String[] arr, HSSFRow row, HSSFCellStyle style) { for (int i = 0; i < arr.length; i++) { HSSFRichTextString richString = new HSSFRichTextString(arr[i]); HSSFCell cell = row.createCell(i); if (style != null) { cell.setCellStyle(style); } cell.setCellValue(richString); } } /** * 校验excel表头是不是和传入数组相同(顺序必须也一样) * * @param arr * @return */ public static boolean validOrder(String[] arr, HSSFSheet sheet) { return validOrder(arr, sheet, 0); } public static void writeLineToRow(Iterable<Object> obj, HSSFRow row) { int i = 0; for (Object object : obj) { if (Double.class.isInstance(object)) { row.createCell(i).setCellValue((double) object); } else if (Integer.class.isInstance(object)) { row.createCell(i).setCellValue((int) object); } else if (Boolean.class.isInstance(object)) { row.createCell(i).setCellValue((boolean) object); } else if (Date.class.isInstance(object)) { HSSFCell cell = row.createCell(i); HSSFWorkbook wb = row.getSheet().getWorkbook(); HSSFDataFormat format = wb.createDataFormat(); HSSFCellStyle cellStyle = wb.createCellStyle(); cellStyle.setDataFormat(format.getFormat("yyyy/m/d hh:mm:ss")); cell.setCellStyle(cellStyle); cell.setCellValue((Date) object); } else if (Calendar.class.isInstance(object)) { row.createCell(i).setCellValue((Calendar) object); } else if (String.class.isInstance(object)) { row.createCell(i).setCellValue((String) object); } else { row.createCell(i).setCellValue(object.toString()); } i++; } } /** * 校验excel表头是不是和传入数组相同(顺序必须也一样) * * @param arr * @return */ public static boolean validOrder(String[] arr, HSSFSheet sheet, int rowIndex) { boolean re = true; HSSFRow row = sheet.getRow(rowIndex); int lastNum = row.getLastCellNum(); if (lastNum != arr.length) { re = false; return re; } if (null != row) { for (int k = 0; k < row.getLastCellNum(); k++) { HSSFCell cell = row.getCell(k); String val = getCellValue(cell); if (!arr[k].equals(val)) { re = false; break; } } } return re; } /** * 读取excel到实体类,默认从第一个sheet开始读取 * * @param is * excel输入流 * @param colunms * excel的字段对应的实体类的属性名称,以excel顺序传入 * @param classType * @param fromRow * 从第几行开始读取 * @return * @throws InstantiationException * @throws IllegalAccessException * @throws NoSuchMethodException * @throws SecurityException * @throws NoSuchFieldException * @throws IllegalArgumentException * @throws InvocationTargetException * @throws ParseException * @throws IOException */ public static <T> List<T> readInputStreamToEntity(InputStream is, String[] colunms, Class<T> classType, int fromRow) throws InstantiationException, IllegalAccessException, NoSuchMethodException, SecurityException, NoSuchFieldException, IllegalArgumentException, InvocationTargetException, ParseException, IOException { HSSFWorkbook wbs = new HSSFWorkbook(is); return readHSSFWorkbookToEntity(wbs, colunms, classType, fromRow); } public static <T> List<T> readHSSFWorkbookToEntity(HSSFWorkbook wbs, String[] colunms, Class<T> classType, int fromRow) throws InstantiationException, IllegalAccessException, NoSuchMethodException, SecurityException, NoSuchFieldException, IllegalArgumentException, InvocationTargetException, ParseException, IOException { HSSFSheet childSheet = wbs.getSheetAt(0); return readSheetToEntity(childSheet, colunms, classType, fromRow); } public static <T> List<T> readSheetToEntity(HSSFSheet childSheet, String[] colunms, Class<T> classType, int fromRow) throws InstantiationException, IllegalAccessException, NoSuchMethodException, SecurityException, NoSuchFieldException, IllegalArgumentException, InvocationTargetException, ParseException, IOException { List<T> list = new ArrayList<T>(); for (int j = fromRow; j <= childSheet.getLastRowNum(); j++) { T obj = classType.newInstance(); HSSFRow row = childSheet.getRow(j); if (null != row) { for (int k = 0; k < colunms.length; k++) { HSSFCell cell = row.getCell(k); String val = getCellValue(cell); setFieldValue(colunms[k], classType, obj, val); } } list.add(obj); } return list; } /** * @param file * excel类型的文件 * @param colunms * @param classType * @param fromRow * @return * @throws InstantiationException * @throws IllegalAccessException * @throws NoSuchMethodException * @throws SecurityException * @throws NoSuchFieldException * @throws IllegalArgumentException * @throws InvocationTargetException * @throws ParseException * @throws IOException */ public static <T> List<T> readExcelToEntity(File file, String[] colunms, Class<T> classType, int fromRow) throws InstantiationException, IllegalAccessException, NoSuchMethodException, SecurityException, NoSuchFieldException, IllegalArgumentException, InvocationTargetException, ParseException, IOException { if (!file.getName().endsWith(".xls")) { throw new IllegalArgumentException("文件格式不正确"); } FileInputStream is = new FileInputStream(file); return readInputStreamToEntity(is, colunms, classType, fromRow); } /** * 更改obj对应的属性值,目前支持几个常用基本的属性类型 * * @param filedName * @param type * @param obj * @param val * @throws NoSuchMethodException * @throws SecurityException * @throws NoSuchFieldException * @throws IllegalAccessException * @throws IllegalArgumentException * @throws InvocationTargetException * @throws ParseException * @throws InstantiationException */ private static void setFieldValue(String filedName, Class<?> type, Object obj, String val) throws NoSuchMethodException, SecurityException, NoSuchFieldException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, ParseException, InstantiationException { Field field = type.getDeclaredField(filedName); String fistletter = filedName.substring(0, 1).toUpperCase(); String setMethodName = "set" + fistletter + filedName.substring(1); Method setMethod = type.getDeclaredMethod(setMethodName, new Class[]{field.getType()}); if (field.getType().isAssignableFrom(String.class)) { setMethod.invoke(obj, val); } else if (field.getType().isAssignableFrom(int.class)) { setMethod.invoke(obj, parseInt(val)); } else if (field.getType().isAssignableFrom(double.class)) { setMethod.invoke(obj, parseDouble(val)); } else if (field.getType().isAssignableFrom(Date.class)) { setMethod.invoke(obj, parseDate(val, "yyyy-MM-dd HH:mm:ss")); } else if (field.getType().isAssignableFrom(boolean.class)) { setMethod.invoke(obj, parseBoolean(val)); } else { setMethod.invoke(obj, new Object[]{field.getType().getConstructor(String.class) .newInstance(val)}); } } /** * 返回String类型的cell值 * * @param cell * @return */ private static String getCellValue(HSSFCell cell) { String value = ""; if (null != cell) { switch (cell.getCellType()) { case HSSFCell.CELL_TYPE_NUMERIC : // 数字 if (HSSFDateUtil.isCellDateFormatted(cell)) { value = (new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")) .format(cell.getDateCellValue()); } else { value = String.valueOf(cell.getNumericCellValue()); } break; case HSSFCell.CELL_TYPE_STRING : // 字符串 value = cell.getStringCellValue().trim(); break; case HSSFCell.CELL_TYPE_BOOLEAN : // Boolean value = String.valueOf(cell.getBooleanCellValue()); break; case HSSFCell.CELL_TYPE_BLANK : // 空值 // System.out.println("null_"); break; case HSSFCell.CELL_TYPE_ERROR : // 故障 System.out.println("error_"); break; default : System.out.print("未知类型 "); break; } return value; } else { return ""; } } private static int parseInt(String str) { str = str.trim(); if (str.equals("")) { return 0; } Double d = new Double(str); Long lnum = Math.round(d); return lnum.intValue(); } private static double parseDouble(String str) { str = str.trim(); if (str.equals("")) { return 0; } Double d = new Double(str); return d; } private static boolean parseBoolean(String str) { str = str.trim(); if (str.equals("")) { return false; } Boolean d = new Boolean(str); return d; } private static Date parseDate(String str, String format) throws ParseException { if (str == null || str.trim().equals("")) { return null; } SimpleDateFormat simpFormat = new SimpleDateFormat(format); Date date = null; try { date = simpFormat.parse(str); } catch (Exception e) { simpFormat = new SimpleDateFormat("yyyy-MM-dd"); try { date = simpFormat.parse(str); } catch (ParseException e1) { simpFormat = new SimpleDateFormat("yyyy/MM/dd"); try { date = simpFormat.parse(str); } catch (ParseException e2) { simpFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm"); try { date = simpFormat.parse(str); } catch (ParseException e3) { simpFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss"); date = simpFormat.parse(str); } } } } return date; } private static String toUpFirst(String str) { char[] arr = str.toCharArray(); if (97 <= arr[0] && 122 >= arr[0]) { arr[0] -= 32; return String.valueOf(arr); } else { return str; } } }