您的位置:首页 > 其它

POI工具类 2016-12-09日项目中再次更新

2016-12-09 17:33 330 查看
package com.rufengda.tms.biz.util.poiexcel;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

/**
* 通过新家class类一样,在选择新家的时候
* 选择新建@Annotation 即可
* 当新建的Annotation之后需要进行策略注解
* @Retention(RetentionPolicy.RUNTIME)
* @Retention指明其策略
* RetentionPolicy.RUNTIME 指明其策略是 运行时策略
* @author wanghaiyang
* @verion time 2015/12/28 15:00:00
* */
@Retention(RetentionPolicy.RUNTIME)
public @interface ExcelResources {
//声明策略的值
String title();
//声明一个order值,并且其默认值为9999
int order() default 9999;
}
package com.rufengda.tms.biz.util.poiexcel;/*** 此类主要用于获取User中 Annotation 中的 title,order* @author wanghaiyang* @version 2015/12/28 16:38**/public class ExcelHeader implements Comparable<ExcelHeader> {private String tilte;private int order;private String methodName;public ExcelHeader() {// TODO Auto-generated constructor stub}public ExcelHeader(String tilte, int order, String methodName) {super();this.tilte = tilte;this.order = order;this.methodName = methodName;}public String getTilte() {return tilte;}public void setTilte(String tilte) {this.tilte = tilte;}public int getOrder() {return order;}public void setOrder(int order) {this.order = order;}public String getMethodName() {return methodName;}public void setMethodName(String methodName) {this.methodName = methodName;}/*** 用于对ExcelHeader进行排序* */public int compareTo(ExcelHeader o) {return this.order > o.order ? 1 : (this.order < o.order ? -1 : 0);}@Overridepublic String toString() {return "ExcelHeader [tilte=" + tilte + ", order=" + order+ ", methodName=" + methodName + "]";}}
package com.rufengda.tms.biz.util.poiexcel;import java.io.File;import java.io.FileNotFoundException;import java.io.FileOutputStream;import java.io.IOException;import java.io.OutputStream;import java.util.HashMap;import java.util.Map;import javax.management.RuntimeErrorException;import org.apache.commons.lang3.StringUtils;import org.apache.poi.openxml4j.exceptions.InvalidFormatException;import org.apache.poi.ss.usermodel.Cell;import org.apache.poi.ss.usermodel.CellStyle;import org.apache.poi.ss.usermodel.Row;import org.apache.poi.ss.usermodel.Sheet;import org.apache.poi.ss.usermodel.Workbook;import org.apache.poi.ss.usermodel.WorkbookFactory;/**** @author wanghaiyang* @version 2015/12/28 16:38**///创建Excel模版类,用于来加载模版Excel表@SuppressWarnings("unused")public class ExcelTemplate {// 创建模版标示符private static final String DATA_LINE = "datas";//excel样式标示符private static final String DEFAULT_STYLE="defaultStyles";private static final String STYLE="styles";//样式容器、用于装载第几列所在的样式private Map<Integer, CellStyle> styles;// 声明Wrokbookprivate Workbook workbook;//声明sheet表格private Sheet sheet;//声明rowprivate Row currRow;//声明最后一行数据private int lastRowIndex;//初始化行的下标private int initRowIndex;//初始化列的下标private int initCollIndex;//当前行的下标private int currRowIndex;//当前列的下标private int currCollIndex;//excel默认样式private CellStyle defaultStyle;//设置默认行高样式private float rowHeight;//用于记录sernums序列号列列的坐标private int colSernums;// single模式private static ExcelTemplate excelTemplate = new ExcelTemplate();private ExcelTemplate() {}public static ExcelTemplate getInstance() {return excelTemplate;}/** 第一步、读取相应模版文档,该方法通过classpath方式读取模版*/public void readExcelTemplateByClassPath(String path) {try {workbook = WorkbookFactory.create(ExcelTemplate.class.getResourceAsStream(path));//初始化模版initTemplate();} catch (InvalidFormatException e) {e.printStackTrace();throw new RuntimeException("Excel模版格式不正确!");} catch (IOException e) {e.printStackTrace();throw new RuntimeException("Excel模版不存在!");}}/**第二种读取模版方式、通过path来继续读取*/public void readExcelTemplateByPath(String path) {try {workbook = WorkbookFactory.create(new File(path));//初始化模版initTemplate();sheet.setDefaultColumnWidth(20);//创建行createNewRow();} catch (InvalidFormatException e) {e.printStackTrace();throw new RuntimeException("Excel模版格式不正确!");} catch (IOException e) {e.printStackTrace();throw new RuntimeException("Excel模版不存在!");}}//初始化模版private void initTemplate(){//得到模版中第一个sheet表格sheet=workbook.getSheetAt(0);//初始化配置信息initConfigData();//获取最后一行的数据坐标lastRowIndex=sheet.getLastRowNum();//初始化完成,创建一行//currRow=sheet.getRow(currRowIndex);//createNewRow();}//初始化模版中的数据信息找到标识符的坐标private void initConfigData() {boolean isFind=false;boolean isFindSernums=false;for (Row row : sheet) {//如果找到对应的数据就结束if(isFind) break;for (Cell cell : row) {//如果当前行的数据类型不是字符串类型就继续,因为我们在excel模版中设置的是datas是字符串类型if(cell.getCellType()!=Cell.CELL_TYPE_STRING) continue;//获取到当前单元格的值String cellValue=cell.getStringCellValue().trim();//找序列号的标示符sernumsif(cellValue.equals("sernums")){colSernums=cell.getColumnIndex();isFindSernums=true;}if(cellValue.equals("datas")){//获取当前单元格行的坐标initRowIndex=cell.getRowIndex();//获取当前单元格列的坐标initCollIndex=cell.getColumnIndex();currRowIndex=initRowIndex;currCollIndex=initCollIndex;//获取默认行高rowHeight=row.getHeightInPoints();//初始化模版样式initStyles();isFind=true;break;}}}//最后检查一下在初始化数据的时候有没有找到,如果没找到就初始化序列号initSernums();}//将模版样式初始化数据加载到styles容器中private void initStyles() {//初始化样式容器styles= new HashMap<Integer, CellStyle>();for (Row row : sheet) {for (Cell cell : row) {if(cell.getCellType()!=Cell.CELL_TYPE_STRING) continue;String cellValue=cell.getStringCellValue().trim();//如果当前列的值等于defaultstyles设置成默认样式if(DEFAULT_STYLE.equals(cellValue)){defaultStyle=cell.getCellStyle();}if(STYLE.equals(cellValue)){styles.put(cell.getColumnIndex(), cell.getCellStyle());}}}}//初始化模版sernums序列号的坐标private void initSernums() {for (Row row : sheet) {for (Cell cell : row) {//如果当前行的数据类型不是字符串类型就继续,因为我们在excel模版中设置的是sernums是字符串类型if(cell.getCellType()!=Cell.CELL_TYPE_STRING) continue;//获取到当前单元格的值String cellValue=cell.getStringCellValue().trim();if(cellValue.equals("sernums")){//获取到序列号sernums的坐标colSernums=cell.getColumnIndex();}}}}//用于替换一些常量固定的值public void replaceConstant(Map<String, String> datas){//数据常量如果为空就不进行替换if(null==datas) return;for (Row row : sheet) {for (Cell cell : row) {String cellValue=cell.getStringCellValue().trim();//如果当前模版中式#开头就是我们所需要替换的常量if (cellValue.startsWith("#")) {//如果datas数据中包含有我们的值就进行常量设置String key = cellValue.substring(1);if (datas.containsKey(key)) {cell.setCellValue(datas.get(key));}}}}}//创建行public void createNewRow() {if(lastRowIndex>=currRowIndex && currRowIndex>initRowIndex){//移动下一行sheet.shiftRows(currRowIndex, lastRowIndex, 1, true, true);lastRowIndex++;}currRow=sheet.createRow(currRowIndex);//设置行高currRow.setHeightInPoints(rowHeight);//下一行currRowIndex++;//当创建到下一行的单元格的列就应该是初始化的列的坐标currCollIndex=initCollIndex;}//创建列,并为当前单元格赋值public void createCell(String cellValue){Cell cell=currRow.createCell(currCollIndex);cell.setCellValue(cellValue);if (null!=styles && styles.size()>0)setCellStyle(cell);//到下一个单元格currCollIndex++;}//插入序列号public void insertSernums(){int index=1;Row row=null;Cell cell= null;for (int i = initRowIndex; i < currRowIndex; i++) {//得到当前行row=sheet.getRow(i);cell=row.createCell(colSernums);setCellStyle(cell);cell.setCellValue(index++);}}//设置样式public void setCellStyle(Cell cell){//设置的时候将样式添加进去cell.setCellStyle(styles.containsKey(currCollIndex)?styles.get(currCollIndex):defaultStyle);}//将数据到处到Excel中public void writeFilePath(String filePath){FileOutputStream fos=null;try {fos= new FileOutputStream(new File(filePath));workbook.write(fos);} catch (FileNotFoundException e) {// TODO Auto-generated catch blocke.printStackTrace();throw new RuntimeException("写入的文件不存在!");} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();throw new RuntimeException("写入流失败!");}finally{try {fos.close();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}public void writeStream(OutputStream os){try {workbook.write(os);} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();throw new RuntimeException("写入流失败!");}finally{try {os.close();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}}
package com.rufengda.tms.biz.util.poiexcel;import java.io.File;import java.io.FileNotFoundException;import java.io.FileOutputStream;import java.io.IOException;import java.io.OutputStream;import java.lang.reflect.Field;import java.lang.reflect.InvocationTargetException;import java.lang.reflect.Method;import java.sql.Timestamp;import java.text.MessageFormat;import java.util.ArrayList;import java.util.Collections;import java.util.Date;import java.util.HashMap;import java.util.List;import java.util.Map;import org.apache.commons.beanutils.BeanUtils;import org.apache.poi.hssf.usermodel.HSSFCellStyle;import org.apache.poi.hssf.usermodel.HSSFWorkbook;import org.apache.poi.openxml4j.exceptions.InvalidFormatException;import org.apache.poi.ss.usermodel.Cell;import org.apache.poi.ss.usermodel.CellStyle;import org.apache.poi.ss.usermodel.DataFormat;import org.apache.poi.ss.usermodel.Row;import org.apache.poi.ss.usermodel.Sheet;import org.apache.poi.ss.usermodel.Workbook;import org.apache.poi.ss.usermodel.WorkbookFactory;import org.apache.poi.xssf.usermodel.XSSFWorkbook;/**** @author wanghaiyang* @version 2015/12/28 16:38**/public class ExcelUtil {private static ExcelUtil excelUtil = new ExcelUtil();private ExcelUtil() {};public static ExcelUtil getInstance() {return excelUtil;}/**通过excel模版的方式,将数据对象导入到Excel中* @param template :excel的模板* @param outPath:文件输出路径 输出到那里* @param objs:数据列表、用于要输出的数据对象* @param constantMap:用于输出一些特殊的一些常量 如#tiltle=标题* @param clz:导入那个,其通过反射机制实现* @param isclassPath:是否通过classpath的加载方式进行加载excel模版* */@SuppressWarnings("rawtypes")public void exportObjToExcelByTemplate(String template,String outPath,List objs,Map constantMap,Class clz,boolean isclassPath){ExcelTemplate excelTemplate=HanderExcelByTemplate(template, objs, constantMap, clz, isclassPath);excelTemplate.writeFilePath(outPath);}/**通过excel模版的方式,将数据对象导入到Excel中* @param template :excel的模板* @param os:通过输出流* @param objs:数据列表、用于要输出的数据对象* @param constantMap:用于输出一些特殊的一些常量 如#tiltle=标题* @param clz:导入那个,其通过反射机制实现* @param isclassPath:是否通过classpath的加载方式进行加载excel模版* */@SuppressWarnings("rawtypes")public void exportObjToExcelByTemplate(String template,OutputStream os,List objs,Map constantMap,Class clz,boolean isclassPath){ExcelTemplate excelTemplate=HanderExcelByTemplate(template, objs, constantMap, clz, isclassPath);excelTemplate.writeStream(os);}/**不通过excel模版的方式,直接将数据对象导入到Excel中* @param  :excel的模板* @param outPath:文件输出路径 输出到那里* @param objs:数据列表、用于要输出的数据对象* @param :用于输出一些特殊的一些常量 如#tiltle=标题* @param clz:导入那个,其通过反射机制实现* @param isXssF:true=2007excel,false=2003excel* */@SuppressWarnings("rawtypes")public void exportObjToExcel(String outPath,List objs,Class clz,boolean isXssF){FileOutputStream fos=null;try {fos= new FileOutputStream(new File(outPath));Workbook workbook=HanderExcel(objs, clz, isXssF);workbook.write(fos);} catch (FileNotFoundException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (NoSuchMethodException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (SecurityException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (IllegalAccessException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (IllegalArgumentException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (InvocationTargetException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}finally{try {fos.close();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}/**不通过excel模版的方式,直接将数据对象导入到Excel中* @param  :excel的模板* @param os:输出流* @param objs:数据列表、用于要输出的数据对象* @param :用于输出一些特殊的一些常量 如#tiltle=标题* @param clz:导入那个,其通过反射机制实现* @param isXssF:true=2007excel,false=2003excel* */@SuppressWarnings("rawtypes")public void exportObjToExcel(OutputStream os,List objs,Class clz,boolean isXssF){try {Workbook workbook=HanderExcel(objs, clz, isXssF);workbook.write(os);} catch (FileNotFoundException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (NoSuchMethodException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (SecurityException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (IllegalAccessException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (IllegalArgumentException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (InvocationTargetException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}/**不通过excel模版的方式,直接将数据对象导入到Excel中* @param  :excel的模板* @param os:输出流* @param objs:数据列表、用于要输出的数据对象* @param :用于输出一些特殊的一些常量 如#tiltle=标题* @param clz:导入那个,其通过反射机制实现* @param isXssF:true=2007excel,false=2003excel* @author ksea:该方法基于属性注解* */@SuppressWarnings("rawtypes")public void exportObjToExcelByField(OutputStream os,List objs,Class clz,boolean isXssF){try {Workbook workbook=HanderExcelByField(objs, clz, isXssF);workbook.write(os);} catch (FileNotFoundException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (NoSuchMethodException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (SecurityException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (IllegalAccessException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (IllegalArgumentException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (InvocationTargetException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}/**不通过excel模版的方式,直接将数据对象导入到Excel中* @param  :excel的模板* @param os:输出流* @param objs:数据列表、用于要输出的数据对象* @param sheetTitleMap:sheet名称* @param :用于输出一些特殊的一些常量 如#tiltle=标题* @param :导入那个,其通过反射机制实现* @param isXssF:true=2007excel,false=2003excel* desc:2016-7-22日项目实际中需求,批量导出,数据列与明细* */@SuppressWarnings("rawtypes")public void exportObjToExcel(OutputStream os,Map<Integer, List> objs,Map<Integer, Object> sheetTitleMap,Map<Integer, Class> classMap,boolean isXssF){try {Workbook workbook=HanderExcel(objs,sheetTitleMap,classMap, isXssF);workbook.write(os);} catch (FileNotFoundException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (NoSuchMethodException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (SecurityException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (IllegalAccessException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (IllegalArgumentException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (InvocationTargetException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}/**通过excel模版的方式,来处理excel,该方法需要提供Excel的模版,并进行在excel中添加模版标识符* @param template :excel的模板* @param objs:数据列表、用于要输出的数据对象* @param constantMap:用于输出一些特殊的一些常量 如#tiltle=标题* @param clz:导入那个,其通过反射机制实现* @param isclassPath:是否通过classpath的加载方式进行加载excel模版* */@SuppressWarnings({ "rawtypes", "unchecked" })private ExcelTemplate HanderExcelByTemplate(String template,List objs,Map constantMap,Class clz,boolean isclassPath){//读取模版ExcelTemplate excelTemplate= ExcelTemplate.getInstance();if(isclassPath){//通过classpath方式读取模版excelTemplate.readExcelTemplateByClassPath(template);}else{//通过path方式读取模版excelTemplate.readExcelTemplateByPath(template);}List<ExcelHeader> headers=getExcelHeader(clz);//对list进行排序Collections.sort(headers);//将其标题项写入到excel中:用户标识、用户名称、用户昵称、用户年龄//创建一行//excelTemplate.createNewRow();//将标题插入到当前行中for (ExcelHeader excelHeader : headers) {excelTemplate.createCell(excelHeader.getTilte());}//开始写入对应数据,ExcelHeader是排序的,因此根据ExcelHeader进行插入//这里插入是通过反射机制进行if(null!=objs && objs.size()>0){for ( Object obj : objs) {//首先创建一行excelTemplate.createNewRow();for (ExcelHeader excelHeader : headers) {try {//通过之前保存在excelHeader中的get方法得到相对应的方法Method method=clz.getMethod(excelHeader.getMethodName());//获取返货类型String returnName=method.getReturnType().getName();//如果这里是时间类型进行时间格式化if (returnName.equals("java.util.Date") ||returnName.equals("java.sql.Date") ||returnName.equals("java.sql.Timestamp")){//通过反射得到对象对应的值Object returnValue=method.invoke(obj);excelTemplate.createCell(String.valueOf(returnValue==null?"": MessageFormat.format("{0,date,yyyy-MM-dd HH:mm:ss}",returnValue)));}else{//通过反射得到对象对应的值Object returnValue=method.invoke(obj);excelTemplate.createCell(String.valueOf(returnValue==null?"":returnValue));}} catch (NoSuchMethodException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (SecurityException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (IllegalAccessException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (IllegalArgumentException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (InvocationTargetException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}}//用于替换一些特殊常量字符if(null!=constantMap && constantMap.size()>0)excelTemplate.replaceConstant(constantMap);return excelTemplate;}/***  HanderExcel该方法不通过加载模版的方式,而是直接将对象数据数据写入到excel* @param objs 要写入的对象集合* @param clz 写入的对象*  isXssF判定是否是2003excel还是2007excel* @throws SecurityException* @throws NoSuchMethodException* @throws InvocationTargetException* @throws IllegalArgumentException* @throws IllegalAccessException** */@SuppressWarnings({ "rawtypes", "unchecked" })private Workbook HanderExcel(List objs,Class clz,boolean isXssF) throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException{Workbook workbook=null;if(isXssF){//创建2007excel后缀是.xlsxworkbook= new XSSFWorkbook();}else{//创建2003excel后缀是.xlsworkbook=new HSSFWorkbook();}//创建sheetSheet sheet=workbook.createSheet();//设置默认列宽度与高度sheet.setDefaultColumnWidth(20);//sheet.setDefaultRowHeight(Short.parseShort("5"));//得到第一行,在excel中第一行第一列的坐标是(0,0)Row row= sheet.createRow(0);//获取传入数据的标题,其就是annotationList<ExcelHeader> excelHeaders=getExcelHeader(clz);//对头部数据进行排序Collections.sort(excelHeaders);//将表头插入到第一行for (int i=0;i<excelHeaders.size();i++) {Cell cell=row.createCell(i);cell.setCellValue(excelHeaders.get(i).getTilte());}//数据不为空的时候执行if(null!=objs && objs.size()>0){/*** 设置时间类型样式,该样式创建不能放在循环中,否则会报异常* java.lang.IllegalStateException: The maximum number of cell styles was exceeded. You can define up to 4000 styles in a .xls workbook*/CellStyle cellStyle= workbook.createCellStyle();DataFormat format=workbook.createDataFormat();cellStyle.setDataFormat(format.getFormat("yyyy-MM-dd HH:mm:ss"));//插入对象数据for (int i = 0; i < objs.size(); i++) {Object obj=objs.get(i);//新建一行Row dataRow=sheet.createRow(i+1);for (int j = 0; j < excelHeaders.size(); j++) {ExcelHeader e=excelHeaders.get(j);//得到对应的get方法Method method=clz.getMethod(e.getMethodName());try {Object objectName=method.getReturnType().getName();String value=String.valueOf(method.invoke(obj));//将对应的值插入进去if(objectName.equals("java.sql.Timestamp")|| objectName.equals("java.sql.Date") || objectName.equals("java.util.Date")){Cell cell=dataRow.createCell(j);if(value==null||value.equals("null")){cell.setCellValue("");}else{Object dateValue=method.invoke(obj);if(objectName.equals("java.sql.Timestamp"))cell.setCellValue((java.sql.Timestamp)dateValue);else if(objectName.equals("java.sql.Date"))cell.setCellValue((java.sql.Date)dateValue);else if(objectName.equals("java.util.Date"))cell.setCellValue((java.util.Date)dateValue);cell.setCellStyle(cellStyle);}}else{dataRow.createCell(j).setCellValue(value==null||value.equals("null")?"":value);}} catch (Exception e1) {// TODO Auto-generated catch blocke1.printStackTrace();}}}}return	workbook;}/***  HanderExcel该方法不通过加载模版的方式,而是直接将对象数据数据写入到excel* @param objs 要写入的对象集合* @param clz 写入的对象* isXssF判定是否是2003excel还是2007excel* @throws SecurityException* @throws NoSuchMethodException* @throws InvocationTargetException* @throws IllegalArgumentException* @throws IllegalAccessException* @author ksea:该方法基于注解* */@SuppressWarnings({ "rawtypes", "unchecked" })private Workbook HanderExcelByField(List objs,Class clz,boolean isXssF) throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException{Workbook workbook=null;if(isXssF){//创建2007excel后缀是.xlsxworkbook= new XSSFWorkbook();}else{//创建2003excel后缀是.xlsworkbook=new HSSFWorkbook();}//创建sheetSheet sheet=workbook.createSheet();//得到第一行,在excel中第一行第一列的坐标是(0,0)Row row= sheet.createRow(0);//获取传入数据的标题,其就是annotationList<ExcelHeader> excelHeaders=getExcelHeaderByField(clz);//对头部数据进行排序Collections.sort(excelHeaders);//将表头插入到第一行for (int i=0;i<excelHeaders.size();i++) {Cell cell=row.createCell(i);cell.setCellValue(excelHeaders.get(i).getTilte());}//数据不为空的时候执行if(null!=objs && objs.size()>0){/*** 设置时间类型样式,该样式创建不能放在循环中,否则会报异常* java.lang.IllegalStateException: The maximum number of cell styles was exceeded. You can define up to 4000 styles in a .xls workbook*/CellStyle cellStyle= workbook.createCellStyle();DataFormat format=workbook.createDataFormat();cellStyle.setDataFormat(format.getFormat("yyyy-MM-dd HH:mm:ss"));//插入对象数据for (int i = 0; i < objs.size(); i++) {Object obj=objs.get(i);//新建一行Row dataRow=sheet.createRow(i+1);for (int j = 0; j < excelHeaders.size(); j++) {ExcelHeader e=excelHeaders.get(j);//得到对应的get方法Method method=clz.getMethod(e.getMethodName());try {Object objectName=method.getReturnType().getName();String value=String.valueOf(method.invoke(obj));//将对应的值插入进去if(objectName.equals("java.sql.Timestamp")|| objectName.equals("java.sql.Date") || objectName.equals("java.util.Date")){Cell cell=dataRow.createCell(j);if(value==null||value.equals("null")){cell.setCellValue("");}else{Object dateValue=method.invoke(obj);if(objectName.equals("java.sql.Timestamp"))cell.setCellValue((java.sql.Timestamp)dateValue);else if(objectName.equals("java.sql.Date"))cell.setCellValue((java.sql.Date)dateValue);else if(objectName.equals("java.util.Date"))cell.setCellValue((java.util.Date)dateValue);cell.setCellStyle(cellStyle);}}else{dataRow.createCell(j).setCellValue(value==null||value.equals("null")?"":value);}} catch (Exception e1) {// TODO Auto-generated catch blocke1.printStackTrace();}}}}return	workbook;}/***  HanderExcel该方法不通过加载模版的方式,而是直接将对象数据数据写入到excel*  objs 要写入的对象集合*  clz 写入的对象*  isXssF判定是否是2003excel还是2007excel* @throws SecurityException* @throws NoSuchMethodException* @throws InvocationTargetException* @throws IllegalArgumentException* @throws IllegalAccessException* desc:2016-7-22日项目中实际需求扩展导出数据列表与明细* 特别说明:Map<String, Object> objs,Map<String, Object> sheetTitleMap,Map<String, Class> clzs三个map的key必须保持一致*        后台处理是根据map的key来进行设置值,因此每个对象的key必须一直,并且key一定是,1,2,3之类的key* */@SuppressWarnings({ "rawtypes", "unchecked" })private Workbook HanderExcel(Map<Integer,  List> objMap,Map<Integer, Object> sheetTitleMap,Map<Integer, Class> classMap,boolean isXssF) throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException{Workbook workbook=null;if(isXssF){//创建2007excel后缀是.xlsxworkbook= new XSSFWorkbook();}else{//创建2003excel后缀是.xlsworkbook=new HSSFWorkbook();}if(null!=sheetTitleMap && sheetTitleMap.size()>0){for (Integer key : sheetTitleMap.keySet()) {//创建sheet并设置对应的sheet名称Sheet sheet=workbook.createSheet();workbook.setSheetName(key, String.valueOf(sheetTitleMap.get(key)));//得到第一行,在excel中第一行第一列的坐标是(0,0)Row row= sheet.createRow(0);//获取传入数据的标题,其就是annotationList<ExcelHeader> excelHeaders=getExcelHeaderByField(classMap.get(key));//对头部数据进行排序Collections.sort(excelHeaders);//将表头插入到第一行for (int i=0;i<excelHeaders.size();i++) {Cell cell=row.createCell(i);cell.setCellValue(excelHeaders.get(i).getTilte());}//数据不为空的时候执行List list=objMap.get(key);if(null!=list && list.size()>0){/*** 设置时间类型样式,该样式创建不能放在循环中,否则会报异常* java.lang.IllegalStateException: The maximum number of cell styles was exceeded. You can define up to 4000 styles in a .xls workbook*/CellStyle cellStyle= workbook.createCellStyle();DataFormat format=workbook.createDataFormat();cellStyle.setDataFormat(format.getFormat("yyyy-MM-dd HH:mm:ss"));//插入对象数据for (int i = 0; i < list.size(); i++) {Object obj=list.get(i);//新建一行Row dataRow=sheet.createRow(i+1);for (int j = 0; j < excelHeaders.size(); j++) {ExcelHeader e=excelHeaders.get(j);//得到对应的get方法Method method=classMap.get(key).getMethod(e.getMethodName());try {Object objectName=method.getReturnType().getName();String value=String.valueOf(method.invoke(obj));//将对应的值插入进去if(objectName.equals("java.sql.Timestamp")|| objectName.equals("java.sql.Date") || objectName.equals("java.util.Date")){Cell cell=dataRow.createCell(j);if(value==null||value.equals("null")){cell.setCellValue("");}else{Object dateValue=method.invoke(obj);if(objectName.equals("java.sql.Timestamp"))cell.setCellValue((java.sql.Timestamp)dateValue);else if(objectName.equals("java.sql.Date"))cell.setCellValue((java.sql.Date)dateValue);else if(objectName.equals("java.util.Date"))cell.setCellValue((java.util.Date)dateValue);cell.setCellStyle(cellStyle);}}else{dataRow.createCell(j).setCellValue(value==null||value.equals("null")?"":value);}} catch (Exception e1) {// TODO Auto-generated catch blocke1.printStackTrace();}}}}}}return	workbook;}/**通过反射机制,得到在对应类中的注解,该方法通过注解在get上*/@SuppressWarnings("rawtypes")public List<ExcelHeader> getExcelHeader(Class clz){List<ExcelHeader> headers= new ArrayList<ExcelHeader>();Method[] methods=clz.getDeclaredMethods();for (int i = 0; i < methods.length; i++) {//获取当前方法Method method=methods[i];//获取方法名称、我们所有的注解都是注解在get方法的,因此只需要获取get有关的方法String methodName=method.getName();if(methodName.startsWith("get")){//获取到get方法中对应的注解ExcelResources er=method.getAnnotation(ExcelResources.class);//当一个类中存在有些字段的get未添加annotation 就不进行添加if(er!=null)headers.add(new ExcelHeader(er.title(), er.order(), methodName));}}return headers;}/**通过反射机制,得到在对应类中的注解,该方法通过注解在属性上上*/@SuppressWarnings("rawtypes")public List<ExcelHeader> getExcelHeaderByField(Class clz){List<ExcelHeader> headers= new ArrayList<ExcelHeader>();//Method[] methods=clz.getDeclaredMethods();Field[] fields=clz.getDeclaredFields();for (int i = 0; i < fields.length; i++) {//获取当前属性Field field=fields[i];String methodName=field.getName();methodName="get"+methodName.substring(0, 1).toUpperCase()+methodName.substring(1);//获取到field中对应的注解ExcelResources er=field.getAnnotation(ExcelResources.class);//当一个类中存在有些字段的get未添加annotation 就不进行添加if(er!=null)headers.add(new ExcelHeader(er.title(), er.order(),methodName));}return headers;}//-------------------------以上是写入excel的方法、以下是将数据从excel中读出来----------@SuppressWarnings("rawtypes")public List<Object> readExcelToObjectByClassPath(String classPath,Class clz,int readLine,int tailLine){Workbook workbook=null;try {workbook=WorkbookFactory.create(ExcelUtil.class.getResourceAsStream(classPath));return handlerExcelToObject(workbook, clz, readLine,tailLine);} catch (InvalidFormatException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}return null;}@SuppressWarnings("rawtypes")public List<Object> readExcelToObjectByPath(String path,Class clz,int readLine,int tailLine){Workbook workbook=null;try {workbook=WorkbookFactory.create(new File(path));return  handlerExcelToObject(workbook, clz, readLine,tailLine);} catch (InvalidFormatException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}return null;}@SuppressWarnings("rawtypes")public List<Object> readExcelToObjectByClassPath(String classPath,Class clz){return	readExcelToObjectByClassPath(classPath, clz, 0,0);}/**** 该方法默认从0行开始读取数据* @param path* @param clz*/@SuppressWarnings("rawtypes")public List<Object> readExcelToObjectByPath(String path,Class clz){return	readExcelToObjectByPath(path, clz, 0,0);}/*** desc:该方法用于处理excel、读取excel中的数据并将转换成clz对应的类* @param workbook* @param clz* @param readLine 从第几行开始读取* @param tailLine 尾部有几行不需要读取*/@SuppressWarnings("rawtypes")private List<Object> handlerExcelToObject(Workbook workbook,Class clz,int readLine,int tailLine){List<Object> objects= new ArrayList<Object>();try {Sheet sheet=workbook.getSheetAt(0);Row row=sheet.getRow(readLine);Map<Integer,String> maps=getExcelHeaderMap(row, clz);/**** i = readLine+1说明、第一行读取的时标题行、因此读取数据应从标题的下一行开始 readLine+1* sheet.getLastRowNum()-tailLine 说明:总共需要读取的行数-不需要读取的行数=需要读取的行数*/for (int i = readLine+1; i <sheet.getLastRowNum()-tailLine; i++) {//实例化对应的对象Object obj=	clz.newInstance();//得到当前行Row currRow=sheet.getRow(i);//循环当前行所有列的数据for (Cell cell : currRow) {//当前列的坐标int currColIndex=cell.getColumnIndex();//得到当前列对应的方法名称String methodName= maps.get(currColIndex);/*** 此处用java反射机制进行方法的反射,由于如果对象有int,date之类的参数,在这里反射就不是特别好用* 因此这里可以在maven配置** <dependency><groupId>commons-beanutils</groupId><artifactId>commons-beanutils</artifactId><version>1.9.2</version></dependency>beanutils的依赖用beantils来进行* *///注意这里如果方法的参数是Integer或者Date或者其他类型需要做判定,而我这里属性全部都定义成String类型的//  Method method=clz.getMethod(methodName, String.class);//通过反射将单元格对应的值、调用对象的setXXX方法实现对数据的添加//method.invoke(obj, cell.getStringCellValue());/***  BeanUtils.copyProperty(obj, methodName, method);*  说明 obj对象*  methodName方法 在beantuils这里只要提供属性名称即可 若 方法名setUserName这里只需要时username** */methodName=methodName.substring(3);methodName=methodName.substring(0,1).toLowerCase()+methodName.substring(1);BeanUtils.copyProperty(obj, methodName, cell.getStringCellValue());}//将添加到集合中去objects.add(obj);}} catch (InstantiationException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (IllegalAccessException e) {// TODO Auto-generated catch blocke.printStackTrace();}  catch (SecurityException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (IllegalArgumentException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (InvocationTargetException e) {// TODO Auto-generated catch blocke.printStackTrace();}return objects;}/***** @param titleRow 标题行* @param clz* @return Map<Integer, String> 对应列所对应的方法*/@SuppressWarnings("rawtypes")private Map<Integer, String> getExcelHeaderMap(Row titleRow,Class clz){//首先获取类上上面所注解的标题List<ExcelHeader> headers=getExcelHeader(clz);//用于存储某一列所对应的方法的值Map<Integer, String> maps= new HashMap<Integer, String>();//根据header列表找到对应的数据列表for (ExcelHeader excelHeader : headers) {for (Cell cell : titleRow) {if(cell.getStringCellValue().trim().equals(excelHeader.getTilte())){//找到当前列所对应的值将存储起来,而这里我们是得到get方法,需要获取set方法,为对象设置maps.put(cell.getColumnIndex(), excelHeader.getMethodName().replace("get", "set"));break;}}}return maps;}}

                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐