java,jxl解析excel

来源:互联网 发布:数据库设计的步骤实例 编辑:程序博客网 时间:2024/04/26 17:05

在编写ExcelUtil之前,在网上查了一些资料。Java中用来处理Excel的第三方开源项目主要就是POIJXLpoi功能强大,但是比较耗资源,对于大数据量的导入导出性能不是太好;jxl功能简单,但是性能比较好。

 

由于本项目的导入导出更多关注性能问题,而且jxl提供的功能基本也都够用了,于是选择了jxl作为支持。


另外jxl的一个很大缺点是:只能是.xls格式,.xlsx格式会失败。

package common.tool.excel;/** * Created by liuyazhou on 2017/4/24. */public class ExcelException extends 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    }}
package common.tool.excel;import jxl.Cell;import jxl.Sheet;import jxl.Workbook;import java.io.InputStream;import java.lang.reflect.Field;import java.text.SimpleDateFormat;import java.util.*;public class ExcelUtil  {    /**     * @MethodName          : excelToList     * @Description             : 将Excel转化为List     * @param in                    :承载着Excel的输入流     * @param entityClass       :List中对象的类型(Excel中的每一行都要转化为该类型的对象)     * @param fieldMap          :Excel中的中文列头和类的英文属性的对应关系Map     * @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 || "".equals(currentCell.getContents().toString())){                        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, Integer>();            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(Map.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;    }//excelToList    /*<-------------------------辅助的私有方法----------------------------------------------->*/    /**     * @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;    }//getFieldByName    /**     * @MethodName  : setFieldValueByName     * @Description : 根据字段名给对象的字段赋值     * @param fieldName  字段名     * @param fieldValue    字段值     * @param o 对象     */    private static void setFieldValueByName(String fieldName,Object fieldValue,Object o) throws Exception{        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 HH:mm:ss").parse(fieldValue.toString()));            }else{                field.set(o, fieldValue);            }        }else{            throw new ExcelException(o.getClass().getSimpleName() + "类不存在字段名 "+fieldName);        }    }//setFieldValueByName}
/** * Created by liuyazhou on 2016/11/28. */public class DpConfigKind  {    private Long id; //主键    private String kindCode; //配置kind    private String kindName; //名称    private Double  rate;    public DpConfigKind() {    }    public Long getId() {        return id;    }    public void setId(Long id) {        this.id = id;    }    public String getKindCode() {        return kindCode;    }    public void setKindCode(String kindCode) {        this.kindCode = kindCode;    }    public String getKindName() {        return kindName;    }    public void setKindName(String kindName) {        this.kindName = kindName;    }    public Double getRate() {        return rate;    }    public void setRate(Double rate) {        this.rate = rate;    }}
import common.tool.excel.ExcelException;import common.tool.excel.ExcelUtil;import java.io.FileInputStream;import java.io.FileNotFoundException;import java.io.InputStream;import java.util.LinkedHashMap;import java.util.List;public class Main {    InputStream in;    String sheetName;    LinkedHashMap<String, String> fieldMap;    String[] uniqueFields;    public static void main(String[] args) {        Main main = new Main();        List<DpConfigKind> dpConfigKindList = main.importExcel();         if(dpConfigKindList != null  && dpConfigKindList.size() > 0){             for(DpConfigKind dpConfigKind :dpConfigKindList){                 System.out.println("id:"+dpConfigKind.getId()+",kind_code:"+dpConfigKind.getKindCode()+",kind_name:"+dpConfigKind.getKindName()+",比率:"+dpConfigKind.getRate());             }         }    }    private List<DpConfigKind> importExcel() {        try {            String filePath = "D:\\开发日志\\导入Excel\\dpConfigKind.xls";            in = new FileInputStream(filePath);            sheetName = "Sheet1";            fieldMap = new LinkedHashMap<String, String>();            fieldMap.put("主键", "id");            fieldMap.put("配置kind", "kindCode");//是属性名            fieldMap.put("名称", "kindName");            fieldMap.put("比率", "rate");            uniqueFields = new String[]{"主键"};//这里要是excel表里的列名,不能是属性的名称,比如“id”就会报错            return ExcelUtil.excelToList(in, sheetName, DpConfigKind.class, fieldMap, uniqueFields);        } catch (ExcelException e) {            e.printStackTrace();        } catch (FileNotFoundException e) {            e.printStackTrace();        }        return null;    }}

Connected to the target VM, address: '127.0.0.1:63497', transport: 'socket'Disconnected from the target VM, address: '127.0.0.1:63497', transport: 'socket'id:1,kind_code:Task1,kind_name:配置1,比率:0.23id:2,kind_code:Task2,kind_name:配置2,比率:0.01id:3,kind_code:Task3,kind_name:配置3,比率:2.58





0 0
原创粉丝点击