首页 > 代码库 > 使用回调方式写POI导入excel工具类

使用回调方式写POI导入excel工具类

场景是这样的:为了做一个excel导入的功能,为了尽可能的写一个通用的工具类,将与poi有关的东西都封装起来,以便以其他人员只用关心自己的业务,不用和poi打交道。

写到最后,现在还是会有poi的东西暴漏出来一点,暴漏出来的这个应该是必须的。

为了模拟这个场景,先写两个service方法,用于和数据库交互,存入从模板中读取的数据。代码如下:

1.berthservice

public class BerthService {    public void update(){        System.out.println("this is berth service");    }}

2.sensorservice

public class SensorServices {    public void update(Sensor sensor){        //do services        System.out.println("success update:"+sensor.getName());    }}

之所以要写两个service,是为了测试,对于同一个xls模板,是不是可以使用两次。

然后需要写一个实体类,用于将模板中的数据存入其中,这里只写一个sensor的。

3.sensor

public class Sensor {    private String name;    private String age;    public String getName() {        return name;    }    public void setName(String name) {        this.name = name;    }    public String getAge() {        return age;    }    public void setAge(String age) {        this.age = age;    }}

上面的准备工作完毕,这里使用回调,需要一个接口,这里其实暴露出了POI里面的HSSFROW这个对象。

public interface ExcelDataSetter {    public Object setCellData(HSSFRow row);}

 

然后就是最重要的工具类,传入上面的接口,这个用来读取xls文件,并且进行业务操作的,这里涉及到的都是关于POI的一些操作。

public class ExcelUtil {    //存放service    private static List serviceList=new ArrayList();    public static void readAndSetData(File file,ExcelDataSetter dataSetter, Object services){        FileInputStream fileInputStream=null;        try {            fileInputStream=new FileInputStream(file);        } catch (FileNotFoundException e) {            e.printStackTrace();        }        POIFSFileSystem fs= null;        HSSFSheet hssfSheet=null;        Object dataObj=null;        List<Object> list=new ArrayList<Object>();        Map map=null;        try {            fs = new POIFSFileSystem(fileInputStream);            HSSFWorkbook wb=new HSSFWorkbook(fs);            hssfSheet=wb.getSheetAt(0);  // 获取第一个Sheet页        } catch (IOException e) {            e.printStackTrace();        }finally {            try {                fileInputStream.close();            } catch (IOException e) {                e.printStackTrace();            }        }        if (hssfSheet!=null){            for (int rowNum=2;rowNum<=hssfSheet.getLastRowNum();rowNum++){                HSSFRow row=hssfSheet.getRow(rowNum);                if (row==null){                    continue;                }               //填充数据到对象中               dataObj= dataSetter.setCellData(row);               /*Sensor sensor= (Sensor) dataObj;               System.out.println("get sensor data:"+sensor.getName());               System.out.println("get sensor age:"+sensor.getAge());               services.update(sensor);*/               doServices(services,dataObj);            }        }    }    public static void doServices(Object o,Object dataObj){            if (o instanceof SensorServices) {                Sensor sensor = (Sensor) dataObj;                ((SensorServices) o).update(sensor);            }            if (o instanceof BerthService) {                ((BerthService) o).update();            }    }    public static void registeService(List list){        serviceList=list;    }}

填充数据到对象中之后,调用doServices方法,与数据库进行交互。
这里设计的不是很合理,因为可能会有很多个services方法,doServices里面,这里是写死的,然后根据类型来判断。之前是想设计一个registeService方法,其他人员采用的时候,先在这里注册一下自己的service,就不需要写死service了。这里如果有高手有比较合理的设计方式,请指教指教。

写一个main方法,测试一下。

public class Main {    public static void main(String args[]){        File file=new File("F:/G/test.xls");        final Sensor sensor=new Sensor();        //test sensor services        SensorServices sensorservices=new SensorServices();        //test berth services        BerthService berthService=new BerthService();       //注册service       //SerivicesRegister register=new SerivicesRegister(sensorservices);       ExcelUtil.readAndSetData(file, new ExcelDataSetter() {            @Override            public Sensor setCellData(HSSFRow row) {                sensor.setName(row.getCell(0).getStringCellValue());                sensor.setAge(row.getCell(1).getStringCellValue());                return sensor;            }        },sensorservices);        //test berth services        ExcelUtil.readAndSetData(file,new ExcelDataSetter() {            @Override            public Object setCellData(HSSFRow row) {                return null;            }        },berthService);    }}

读取的文件里面,有两行数据。

运行main方法,在控制台,就会打印出service中的语句,模拟service的操作。sensor的service是读取该模板的内容并,berthservice纯粹是打印语句。

控制台输出:

success update:wll
success update:zhangsan
this is berth service
this is berth service

针对上面的设计问题,希望各位指教指教。

 

使用回调方式写POI导入excel工具类