使用SpringBoot+poi实现excel文档导出,打算分为三篇书写,第一篇基于if-else导出,第二篇提取部分方法作为抽象方法导出,第三篇为全抽象导出。
三、全抽象导出本篇将用三个模板导出三个不同样式的excel表格。
首先理一下思路 (可以类比一个两头和中间有开口的物体,按照基本的三种颜色的流体往下灌,中间的口不动的情况下,灌红色的流体出红色,灌绿色的流体出绿色;如果上口灌红色的流体,中间灌绿色的流体,出来的颜色就是黄色。把开口的物体作为抽象层的业务代码,流体作为参数,传不同的参数,出不同的结果,但是物体不变):
- 将第二章Service层的业务层代码全部抽取出来作为抽象方法,使用工厂生产impl层和不同类型数据处理结果;
- 使用“T”“V”“B”三个泛型分别代表实体(业务中暂时用不到,但是使用baseService查询肯定会用到)、导出表的Vo、查询条件。
import javax.servlet.http.HttpServletResponse; import java.util.List; public interface IExportServiceFactory2.1. 实现类1(用户){ void exportExcel(B b, HttpServletResponse response) throws Exception; List findScheduleByConditions(B b);
import com.example.export.dispose.ExcelDispose; import com.example.export.dispose.IDispose; import com.example.export.dispose.datadispose.UserExport; import com.example.export.service.IExportServiceFactory; import com.example.export.vo.UserVo; import com.example.export.vo.ScheduleVo; import org.springframework.stereotype.Service; import javax.servlet.http.HttpServletResponse; import java.util.ArrayList; import java.util.List; @Service public class UserExportServiceImpl implements IExportServiceFactory2.2. 实现类2(汽车){ @Override public void exportExcel(ScheduleVo vo, HttpServletResponse response) throws Exception { // 新行的索引 int i = 1; // 表头索引 int j = 0; List cellNameList = new ArrayList<>(); Integer width = null; IDispose dispose = new UserExport(); ExcelDispose zhqJtsyjcExcelDispose = new UserExport(); // vo.setYljgLb(DicYljgUtils.findByOrganId(UserUtils.getUser(vo.getUserId()).getOrganId()).getYljgLb()); // 导出excel模板根据传入的参数置空list,1:模板导出;2:全量导出 // List users = vo.getMb().equals("1") ? new ArrayList<>() : query(vo); List scheduleByConditions = findScheduleByConditions(vo); String path = "excel/user.xlsx"; zhqJtsyjcExcelDispose.excelPathDispose(path, scheduleByConditions, cellNameList, i, j, response, width, dispose); } public List findScheduleByConditions(ScheduleVo vo) { UserVo userVo1 = new UserVo(); UserVo userVo2 = new UserVo(); UserVo userVo3 = new UserVo(); UserVo userVo4 = new UserVo(); UserVo userVo5 = new UserVo(); List userVos = new ArrayList<>(); userVo1.setName("账伞").setAge("17").setSex("男").setAddress("北京市朝阳区上雕刻技法").setContactInformation("2342893472374"); userVo2.setName("里斯").setAge("43").setSex("女").setAddress("上海市黄浦区的发射点").setContactInformation("34534453"); userVo3.setName("汪芜").setAge("23").setSex("男").setAddress("陕西省西安市瓦基尔克").setContactInformation("3131231"); userVo4.setName("马尔扎哈").setAge("534").setSex("男").setAddress("山西省太原市昆仑山地方").setContactInformation("23544343"); userVo5.setName("古力娜扎").setAge("43").setSex("女").setAddress("广东省广州市的快速减肥").setContactInformation("1213124242"); userVos.add(userVo1); userVos.add(userVo2); userVos.add(userVo3); userVos.add(userVo4); userVos.add(userVo5); return userVos; } }
import com.example.export.dispose.ExcelDispose; import com.example.export.dispose.IDispose; import com.example.export.dispose.datadispose.CarExport; import com.example.export.service.IExportServiceFactory; import com.example.export.vo.CarVo; import com.example.export.vo.ScheduleVo; import org.springframework.stereotype.Service; import javax.servlet.http.HttpServletResponse; import java.util.ArrayList; import java.util.List; @Service public class CarExportServiceImpl implements IExportServiceFactory2.3. 实现类3(公司){ @Override public void exportExcel(ScheduleVo vo, HttpServletResponse response) throws Exception { // 新行的索引 int i = 1; // 表头索引 int j = 0; List cellNameList = new ArrayList<>(); Integer width = null; IDispose dispose = new CarExport(); ExcelDispose zhqJtsyjcExcelDispose = new CarExport(); // vo.setYljgLb(DicYljgUtils.findByOrganId(UserUtils.getUser(vo.getUserId()).getOrganId()).getYljgLb()); // 导出excel模板根据传入的参数置空list,1:模板导出;2:全量导出 // List users = vo.getMb().equals("1") ? new ArrayList<>() : query(vo); List scheduleByConditions = findScheduleByConditions(vo); String path = "excel/car.xlsx"; zhqJtsyjcExcelDispose.excelPathDispose(path, scheduleByConditions, cellNameList, i, j, response, width, dispose); } @Override public List findScheduleByConditions(ScheduleVo vo) { CarVo carVo1 = new CarVo(); CarVo carVo2 = new CarVo(); CarVo carVo3 = new CarVo(); CarVo carVo4 = new CarVo(); CarVo carVo5 = new CarVo(); CarVo carVo6 = new CarVo(); CarVo carVo7 = new CarVo(); List carVos = new ArrayList<>(); carVo1.setBrand("奥迪").setColor("红色").setLength("6.2").setWidth("2.4").setKilometre("600公里").setSpeed("150km/h").setLifetime("3年"); carVo2.setBrand("宝马").setColor("蓝色").setLength("6.3").setWidth("2.5").setKilometre("700公里").setSpeed("160km/h").setLifetime("4年"); carVo3.setBrand("比亚迪").setColor("黑色").setLength("6.4").setWidth("2.6").setKilometre("800公里").setSpeed("170km/h").setLifetime("5年"); carVo4.setBrand("长安").setColor("橙色").setLength("6.5").setWidth("2.7").setKilometre("900公里").setSpeed("180km/h").setLifetime("6年"); carVo5.setBrand("长城").setColor("渐变红").setLength("6.6").setWidth("2.8").setKilometre("1000公里").setSpeed("190km/h").setLifetime("7年"); carVo6.setBrand("五菱之光").setColor("青色").setLength("6.7").setWidth("2.9").setKilometre("1100公里").setSpeed("200km/h").setLifetime("8年"); carVo7.setBrand("奥托").setColor("玫瑰红").setLength("6.8").setWidth("2.0").setKilometre("11200公里").setSpeed("140km/h").setLifetime("9年"); carVos.add(carVo1); carVos.add(carVo2); carVos.add(carVo3); carVos.add(carVo4); carVos.add(carVo5); carVos.add(carVo6); carVos.add(carVo7); return carVos; } }
import com.example.export.dispose.ExcelDispose; import com.example.export.dispose.IDispose; import com.example.export.dispose.datadispose.CompanyExport; import com.example.export.service.IExportServiceFactory; import com.example.export.vo.CompanyVo; import com.example.export.vo.ScheduleVo; import org.springframework.stereotype.Service; import javax.servlet.http.HttpServletResponse; import java.util.ArrayList; import java.util.List; @Service public class CompanyExportServiceImpl implements IExportServiceFactory3. 抽象数据处理{ @Override public void exportExcel(ScheduleVo vo, HttpServletResponse response) throws Exception { // 新行的索引 int i = 2; // 表头索引 int j = 1; List cellNameList = new ArrayList<>(); Integer width = null; IDispose dispose = new CompanyExport(); ExcelDispose zhqJtsyjcExcelDispose = new CompanyExport(); // vo.setYljgLb(DicYljgUtils.findByOrganId(UserUtils.getUser(vo.getUserId()).getOrganId()).getYljgLb()); // 导出excel模板根据传入的参数置空list,1:模板导出;2:全量导出 // List users = vo.getMb().equals("1") ? new ArrayList<>() : query(vo); List scheduleByConditions = findScheduleByConditions(vo); String path = "excel/company.xlsx"; zhqJtsyjcExcelDispose.excelPathDispose(path, scheduleByConditions, cellNameList, i, j, response, width, dispose); } @Override public List findScheduleByConditions(ScheduleVo vo) { CompanyVo companyVo1 = new CompanyVo(); CompanyVo companyVo2 = new CompanyVo(); CompanyVo companyVo3 = new CompanyVo(); CompanyVo companyVo4 = new CompanyVo(); List companyVos = new ArrayList<>(); companyVo1.setName("北京市律师事务所").setAddress("北京市朝阳区觉得还是开发").setPeopleNum("59").setAverageSalary("12300元").setBusiness("打官司").setScale("200平"); companyVo2.setName("上海市美食加工厂").setAddress("上海市浦东新区登记是否").setPeopleNum("519").setAverageSalary("12400元").setBusiness("做食品").setScale("2000平"); companyVo3.setName("上海市机械加工厂").setAddress("上海市闵行区健身房的和").setPeopleNum("5119").setAverageSalary("12500元").setBusiness("加工零件").setScale("20000平"); companyVo4.setName("陕西旅游公司").setAddress("陕西省西安市扣税的风格").setPeopleNum("58").setAverageSalary("12600元").setBusiness("旅游推荐").setScale("200000平"); companyVos.add(companyVo1); companyVos.add(companyVo2); companyVos.add(companyVo3); companyVos.add(companyVo4); return companyVos; } }
import org.apache.poi.ss.usermodel.CellStyle; import org.apache.poi.ss.usermodel.Row; import org.apache.poi.ss.usermodel.Sheet; import java.util.List; public interface IDispose3.1. 数据处理实现1(用户,全样式){ V getType(List list, int k); void dataDispose(Row row, Sheet sheet, List cellNameList, List valueList, CellStyle cellStyle, Integer width, int cells);
import com.example.export.dispose.ExcelDispose; import com.example.export.dispose.IDispose; import com.example.export.util.DataExportUtils; import com.example.export.vo.UserVo; import org.apache.poi.ss.usermodel.Cell; import org.apache.poi.ss.usermodel.CellStyle; import org.apache.poi.ss.usermodel.Row; import org.apache.poi.ss.usermodel.Sheet; import java.util.List; public class UserExport extends ExcelDispose3.2. 数据处理实现2(汽车,去掉所有样式)implements IDispose { @Override public void dataDispose(Row row, Sheet sheet, List cellNameList, List valueList, CellStyle cellStyle, Integer width, int cells) { for (int j = 0; j < cells; j++) { Cell cell = row.createCell(j); for (int z = 0; z < valueList.size(); z++) { if (j == z) { if (j == 0) { // 插入序号,并按照表头对序号进行列宽设置 width = DataExportUtils.checkNum(cellNameList.get(0).length()); sheet.setColumnWidth(j, width); cell.setCellValue(valueList.get(z)); cell.setCellStyle(cellStyle); break; } cell.setCellValue(valueList.get(z)); cell.setCellStyle(cellStyle); break; } } } } @Override public UserVo getType(List list, int k) { // 对特定数据处理方法 return list.get(k); } @Override public void valueListDispose(List valueList, UserVo userVo) { // 例如:valueList.set(2, 调用翻译方法翻译字典项); } }
import com.example.export.dispose.ExcelDispose; import com.example.export.dispose.IDispose; import com.example.export.util.DataExportUtils; import com.example.export.vo.CarVo; import com.example.export.vo.UserVo; import org.apache.poi.ss.usermodel.Cell; import org.apache.poi.ss.usermodel.CellStyle; import org.apache.poi.ss.usermodel.Row; import org.apache.poi.ss.usermodel.Sheet; import java.util.List; public class CarExport extends ExcelDispose3.3. 数据处理实现3(公司, 去掉样式,保留动态列宽设置)implements IDispose { @Override public void dataDispose(Row row, Sheet sheet, List cellNameList, List valueList, CellStyle cellStyle, Integer width, int cells) { for (int j = 0; j < cells; j++) { Cell cell = row.createCell(j); for (int z = 0; z < valueList.size(); z++) { if (j == z) { if (j == 0) { // 插入序号,并按照表头对序号进行列宽设置 // 删除样式和列宽设置 // width = DataExportUtils.checkNum(cellNameList.get(0).length()); // sheet.setColumnWidth(j, width); cell.setCellValue(valueList.get(z)); // cell.setCellStyle(cellStyle); break; } cell.setCellValue(valueList.get(z)); // cell.setCellStyle(cellStyle); break; } } } } @Override public CarVo getType(List list, int k) { // 对特定数据处理方法 return list.get(k); } @Override public void valueListDispose(List valueList, CarVo carVo) { // 例如:valueList.set(2, 调用翻译方法翻译字典项); // 给车长和车宽都加上单位 valueList.set(3, valueList.get(3) + "米"); valueList.set(4, valueList.get(4) + "米"); } }
import com.example.export.dispose.ExcelDispose; import com.example.export.dispose.IDispose; import com.example.export.util.DataExportUtils; import com.example.export.vo.CompanyVo; import org.apache.poi.ss.usermodel.Cell; import org.apache.poi.ss.usermodel.CellStyle; import org.apache.poi.ss.usermodel.Row; import org.apache.poi.ss.usermodel.Sheet; import java.util.List; public class CompanyExport extends ExcelDispose4. 实体Vo 4.1. 用户implements IDispose { @Override public void dataDispose(Row row, Sheet sheet, List cellNameList, List valueList, CellStyle cellStyle, Integer width, int cells) { for (int j = 0; j < cells; j++) { Cell cell = row.createCell(j); for (int z = 0; z < valueList.size(); z++) { if (j == z) { if (j == 0) { // 插入序号,并按照表头对序号进行列宽设置 // 删除样式但不删除格式 width = DataExportUtils.checkNum(cellNameList.get(0).length()); sheet.setColumnWidth(j, width); cell.setCellValue(valueList.get(z)); // cell.setCellStyle(cellStyle); break; } cell.setCellValue(valueList.get(z)); // cell.setCellStyle(cellStyle); break; } } } } @Override public CompanyVo getType(List list, int k) { // 对特定数据处理方法 return list.get(k); } @Override public void valueListDispose(List valueList, CompanyVo companyVo) { // 例如:valueList.set(2, 调用翻译方法翻译字典项); } }
import lombok.Data; import lombok.experimental.Accessors; @Data @Accessors(chain = true) public class UserVo { private String id; private String name; private String age; private String sex; private String address; private String contactInformation; }4.2. 汽车
import lombok.Data; import lombok.experimental.Accessors; @Data @Accessors(chain = true) public class CarVo { private String id; private String brand; private String color; private String length; private String width; private String kilometre; private String speed; private String lifetime; }4.3. 公司
import lombok.Data; import lombok.experimental.Accessors; @Data @Accessors(chain = true) public class CompanyVo { private String id; private String name; private String address; private String peopleNum; private String scale; private String averageSalary; private String business; }5. 表格模板 5.1. 用户模板 5.2. 汽车模板 5.2. 公司模板 6. Controller层(其他两层参考如下用户层)
import com.example.export.service.IExportServiceFactory; import com.example.export.vo.ScheduleVo; import com.example.export.vo.UserVo; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import javax.servlet.http.HttpServletResponse; @RestController @RequestMapping("/user") public class UserController { @Autowired private IExportServiceFactory7. 输出结果 7.1. 用户保留所有样式 7.2. 汽车删除所有样式 7.3. 公司除自适应列宽外样式全部删除 8. 项目层级exportService; @GetMapping("/export") public void export(ScheduleVo scheduleVo, HttpServletResponse response) throws Exception { exportService.exportExcel(scheduleVo, response); } }
本章内容解决了项目内繁琐的if-else开发模式,并且抽取抽象方法,使用工厂模式自动生成对象,简单的静态代理模式增强代码块,强化各个类型的私有属性,这样就可以自定义一个通用的导出方法,无论业务怎么变,抽象方法自身不会发生改变,如果有需求需要强制改变所有类型的结构,我们只需要将抽象方法继承过来,使用简单的代理就可以达到要求,不会动原有的代码,符合设计模式的开闭原则,并且代码的灵动性非常高。
如果有新增其他类型的导出,我们只需要继承抽象类,实现抽象数据处理工厂的方法,就可以达到导出功能。
纯手打,技术有限,请各位大佬批评指正,谢谢!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)