利用POI实现excel导入导出(反射版)

1、需要导入的依赖:


            org.apache.poi
            poi
            3.15-beta1
       

       
            org.apache.poi
            poi-ooxml-schemas
            3.15-beta1
       

       
            org.apache.poi
            poi-ooxml
            3.15-beta1
       

2、自定注解:

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface ExcelAnnotation {

    //excel导出时标题显示的名字,如果没有设置Annotation的属性将不会被导出和导入
    public String exportName();
}

3、设置样式工具类:

/**
 * 设置标题样式
 */
public class  ExcelStyle{
    public static HSSFCellStyle setHeadStyle(HSSFWorkbook workbook, HSSFCellStyle style){
        style.setFillBackgroundColor(HSSFColor.SKY_BLUE.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 = workbook.createFont();
        font.setColor(HSSFColor.VIOLET.index); 
        font.setFontHeightInPoints((short)12); //字体大小
        font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD); //粗体
        //把字体应用到当前的样式
        style.setFont(font);
        return  style;
    }

    /**
     * 设置内容样式
     * @return
     */
    public static HSSFCellStyle setbodyStyle(HSSFWorkbook workbook,HSSFCellStyle style){
        style.setFillBackgroundColor(HSSFColor.SKY_BLUE.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);
        style.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER); //垂直居中
        //生成字体
        HSSFFont font = workbook.createFont();
        font.setBoldweight(HSSFFont.BOLDWEIGHT_NORMAL);
        //字体应用到当前样式
        style.setFont(font);
        return style;
    }
}
4、导入导出工具类:

/* poi导出工具类
 */
public class ImportExcel {
    Class clazz;

    public ImportExcel(Class clazz){
        this.clazz = clazz;
    }

    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");//格式化日期

    /**
     * 导出excel
     */
    public void exportExcel(String title, Collection dataset, OutputStream out){
        //格式化日期

        //声明一个工作簿
        try {
            //判读数据是否正确
            Iterator its = dataset.iterator();
            if(dataset == null || !its.hasNext() || title == null || out == null){
                throw new Exception("传入数据不对!");
            }
            //获得泛型类
            T ts = (T)its.next();
            Class tCls = ts.getClass();
            HSSFWorkbook workbook = new HSSFWorkbook();
            //生成一个表格
            HSSFSheet sheet = workbook.createSheet();
            //设置表格默认列宽度为多少字节
            sheet.setDefaultColumnWidth(20);
            //生成一个样式
            HSSFCellStyle style = workbook.createCellStyle();
            //设置标题样式
            style = ExcelStyle.setHeadStyle(workbook,style);

            //得到所有字段
            Field field[] = ts.getClass().getDeclaredFields();
            //标题
            List exportFieldTitle = new ArrayList<>();
            //导出的字段的get方法
            List methodObj = new ArrayList();
            //遍历field
            for (int i = 0; i                 Field f  = field[i];
                ExcelAnnotation exa = f.getAnnotation(ExcelAnnotation.class);
                //如果设置了annottion
                if(exa != null){
                    String export = exa.exportName();
                    //添加到标题
                    exportFieldTitle.add(export);
                    //添加到需要的字段
                    String fieldName = f.getName();
                    String getMethodName = "get"
                            + fieldName.substring(0,1).toUpperCase()
                            + fieldName.substring(1);
                    Method getmethod = tCls.getMethod(getMethodName, new Class[]{});
                    methodObj.add(getmethod);
                }
            }
            //产生表格标题行
            HSSFRow row = sheet.createRow(0);
            for (int i = 0; i < exportFieldTitle.size(); i++) {
                HSSFCell cell = row.createCell(i);
                cell.setCellStyle(style);
                HSSFRichTextString text = new HSSFRichTextString(exportFieldTitle.get(i));
                cell.setCellValue(text);
            }
            int index = 0;
            //循环整个集合
            its = dataset.iterator();
            while (its.hasNext()){
                //从第二行开始,第一行为标题行
                index++;
                row = sheet.createRow(index);
                T t = (T)its.next();
                for (int k = 0; k < methodObj.size(); k++) {
                    HSSFCell cell = row.createCell(k);
                    Method getMethod = methodObj.get(k);
                    Object value = getMethod.invoke(t, new Object[]{});
                    String textValue = getValue(value);
                    cell.setCellValue(textValue);
                }
            }
            workbook.write(out);
        }catch (Exception e)
        {
            e.printStackTrace();
        }
    }

    @SuppressWarnings({"static-access"})
    public String getValue(Object value){
        String textValue = "";
        if(null == value){
            return textValue;
        }
        if(value instanceof Boolean){
            boolean bValue = (Boolean) value;
            textValue = "是";
            if(!bValue){
                textValue = "否";
            }
        }else if(value instanceof GregorianCalendar){
            GregorianCalendar calender = (GregorianCalendar) value;
            Date d = calender.getTime();
            textValue = sdf.format(d);
        }else{
            textValue = value.toString();
        }
        return  textValue;
    }

    /**
     * 导入Excel
     * @param file
     * @param pattern
     * @return
     */
    public Collection importExcel(File file, String... pattern){
        Collection dist = new ArrayList();
        try{
            //得到目标类的所有字段列表
            Field field[] = clazz.getDeclaredFields();
            //将所有标有Annotaion字段,放入map中
            Map filedmap = new HashMap();
            //循环读取所有字段
            for(int i = 0; i< field.length; i++){
                Field f = field[i];
                //得到单个字段上的Annotaion
                ExcelAnnotation exa = f.getAnnotation(ExcelAnnotation.class);
                String filedname = f.getName();
                String setMethodName = "set"
                        + filedname.substring(0,1).toUpperCase()
                        + filedname.substring(1);
                if(null != exa){
                    Method setmethod = clazz.getMethod(setMethodName,
                            new Class[]{f.getType()});
                    //将这个method以Annotation的名字为key来存入
                    filedmap.put(exa.exportName(), setmethod);
                }
            }
            /**
             * excel解析开始
             */
            //将传入的file构造为FileInputStream
            FileInputStream in = new FileInputStream(file);
            //得到表
            HSSFWorkbook book = new HSSFWorkbook(in);
            //得到第一页
            HSSFSheet sheet = book.getSheetAt(0);
            //得到第一面的所有行
            Iterator row = sheet.rowIterator();

            /**
             * 标题解析
             */
            //得到标题行
            Row title = row.next();
            //得到第一行所有列
            Iterator cellTitle = title.cellIterator();
            //将标题的文字内容放入一个map中
            Map titlemap = new HashMap();
            //从标题的第一列开始
            int i = 0;
            //循环所有的列
            while (cellTitle.hasNext()){
                Cell cell = cellTitle.next();
                String value = cell.getStringCellValue();
                titlemap.put(i,value);
                i = i + 1;
            }
            /**
             * 解析行
             */
            //格式化日期
            SimpleDateFormat sf;
            if(pattern.length<1){
                sf = new SimpleDateFormat("yyyy-MM-dd");
            }
            else {
                sf = new SimpleDateFormat(pattern[0]);
            }
            while (row.hasNext()){
                //标题下的第一行
                Row rown = row.next();
                //行的所有列
                Iterator cellbody = rown.cellIterator();
                //得到传入类的实例
                T tObject = clazz.newInstance();
                int k= 0;
                //遍历一行的列
                while (cellbody.hasNext()){
                    Cell cell = cellbody.next();
                    //此列标题
                    String titleString = (String)titlemap.get(k);

                    Method setMethod = (Method) filedmap.get(titleString);
                    //得到set的参数
                    Type[] ts = setMethod.getGenericParameterTypes();
                    String xclass = ts[0].toString();
                    //设置cell的类型防止读取字符串出错
                    cell.setCellType(cell.CELL_TYPE_STRING);
                    //判断参数类型
                    //如果这一列的标题和类中的Annotation相同 ,那么调用此类的set方法,设值
                    if(filedmap.containsKey(titleString)){
                        if(xclass.equals("class java.lang.String")){
                            setMethod.invoke(tObject,cell.getStringCellValue());
                        }else if(xclass.equals("class java.util.Date")){
                            setMethod.invoke(tObject,sf.parse(cell.getStringCellValue()));
                        }else if(xclass.equals("class java.lang.Boolean")) {
                            Boolean boolname = true;
                            if (cell.getStringCellValue().equals("否")) {
                                {
                                    boolname = false;
                                }
                                setMethod.invoke(tObject, boolname);
                            }
                        }
                        else if(xclass.equals("class java.lang.Integer")){
                            setMethod.invoke(tObject,new Integer(cell.getStringCellValue()));
                        }
                        else if(xclass.equals("class java.lang.Long")){
                            setMethod.invoke(tObject,new Long(cell.getStringCellValue()));
                        }
                    }
                    //下一列
                    k = k + 1;
                }
                dist.add(tObject);
            }
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
        return dist;
    }

}

5、测试:

@SpringBootTest
@RunWith(SpringRunner.class)
public class ImportController {
    @Autowired
    ImportRepository importRepository;
    @Test
    public void Test() {
        ImportExcel importExcel = new ImportExcel(Messagess.class);
        File file = new File("D:\\测试.xls");
        List result = (ArrayList)importExcel.importExcel(file);
        for(int i =0 ; i

            Messagess mes = result.get(i);
            mes.setId(UUIDGenerator.getUUID());
            importRepository.save(mes);
            System.out.println("导入的信息为:"+ mes.getDeptName()+"\t"
                    +mes.getUserName()+"\t"+mes.getPone()+"\t"
                    +mes.getEmail());
        }
    }

    @Test
    public void Test1() {
        //模拟list
        List list = new ArrayList();
        for (int i = 0; i < 10; i++) {
            Messagess item = new Messagess();
            item.set();
            item.add();
        }
        //构造输出对象,可以response输出,直接下载
        FileOutputStream out = new FileOutputStream("D:\\测试.xls");
        //开始时间
        Long l = System.currentTimeMillis();
        //注意
        new ImportExcel().exportExcel("",list,out);
        out.close();
        //结束时间
        Long s = System.currentTimeMillis();
        System.out.println("总耗时:"+ (s-l));
    }
}
 

你可能感兴趣的:(报表导出)