JAVA POI 导出EXCEL: 代码中不需关心excel样式格式的实现思路 (反射)

代码中完全不需要考虑excel的单元格样式;

当需要改变excel的样式时,只需要改模板文件,不需要改代码;

当需要增加新的bean时, 只需要把新的bean传入makeDatasMap方法即可;

-------------------

模板是这个样子的: 在模板 需要填入数据的单元格中定义好参数,$类名.属性名;

一个Model:

package model;

/**
 * Created by zhz on 2016/5/30.
 */
public class DataBean1 {
    private String name =  "Tommy" ;
    private Integer age = 18;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }
}

另一个model:


package model;

/**
 * Created by zhz on 2016/5/30.
 */
public class DataBean2 {
    private String name = "Lisa" ;
    private Integer age = 16 ;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }
}

package controller;

import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.Multimap;
import model.DataBean1;
import model.DataBean2;
import org.apache.poi.ss.usermodel.*;

import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.lang.reflect.Field;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

public class Main {
    /**
     * 萝卜
     */
    public Map<String, Object> makeDatasMap(Object... args) {
        Map<String, Object> beansMap = new HashMap<>();
        for (Object obj : args) {
            beansMap.put(obj.getClass().getSimpleName(), obj);
        }
        return beansMap;
    }

    /**
     * 萝卜坑
     *
     * @param sheet
     * @return
     */
    public Multimap<String, Cell> getMarkedCells(Sheet sheet) {
        Multimap<String, Cell> map = ArrayListMultimap.create();
        for (Row row : sheet) {
            for (Cell cell : row) {
                if (cell.getCellType() == Cell.CELL_TYPE_STRING) {
                    String val = cell.getStringCellValue();
                    if (val.startsWith("$") && val.contains(".")) {
                        map.put(val.substring(1, val.length()), cell);
                    }
                }
            }
        }
        return map;
    }

    private void fillCellsWithData(Multimap<String, Cell> cells, Map<String, Object> datas) throws Exception {
        Set<String> keys = cells.keySet();
        for (String k : keys) {
            String[] key_splitted = k.split("\\.");
            assert key_splitted.length == 2 : "单元格" + k + "参数错误!";
            String className = key_splitted[0];
            String propertyName = key_splitted[1];
            Object object = datas.get(className);
            if (object == null) {
                throw new Exception("没这个bean!");
            }
            Class c = object.getClass();
            Field f = c.getDeclaredField(propertyName);
            f.setAccessible(true);
            Object val = f.get(object);
            Collection<Cell> cs = cells.get(k);
            for (Cell cell : cs) {
                cell.setCellValue(val == null ? "" : val.toString());
            }
        }
    }

    public static void main(String[] args) throws Exception {
        Main m = new Main();
        Workbook wb = WorkbookFactory.create(new File("D:/模板.xlsx"));
        DataBean1 bean1 = new DataBean1();// model对象
        DataBean2 bean2 = new DataBean2();// model对象
        Map<String, Object> datas = m.makeDatasMap(bean1, bean2); // get the datasMap which contains all the  carrots   above.
        Multimap<String, Cell> cells = m.getMarkedCells(wb.getSheetAt(0));//获取坑
        m.fillCellsWithData(cells, datas);
        OutputStream os = new FileOutputStream(new File("D:/结果.xlsx"));
        wb.write(os);
        System.out.println("end.");
    }
}



然后, 导出的结果就是这个样子:


nice , huh ?

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值