问题:在我们的项目中会遇到各种各样的导表,比如说是财务报表,用户报表,员工报表等。基本这些报表导出的步骤是一定的,比如获取要导出的数据,然后借用poi导出数据并生成excel.但是如果每个service都去执行这两个方法,就不可避免会有很多重复的代码。比如说UserService,EmployeeService,AgentService等,那么其实导出这个数据生成excel的方法是一样,都是采用注解+反射实现的,也就是说这个步骤是一定的。也就是说只有获取需要导出数据这个步骤是不一样的。那么我们可以将其定义为模板模式实现,其中获取数据父类抽象定义,

而由子类自己实现。导出数据这个步骤是一样的。我们来看看代码实现:

1.ExcelTemplate:导出excel需要的模板

/**
 * @author wxe
 * @since 1.0.0
 */
public abstract class ExcelTemplate<T> {
    
    /**
     * 导出文件
     */
    public void doExcel(Condition condition,String fileName,OutputStream out){
        //1.获取数据map
        List<T> data = getDataByCondition(condition);
        
        //2.导出
        exportExcel(fileName,out,data);
    }
    
    /**
     * 根据页面传递来的条件参数获取数据
     * @param condition
     * @return
     */
    public abstract List<T> getDataByCondition(Condition condition);
    
    /**
     * 导出数据
     * @param fileName
     * @param out
     * @param data
     * @throws IllegalAccessException 
     */
    public void exportExcel(String fileName, OutputStream out, List<T> data) {
        ExlAnnotationUtil.export(fileName,null, data ,getT(),out);    
    }    
    
    /**
     * 获取当前类类型
     * @return
     */
    public Class<T> getT() {
        Type sType = this.getClass().getGenericSuperclass();
        Type[] generics = ((ParameterizedType) sType).getActualTypeArguments();// 一个泛型类可能有多个泛型形参,比如ClassName<T,K>
                                                                                // 这里有两个泛型形参T和K,Class
                                                                                // Name<T>
                                                                                // 这里只有1个泛型形参T
        Class<T> mTClass = (Class<T>) (generics[0]);
        return mTClass;
    }
}

由上面可以看出,我们定义好了导出数据这个类的方法步骤,只是获取数据需要子类继承实现。

2.实践:

public class UserExcel extends ExcelTemplate<UserModel> {


    @Override
    public List<UserModel> getDataByCondition(Condition condition) {
        List<UserModel> result = findExportsExcel(condition);
        return result;
    }
}

3.调用

public class UserServiceImpl{

    @Resource
    private UserExcel userExcel;


    public void  findExportsExcel(Condition param,String fileName,OutputStream out) {
          doExcel(condition, fileName, out);
    }
}    

后面就是controller层的调用,我就不写了。

其实,这个有个很大的缺点:

1.每一个需要导出的业务,都需要有一个类专门来实现ExcelTemplate。如果后期这种导出需求很多的话,就会产生更多的子类。

但是有两个优点:

1.逻辑比较清晰。先定义获取导出数据,再定义导出并生成excel.

2.扩展性比较高。

 posted on 2017-09-04 15:07  abysstoabyss  阅读(160)  评论(1)    收藏  举报