问题:在我们的项目中会遇到各种各样的导表,比如说是财务报表,用户报表,员工报表等。基本这些报表导出的步骤是一定的,比如获取要导出的数据,然后借用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
浙公网安备 33010602011771号