数据导入导出工具类

Exception处理

public ExcelException() { 
       // TODO Auto-generated constructor stub 
   } 
 
   public ExcelException(String message) { 
       super(message); 
       // TODO Auto-generated constructor stub 
   } 
 
   public ExcelException(Throwable cause) { 
       super(cause); 
       // TODO Auto-generated constructor stub 
   } 
 
   public ExcelException(String message, Throwable cause) { 
       super(message, cause); 
       // TODO Auto-generated constructor stub 
   }

POI核心处理

* @author     : SUNZK-QQ:1131341075 
* @Date       : 2018-8-23 下午9:13:21 
* @Comments   : 导入导出Excel工具类 
* @Version    : 1.0.0 
*/ 
 
 { 
 
   /** 
    * @MethodName  : listToExcel 
    * @Description : 导出Excel(可以导出到本地文件系统,也可以导出到浏览器,可
 
    * @param list      数据源 
    * @param fieldMap      类的英文属性和Excel中的中文列名的对应关系 
    * 如果需要的是引用对象的属性,则英文属性使用类似于EL表达式的格式 
    * 如:list中存放的都是student,student中又有college属性,而我们需要学院名
 
    * fieldMap.put("college.collegeName","学院名称") 
    * @param sheetName 工作表的名称 
    * @param sheetSize 每个工作表中记录的最大个数 
    * @param out       导出流 
    * @throws ExcelException 
    */ 
   public static <T>  void   listToExcel ( 
           List<T> list , 
           LinkedHashMap<String,String> fieldMap, 
           String sheetName, 
           int sheetSize, 
           OutputStream out 
           ) throws ExcelException{ 
 
 
       if(list.size()==0 || list==null){ 
           throw new ExcelException("数据源中没有任何数据"); 
       } 
 
       if(sheetSize>65535 || sheetSize<1){ 
           sheetSize=65535; 
       } 
 
       //创建工作簿并发送到OutputStream指定的地方 
       WritableWorkbook wwb; 
       try { 
           wwb = Workbook.createWorkbook(out); 
 
           //因为2003的Excel一个工作表最多可以有65536条记录,除去列头剩下
条 
           //所以如果记录太多,需要放到多个工作表中,其实就是个分页的过程 
           //1.计算一共有多少个工作表 
           double sheetNum=Math.ceil(list.size()/new

//2.创建相应的工作表,并向其中填充数据 
           for(int i=0; i<sheetNum; i++){ 
               //如果只有一个工作表的情况 
               if(1==sheetNum){ 
                   WritableSheet sheet=wwb.createSheet(sheetName, i); 
                   fillSheet(sheet, list, fieldMap, 0, list.size()-1); 
 
               //有多个工作表的情况 
               }else{ 
                   WritableSheet sheet=wwb.createSheet(sheetName+(i+1), i); 
 
                   //获取开始索引和结束索引 
                   int firstIndex=i*sheetSize; 
                   int lastIndex=(i+1)*sheetSize-1>list.size()-1 ? list.size()-1 :

//填充工作表 
                   fillSheet(sheet, list, fieldMap, firstIndex, lastIndex); 
               } 
           } 
 
           wwb.write(); 
           wwb.close(); 
 
       }catch (Exception e) { 
           e.printStackTrace(); 
           //如果是ExcelException,则直接抛出 
           if(e instanceof ExcelException){ 
               throw (ExcelException)e; 
 
           //否则将其它异常包装成ExcelException再抛出 
           }else{ 
               throw new ExcelException("导出Excel失败"); 
           } 
       } 
 
   } 
 
   /** 
    * @MethodName  : listToExcel 
    * @Description : 导出Excel(可以导出到本地文件系统,也可以导出到浏览器,工
2003支持的最大值) 
    * @param list      数据源 
    * @param fieldMap      类的英文属性和Excel中的中文列名的对应关系 
    * @param out       导出流 
    * @throws ExcelException 
    */ 
   public static  <T>  void   listToExcel ( 
           List<T> list , 
           LinkedHashMap<String,String> fieldMap, 
           String sheetName, 
           OutputStream out 
           ) throws ExcelException{ 
 
       listToExcel(list, fieldMap, sheetName, 65535, out); 
 
   } 
 
 
   /** 
    * @MethodName  : listToExcel 
    * @Description : 导出Excel(导出到浏览器,可以自定义工作表的大小) 
    * @param list      数据源 
    * @param fieldMap      类的英文属性和Excel中的中文列名的对应关系 
    * @param sheetSize    每个工作表中记录的最大个数 
    * @param response  使用response可以导出到浏览器 
    * @throws ExcelException 
    */ 
   public static  <T>  void   listToExcel ( 
           List<T> list , 
           LinkedHashMap<String,String> fieldMap, 
           String sheetName, 
           int sheetSize, 
           HttpServletResponse response  
           ) throws ExcelException{ 
 
       //设置默认文件名为当前时间:年月日时分秒 
       String fileName=new SimpleDateFormat("yyyyMMddhhmmss").format(new

//设置response头信息 
       response.reset();           
       response.setContentType("application/vnd.ms-excel");        //改成输出excel
 
       response.setHeader("Content-disposition","attachment;

//创建工作簿并发送到浏览器 
       try { 
 
           OutputStream out=response.getOutputStream(); 
           listToExcel(list, fieldMap, sheetName, sheetSize,out ); 
 
       } catch (Exception e) { 
           e.printStackTrace(); 
 
           //如果是ExcelException,则直接抛出 
           if(e instanceof ExcelException){ 
               throw (ExcelException)e; 
 
           //否则将其它异常包装成ExcelException再抛出 
           }else{ 
               throw new ExcelException("导出Excel失败"); 
           } 
       } 
   } 
 
 
   /** 
    * @MethodName  : listToExcel 
    * @Description : 导出Excel(导出到浏览器,工作表的大小是2003支持的最大值) 
    * @param list      数据源 
    * @param fieldMap      类的英文属性和Excel中的中文列名的对应关系 
    * @param response  使用response可以导出到浏览器 
    * @throws ExcelException 
    */ 
   public static <T>  void   listToExcel ( 
           List<T> list , 
           LinkedHashMap<String,String> fieldMap, 
           String sheetName, 
           HttpServletResponse response  
           ) throws ExcelException{ 
 
       listToExcel(list, fieldMap, sheetName, 65535, response); 
   } 
 
   /** 
    * @MethodName          : excelToList 
    * @Description             : 将Excel转化为List 
    * @param in                    :承载着Excel的输入流 
    * @param sheetIndex        :要导入的工作表序号 
    * @param entityClass       :List中对象的类型(Excel中的每一行都要转化为该
 
    * @param fieldMap          :Excel中的中文列头和类的英文属性的对应关系

* @param uniqueFields  :指定业务主键组合(即复合主键),这些列的组合不
 
    * @return                      :List 
    * @throws ExcelException 
    */ 
   public static <T>  List<T>  excelToList( 
           InputStream in, 
           String sheetName, 
           Class<T> entityClass, 
           LinkedHashMap<String, String> fieldMap, 
           String[] uniqueFields 
           ) throws ExcelException{ 
 
       //定义要返回的list 
       List<T> resultList=new ArrayList<T>(); 
 
       try { 
 
           //根据Excel数据源创建WorkBook 
           Workbook wb=Workbook.getWorkbook(in); 
           //获取工作表 
           Sheet sheet=wb.getSheet(sheetName); 
 
           //获取工作表的有效行数 
           int realRows=0; 
           for(int i=0;i<sheet.getRows();i++){ 
 
               int nullCols=0; 
               for(int j=0;j<sheet.getColumns();j++){ 
                   Cell currentCell=sheet.getCell(j,i); 
                   if(currentCell==null ||

nullCols++; 
                   } 
               } 
 
               if(nullCols==sheet.getColumns()){ 
                   break; 
               }else{ 
                   realRows++; 
               } 
           } 
 
 
           //如果Excel中没有数据则提示错误 
           if(realRows<=1){ 
               throw new ExcelException("Excel文件中没有任何数据"); 
           } 
 
 
           Cell[] firstRow=sheet.getRow(0); 
 
           String[] excelFieldNames=new String[firstRow.length]; 
 
           //获取Excel中的列名 
           for(int i=0;i<firstRow.length;i++){ 
               excelFieldNames[i]=firstRow[i].getContents().toString().trim(); 
           } 
 
           //判断需要的字段在Excel中是否都存在 
           boolean isExist=true; 
           List<String> excelFieldList=Arrays.asList(excelFieldNames); 
           for(String cnName : fieldMap.keySet()){ 
               if(!excelFieldList.contains(cnName)){ 
                   isExist=false; 
                   break; 
               } 
           } 
 
           //如果有列名不存在,则抛出异常,提示错误 
           if(!isExist){ 
               throw new ExcelException("Excel中缺少必要的字段,或字段名称有误


 
 
           //将列名和列号放入Map中,这样通过列名就可以拿到列号 
           LinkedHashMap<String, Integer> colMap=new LinkedHashMap<String,

for(int i=0;i<excelFieldNames.length;i++){ 
               colMap.put(excelFieldNames[i], firstRow[i].getColumn()); 
           }  
 
 
 
           //判断是否有重复行 
           //1.获取uniqueFields指定的列 
           Cell[][] uniqueCells=new Cell[uniqueFields.length][]; 
           for(int i=0;i<uniqueFields.length;i++){ 
               int col=colMap.get(uniqueFields[i]); 
               uniqueCells[i]=sheet.getColumn(col); 
           } 
 
           //2.从指定列中寻找重复行 
           for(int i=1;i<realRows;i++){ 
               int nullCols=0; 
               for(int j=0;j<uniqueFields.length;j++){ 
                   String currentContent=uniqueCells[j][i].getContents(); 
                   Cell sameCell=sheet.findCell(currentContent,  
                           uniqueCells[j][i].getColumn(), 
                           uniqueCells[j][i].getRow()+1,  
                           uniqueCells[j][i].getColumn(),  
                           uniqueCells[j][realRows-1].getRow(),  
                           true); 
                   if(sameCell!=null){ 
                       nullCols++; 
                   } 
               } 
 
               if(nullCols==uniqueFields.length){ 
                   throw new ExcelException("Excel中有重复行,请检查"); 
               } 
           } 
 
           //将sheet转换为list 
           for(int i=1;i<realRows;i++){ 
               //新建要转换的对象 
               T entity=entityClass.newInstance(); 
 
               //给对象中的字段赋值 
               for(Entry<String, String> entry : fieldMap.entrySet()){ 
                   //获取中文字段名 
                   String cnNormalName=entry.getKey(); 
                   //获取英文字段名 
                   String enNormalName=entry.getValue(); 
                   //根据中文字段名获取列号 
                   int col=colMap.get(cnNormalName); 
 
                   //获取当前单元格中的内容 
                   String content=sheet.getCell(col, i).getContents().toString().trim(); 
 
                   //给对象赋值 
                   setFieldValueByName(enNormalName, content, entity); 
               } 
 
               resultList.add(entity); 
           } 
       } catch(Exception e){ 
           e.printStackTrace(); 
           //如果是ExcelException,则直接抛出 
           if(e instanceof ExcelException){ 
               throw (ExcelException)e; 
 
           //否则将其它异常包装成ExcelException再抛出 
           }else{ 
               e.printStackTrace(); 
               throw new ExcelException("导入Excel失败"); 
           } 
       } 
       return resultList; 
   } 
 
 
 
 
 
   /*<-------------------------辅助的私有方法----------------------------------------------->*/ 
   /** 
    * @MethodName  : getFieldValueByName 
    * @Description : 根据字段名获取字段值 
    * @param fieldName 字段名 
    * @param o 对象 
    * @return  字段值 
    */ 
   private static  Object getFieldValueByName(String fieldName, Object o) throws

Object value=null; 
       Field field=getFieldByName(fieldName, o.getClass()); 
 
       if(field !=null){ 
           field.setAccessible(true); 
           value=field.get(o); 
       }else{ 
           throw new ExcelException(o.getClass().getSimpleName() + "类不存在字段名


 
       return value; 
   } 
 
   /** 
    * @MethodName  : getFieldByName 
    * @Description : 根据字段名获取字段 
    * @param fieldName 字段名 
    * @param clazz 包含该字段的类 
    * @return 字段 
    */ 
   private static Field getFieldByName(String fieldName, Class<?>  clazz){ 
       //拿到本类的所有字段 
       Field[] selfFields=clazz.getDeclaredFields(); 
 
       //如果本类中存在该字段,则返回 
       for(Field field : selfFields){ 
           if(field.getName().equals(fieldName)){ 
               return field; 
           } 
       } 
 
       //否则,查看父类中是否存在此字段,如果有则返回 
       Class<?> superClazz=clazz.getSuperclass(); 
       if(superClazz!=null  &&  superClazz !=Object.class){ 
           return getFieldByName(fieldName, superClazz); 
       } 
 
       //如果本类和父类都没有,则返回空 
       return null; 
   } 
 
 
 
   /** 
    * @MethodName  : getFieldValueByNameSequence 
    * @Description :  
    * 根据带路径或不带路径的属性名获取属性值 
    * 即接受简单属性名,如userName等,又接受带路径的属性名,如
等 
    *  
    * @param fieldNameSequence  带路径的属性名或简单属性名 
    * @param o 对象 
    * @return  属性值 
    * @throws Exception 
    */ 
   private static  Object getFieldValueByNameSequence(String fieldNameSequence,

Object value=null; 
 
       //将fieldNameSequence进行拆分 
       String[] attributes=fieldNameSequence.split("\\."); 
       if(attributes.length==1){ 
           value=getFieldValueByName(fieldNameSequence, o); 
       }else{ 
           //根据属性名获取属性对象 
           Object fieldObj=getFieldValueByName(attributes[0], o); 
           String

value=getFieldValueByNameSequence(subFieldNameSequence, fieldObj); 
       } 
       return value;  
 
   }  
 
 
   /** 
    * @MethodName  : setFieldValueByName 
    * @Description : 根据字段名给对象的字段赋值 
    * @param fieldName  字段名 
    * @param fieldValue    字段值 
    * @param o 对象 
    */ 
   private static void setFieldValueByName(String fieldName,Object fieldValue,Object o)

Field field=getFieldByName(fieldName, o.getClass()); 
           if(field!=null){ 
               field.setAccessible(true); 
               //获取字段类型 
               Class<?> fieldType = field.getType();   
 
               //根据字段类型给字段赋值 
               if (String.class == fieldType) {   
                   field.set(o, String.valueOf(fieldValue));   
               } else if ((Integer.TYPE == fieldType)   
                       || (Integer.class == fieldType)) {   
                   field.set(o, Integer.parseInt(fieldValue.toString()));   
               } else if ((Long.TYPE == fieldType)   
                       || (Long.class == fieldType)) {   
                   field.set(o, Long.valueOf(fieldValue.toString()));   
               } else if ((Float.TYPE == fieldType)   
                       || (Float.class == fieldType)) {   
                   field.set(o, Float.valueOf(fieldValue.toString()));   
               } else if ((Short.TYPE == fieldType)   
                       || (Short.class == fieldType)) {   
                   field.set(o, Short.valueOf(fieldValue.toString()));   
               } else if ((Double.TYPE == fieldType)   
                       || (Double.class == fieldType)) {   
                   field.set(o, Double.valueOf(fieldValue.toString()));   
               } else if (Character.TYPE == fieldType) {   
                   if ((fieldValue!= null) && (fieldValue.toString().length() > 0)) {   
                       field.set(o, Character   
                               .valueOf(fieldValue.toString().charAt(0)));   
                   }   
               }else if(Date.class==fieldType){ 
                   field.set(o, new SimpleDateFormat("yyyy-MM-dd

}else{ 
                   field.set(o, fieldValue); 
               } 
           }else{ 
               throw new ExcelException(o.getClass().getSimpleName() + "类不存在字
 "+fieldName); 
           } 
   } 
 
 
   /** 
    * @MethodName  : setColumnAutoSize 
    * @Description : 设置工作表自动列宽和首行加粗 
    * @param ws 
    */ 
   private static void setColumnAutoSize(WritableSheet ws,int extraWith){ 
       //获取本列的最宽单元格的宽度 
       for(int i=0;i<ws.getColumns();i++){ 
           int colWith=0; 
           for(int j=0;j<ws.getRows();j++){ 
               String content=ws.getCell(i,j).getContents().toString(); 
               int cellWith=content.length(); 
               if(colWith<cellWith){ 
                   colWith=cellWith; 
               } 
           } 
           //设置单元格的宽度为最宽宽度+额外宽度 
           ws.setColumnView(i, colWith+extraWith); 
       } 
 
   } 
 
   /** 
    * @MethodName  : fillSheet 
    * @Description : 向工作表中填充数据 
    * @param sheet     工作表  
    * @param list  数据源 
    * @param fieldMap 中英文字段对应关系的Map 
    * @param firstIndex    开始索引 
    * @param lastIndex 结束索引 
    */ 
   private static <T> void fillSheet( 
           WritableSheet sheet, 
           List<T> list, 
           LinkedHashMap<String,String> fieldMap, 
           int firstIndex, 
           int lastIndex 
           )throws Exception{ 
 
       //定义存放英文字段名和中文字段名的数组 
       String[] enFields=new String[fieldMap.size()]; 
       String[] cnFields=new String[fieldMap.size()]; 
 
       //填充数组 
       int count=0; 
       for(Entry<String,String> entry:fieldMap.entrySet()){ 
           enFields[count]=entry.getKey(); 
           cnFields[count]=entry.getValue(); 
           count++; 
       } 
       //填充表头 
       for(int i=0;i<cnFields.length;i++){ 
           Label label=new Label(i,0,cnFields[i]); 
           sheet.addCell(label); 
       } 
 
       //填充内容 
       int rowNo=1; 
       for(int index=firstIndex;index<=lastIndex;index++){ 
           //获取单个对象 
           T item=list.get(index); 
           for(int i=0;i<enFields.length;i++){ 
               Object objValue=getFieldValueByNameSequence(enFields[i], item); 
               String fieldValue=objValue==null ? "" : objValue.toString(); 
               Label label =new Label(i,rowNo,fieldValue); 
               sheet.addCell(label); 
           } 
 
           rowNo++; 
       } 
       //设置自动列宽 
       setColumnAutoSize(sheet, 5); 
   }

java poi 通用工具类相关推荐

  1. Java - json通用工具类

    1.json工具类 import com.fasterxml.jackson.core.JsonParseException; import com.fasterxml.jackson.core.Js ...

  2. JAVA导出Excel通用工具类——第一篇:详细介绍POI 导出excel的多种复杂情况,包括动态设置筛选、动态合并横向(纵向)单元格等多种复杂情况——保姆级别,真的不能再详细了,代码拿来即用)

    JAVA导出Excel通用工具--第一篇:详细介绍POI 导出excel的多种复杂情况,包括动态设置筛选.动态合并横向(纵向)单元格等多种复杂情况--保姆级别,真的不能再详细了,封装通用工具类,代码拿 ...

  3. java通用解析excel_java读取简单excel通用工具类

    本文实例为大家分享了java读取简单excel通用工具类的具体代码,供大家参考,具体内容如下 读取excel通用工具类 import java.io.File; import java.io.File ...

  4. Java通用工具类之按对象属性排序工具类

    本工具类为按对象属性排序工具类,实现的功能: 1.按对象的一个属性和多个属性进行排序. 2.按对象属性正序和倒序排列. 3.完美支持int等基础类和Integer等包装类. 4.完美支持属性为实现了C ...

  5. 利用poi 读取excel通用工具类

    poi excel导出通用工具 | 这一行是废话 根据上一篇利用poi 导出excel通用工具类去年写的一个工具类,同样根据业务需求重新封装了一个读excel 工具类,感觉还算通用,分享到博客,欢迎各 ...

  6. Excel导出+解析通用工具类

    参照原文:http://blog.csdn.net/houxuehan/article/details/50960259 maven配置: <dependencies> <depen ...

  7. java POI 写入百万数据到 excel

    .xls文件只支持6w+的数据写入 .xlsx文件只支持104w+数据的写入 在java中jxl工具类只能操作.xls的文件,不能操作.xlsx的文件 POI工具类能够支持.xlsx的文件操作. ex ...

  8. c mysql 工具类_Jave工具——servlet+jsp编程中mysql数据库连接及操作通用工具类

    该工具类是在JavaWeb中连接mysql所用到的通用工具类 该类用于Java+Servlet的编程中,方便数据库的操作,连接,获取其列表值.下面是这个数据库操作类的通用方法,基本上能够用于类里面只含 ...

  9. java poi 操作ppt

    java poi 操作ppt 可以参考: https://www.w3cschool.cn/apache_poi_ppt/apache_poi_ppt_installation.html http:/ ...

最新文章

  1. socket read阻塞_go tcp中的ioutil.ReadAll阻塞的问题
  2. 特性(C# 和 Visual Basic)
  3. NGUI的button的创建的问题(Button Script)
  4. php生成红包数组,PHP 生成微信红包代码简单
  5. C++ 以智能指针管理内存资源
  6. python之模块的导入和用户的交互格式化输出
  7. python赚钱项目开发大体流程咨询_大型项目开发的基本流程
  8. 撤销Excel文件工作表保护的两种方法
  9. 自己做量化交易软件(26)小白量化事件回测之MetaTrader5自动回测
  10. 点击唤起电话功能和企业微信聊天窗口事件(H5)
  11. 【iOS】苹果登录Sign in with Apple
  12. RocketMq之消费方式
  13. Leetcode刷题:贪心算法
  14. 连接远程桌面提示“无法验证此远程计算机的身份”的解决办法
  15. canvas整体放大_Canvas实现图片放大缩小移动操作
  16. android5.0模拟器pc版,逍遥安卓独家发布支持5.0安卓系统电脑模拟器
  17. 斐讯k3搭建nginx+php+MariaDB(mysql )的教程
  18. 微软Office 2013定价及版本详情曝光
  19. HDU 5514 容斥原理
  20. 如何免费参加高端大气上档次的 COSCon'19 ?

热门文章

  1. element-ui 按需加载情况下覆盖预置scss变量
  2. 6-1 求二叉树高度 (25 分)【实验三:二叉树的构造和遍历】
  3. 微信小程序,上传身份证图片
  4. MFC列表框控件的动态编辑
  5. 为王菲写的第十首《雄心永在》
  6. airtest测试网页_使用AirTest进行网页自动化测试
  7. 待办清单和日程计划表哪个会更好?可做日程表和待办提醒管理的便签
  8. jq 刷新页面,刷新父级页面,iframe刷新父级页面
  9. 太吾绘卷加载卡54_太吾绘卷支持度卡40%提高支持率解决办法分享
  10. 教育城域网内网测速方法