智能摘要文章源自JAVA秀-https://www.javaxiu.com/40865.html
一般我们在导出的时候都是导出的前端表格,而前端表格同时也会对应的在后台有一个映射类。欢迎加入我的知识星球,一起探讨架构,交流源码。文章源自JAVA秀-https://www.javaxiu.com/40865.html
原文约 4943 字 | 图片 16 张 | 建议阅读 10 分钟 | 评价反馈文章源自JAVA秀-https://www.javaxiu.com/40865.html
注解+反射优雅的实现Excel导入导出(通用版)
点击关注 ? Java基基 文章源自JAVA秀-https://www.javaxiu.com/40865.html
收录于话题文章源自JAVA秀-https://www.javaxiu.com/40865.html
#Java基基文章源自JAVA秀-https://www.javaxiu.com/40865.html
299个文章源自JAVA秀-https://www.javaxiu.com/40865.html
点击上方“Java基基”,选择“设为星标”文章源自JAVA秀-https://www.javaxiu.com/40865.html
做积极的人,而不是积极废人!文章源自JAVA秀-https://www.javaxiu.com/40865.html
每天 14:00 更新文章,每天掉亿点点头发...文章源自JAVA秀-https://www.javaxiu.com/40865.html
文章源自JAVA秀-https://www.javaxiu.com/40865.html 源码精品专栏文章源自JAVA秀-https://www.javaxiu.com/40865.html
原创 | Java 2021 超神之路,很肝~文章源自JAVA秀-https://www.javaxiu.com/40865.html
中文详细注释的开源项目文章源自JAVA秀-https://www.javaxiu.com/40865.html
RPC 框架 Dubbo 源码解析文章源自JAVA秀-https://www.javaxiu.com/40865.html
网络应用框架 Netty 源码解析文章源自JAVA秀-https://www.javaxiu.com/40865.html
消息中间件 RocketMQ 源码解析文章源自JAVA秀-https://www.javaxiu.com/40865.html
数据库中间件 Sharding-JDBC 和 MyCAT 源码解析文章源自JAVA秀-https://www.javaxiu.com/40865.html
作业调度中间件 Elastic-Job 源码解析文章源自JAVA秀-https://www.javaxiu.com/40865.html
分布式事务中间件 TCC-Transaction 源码解析文章源自JAVA秀-https://www.javaxiu.com/40865.html
Eureka 和 Hystrix 源码解析文章源自JAVA秀-https://www.javaxiu.com/40865.html
Java 并发源码文章源自JAVA秀-https://www.javaxiu.com/40865.html
来源:blog.csdn.net/youzi1394046585/文章源自JAVA秀-https://www.javaxiu.com/40865.html
article/details/86670203文章源自JAVA秀-https://www.javaxiu.com/40865.html
实现过程:文章源自JAVA秀-https://www.javaxiu.com/40865.html
三个注解创建好之后就需要开始操作Excel了文章源自JAVA秀-https://www.javaxiu.com/40865.html
下面是一些自定义方法的代码文章源自JAVA秀-https://www.javaxiu.com/40865.html
文章源自JAVA秀-https://www.javaxiu.com/40865.html
日常在做后台系统的时候会很频繁的遇到Excel导入导出的问题,正好这次在做一个后台系统,就想着写一个公用工具来进行Excel的导入导出。文章源自JAVA秀-https://www.javaxiu.com/40865.html
一般我们在导出的时候都是导出的前端表格,而前端表格同时也会对应的在后台有一个映射类。文章源自JAVA秀-https://www.javaxiu.com/40865.html
所以在写这个工具的时候我们先理一下我们需要实现的效果:文章源自JAVA秀-https://www.javaxiu.com/40865.html
导出方法接收一个list集合,和一个Class类型,和HttpServletResponse 对象文章源自JAVA秀-https://www.javaxiu.com/40865.html
导出是可能会有下拉列表,所以需要一个map存储下拉列表数据源,传入参数后只需一行代码即可导出文章源自JAVA秀-https://www.javaxiu.com/40865.html
导入方法需要传入file文件,以及一个Class类型,导入之后将会返回一个list集合,里面的对象就是传入类型的对象,传入参数后只需一行代码即可导入文章源自JAVA秀-https://www.javaxiu.com/40865.html
实现过程:
首先需要创建三个注解文章源自JAVA秀-https://www.javaxiu.com/40865.html
一个是EnableExport ,必须有这个注解才能导出文章源自JAVA秀-https://www.javaxiu.com/40865.html
/** * 设置允许导出 */@Target(ElementType.TYPE)@Retention(RetentionPolicy.RUNTIME)public @interface EnableExport { String fileName();}
然后就是EnableExportField,有这个注解的字段才会导出到Excel里面,并且可以设置列宽文章源自JAVA秀-https://www.javaxiu.com/40865.html
/** * 设置该字段允许导出 * 并且可以设置宽度 */@Target(ElementType.FIELD)@Retention(RetentionPolicy.RUNTIME)public @interface EnableExportField { int colWidth() default 100; String colName();}
再就是ImportIndex,导入的时候设置Excel中的列对应的序号文章源自JAVA秀-https://www.javaxiu.com/40865.html
/** * 导入时索引 */@Target(ElementType.FIELD)@Retention(RetentionPolicy.RUNTIME)public @interface ImportIndex { int index() ;}
注解使用示例文章源自JAVA秀-https://www.javaxiu.com/40865.html
文章源自JAVA秀-https://www.javaxiu.com/40865.html
图片文章源自JAVA秀-https://www.javaxiu.com/40865.html
推荐下自己做的 Spring Boot 的实战项目:文章源自JAVA秀-https://www.javaxiu.com/40865.html
https://github.com/YunaiV/ruoyi-vue-pro文章源自JAVA秀-https://www.javaxiu.com/40865.html
三个注解创建好之后就需要开始操作Excel了
首先,导入方法。在后台接收到前端上传的Excel文件之后,使用poi来读取Excel文件文章源自JAVA秀-https://www.javaxiu.com/40865.html
我们根据传入的类型上面的字段注解的顺序来分别为不同的字段赋值,然后存入集合中,再返回文章源自JAVA秀-https://www.javaxiu.com/40865.html
代码如下:文章源自JAVA秀-https://www.javaxiu.com/40865.html
/** * 将Excel转换为对象集合 * @param excel Excel 文件 * @param clazz pojo类型 * @return */public static List<Object> parseExcelToList(File excel,Class clazz){ List<Object> res = new ArrayList<>(); // 创建输入流,读取Excel InputStream is = null; Sheet sheet = null; try { is = new FileInputStream(excel.getAbsolutePath()); if (is != null) { Workbook workbook = WorkbookFactory.create(is); //默认只获取第一个工作表 sheet = workbook.getSheetAt(0); if (sheet != null) { //前两行是标题 int i = 2; String values[] ; Row row = sheet.getRow(i); while (row != null) { //获取单元格数目 int cellNum = row.getPhysicalNumberOfCells(); values = new String[cellNum]; for (int j = 0; j <= cellNum; j++) { Cell cell = row.getCell(j); if (cell != null) { //设置单元格内容类型 cell.setCellType(Cell.CELL_TYPE_STRING ); //获取单元格值 String value = cell.getStringCellValue() == null ? null : cell.getStringCellValue(); values[j]=value; } } Field[] fields = clazz.getDeclaredFields(); Object obj = clazz.newInstance(); for(Field f : fields){ if(f.isAnnotationPresent(ImportIndex.class)){ ImportIndex annotation = f.getDeclaredAnnotation(ImportIndex.class); int index = annotation.index(); f.setAccessible(true); //此处使用了阿里巴巴的fastjson包里面的一个类型转换工具类 Object val =TypeUtils.cast(values[index],f.getType(),null); f.set(obj,val); } } res.add(obj); i++; row=sheet.getRow(i); } } } } catch (Exception e) { e.printStackTrace(); } return res;}
接下来就是导出方法。文章源自JAVA秀-https://www.javaxiu.com/40865.html
导出分为几个步骤:文章源自JAVA秀-https://www.javaxiu.com/40865.html
建立一个工作簿,也就是类型新建一个Excel文件文章源自JAVA秀-https://www.javaxiu.com/40865.html
文章源自JAVA秀-https://www.javaxiu.com/40865.html
图片文章源自JAVA秀-https://www.javaxiu.com/40865.html
建立一张sheet表文章源自JAVA秀-https://www.javaxiu.com/40865.html
文章源自JAVA秀-https://www.javaxiu.com/40865.html
图片文章源自JAVA秀-https://www.javaxiu.com/40865.html
设置标的行高和列宽文章源自JAVA秀-https://www.javaxiu.com/40865.html
文章源自JAVA秀-https://www.javaxiu.com/40865.html
图片文章源自JAVA秀-https://www.javaxiu.com/40865.html
绘制标题和表头文章源自JAVA秀-https://www.javaxiu.com/40865.html
文章源自JAVA秀-https://www.javaxiu.com/40865.html
图片文章源自JAVA秀-https://www.javaxiu.com/40865.html
这两个方法是自定义方法,代码会贴在后面文章源自JAVA秀-https://www.javaxiu.com/40865.html
写入数据到Excel文章源自JAVA秀-https://www.javaxiu.com/40865.html
文章源自JAVA秀-https://www.javaxiu.com/40865.html
图片文章源自JAVA秀-https://www.javaxiu.com/40865.html
创建下拉列表文章源自JAVA秀-https://www.javaxiu.com/40865.html
文章源自JAVA秀-https://www.javaxiu.com/40865.html
图片文章源自JAVA秀-https://www.javaxiu.com/40865.html
写入文件到response文章源自JAVA秀-https://www.javaxiu.com/40865.html
文章源自JAVA秀-https://www.javaxiu.com/40865.html
图片文章源自JAVA秀-https://www.javaxiu.com/40865.html
到这里导出工作就完成了文章源自JAVA秀-https://www.javaxiu.com/40865.html
推荐下自己做的 Spring Cloud 的实战项目:文章源自JAVA秀-https://www.javaxiu.com/40865.html
https://github.com/YunaiV/onemall文章源自JAVA秀-https://www.javaxiu.com/40865.html
下面是一些自定义方法的代码
/** * 获取一个基本的带边框的单元格 * @param workbook * @return */private static HSSFCellStyle getBasicCellStyle(HSSFWorkbook workbook){ HSSFCellStyle hssfcellstyle = workbook.createCellStyle(); hssfcellstyle.setBorderLeft(HSSFCellStyle.BORDER_THIN); hssfcellstyle.setBorderBottom(HSSFCellStyle.BORDER_THIN); hssfcellstyle.setBorderRight(HSSFCellStyle.BORDER_THIN); hssfcellstyle.setBorderTop(HSSFCellStyle.BORDER_THIN); hssfcellstyle.setAlignment(HSSFCellStyle.ALIGN_CENTER); hssfcellstyle.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER); hssfcellstyle.setWrapText(true); return hssfcellstyle;}/** * 获取带有背景色的标题单元格 * @param workbook * @return */private static HSSFCellStyle getTitleCellStyle(HSSFWorkbook workbook){ HSSFCellStyle hssfcellstyle = getBasicCellStyle(workbook); hssfcellstyle.setFillForegroundColor((short) HSSFColor.CORNFLOWER_BLUE.index); // 设置背景色 hssfcellstyle.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND); return hssfcellstyle;}/** * 创建一个跨列的标题行 * @param workbook * @param hssfRow * @param hssfcell * @param hssfsheet * @param allColNum * @param title */private static void createTitle(HSSFWorkbook workbook, HSSFRow hssfRow , HSSFCell hssfcell, HSSFSheet hssfsheet,int allColNum,String title){ //在sheet里增加合并单元格 CellRangeAddress cra = new CellRangeAddress(0, 0, 0, allColNum); hssfsheet.addMergedRegion(cra); // 使用RegionUtil类为合并后的单元格添加边框 RegionUtil.setBorderBottom(1, cra, hssfsheet, workbook); // 下边框 RegionUtil.setBorderLeft(1, cra, hssfsheet, workbook); // 左边框 RegionUtil.setBorderRight(1, cra, hssfsheet, workbook); // 有边框 RegionUtil.setBorderTop(1, cra, hssfsheet, workbook); // 上边框 //设置表头 hssfRow = hssfsheet.getRow(0); hssfcell = hssfRow.getCell(0); hssfcell.setCellStyle( getTitleCellStyle(workbook)); hssfcell.setCellType(HSSFCell.CELL_TYPE_STRING); hssfcell.setCellValue(title);}/** * 设置表头标题栏以及表格高度 * @param workbook * @param hssfRow * @param hssfcell * @param hssfsheet * @param colNames */private static void createHeadRow(HSSFWorkbook workbook,HSSFRow hssfRow , HSSFCell hssfcell,HSSFSheet hssfsheet,List<String> colNames){ //插入标题行 hssfRow = hssfsheet.createRow(1); for (int i = 0; i < colNames.size(); i++) { hssfcell = hssfRow.createCell(i); hssfcell.setCellStyle(getTitleCellStyle(workbook)); hssfcell.setCellType(HSSFCell.CELL_TYPE_STRING); hssfcell.setCellValue(colNames.get(i)); }}/** * excel添加下拉数据校验 * @param sheet 哪个 sheet 页添加校验 * @return */public static void createDataValidation(Sheet sheet,Map<Integer,String[]> selectListMap) { if(selectListMap!=null) { selectListMap.forEach( // 第几列校验(0开始)key 数据源数组value (key, value) -> { if(value.length>0) { CellRangeAddressList cellRangeAddressList = new CellRangeAddressList(2, 65535, key, key); DataValidationHelper helper = sheet.getDataValidationHelper(); DataValidationConstraint constraint = helper.createExplicitListConstraint(value); DataValidation dataValidation = helper.createValidation(constraint, cellRangeAddressList); //处理Excel兼容性问题 if (dataValidation instanceof XSSFDataValidation) { dataValidation.setSuppressDropDownArrow(true); dataValidation.setShowErrorBox(true); } else { dataValidation.setSuppressDropDownArrow(false); } dataValidation.setEmptyCellAllowed(true); dataValidation.setShowPromptBox(true); dataValidation.createPromptBox("提示", "只能选择下拉框里面的数据"); sheet.addValidationData(dataValidation); } } ); }}
使用实例文章源自JAVA秀-https://www.javaxiu.com/40865.html
导出数据文章源自JAVA秀-https://www.javaxiu.com/40865.html
文章源自JAVA秀-https://www.javaxiu.com/40865.html
图片文章源自JAVA秀-https://www.javaxiu.com/40865.html
导入数据(返回对象List)文章源自JAVA秀-https://www.javaxiu.com/40865.html
文章源自JAVA秀-https://www.javaxiu.com/40865.html
图片文章源自JAVA秀-https://www.javaxiu.com/40865.html
源码地址:文章源自JAVA秀-https://www.javaxiu.com/40865.html
https://github.com/xyz0101/excelutils文章源自JAVA秀-https://www.javaxiu.com/40865.html
- END -文章源自JAVA秀-https://www.javaxiu.com/40865.html
欢迎加入我的知识星球,一起探讨架构,交流源码。加入方式,长按下方二维码噢:文章源自JAVA秀-https://www.javaxiu.com/40865.html
文章源自JAVA秀-https://www.javaxiu.com/40865.html
已在知识星球更新源码解析如下:文章源自JAVA秀-https://www.javaxiu.com/40865.html
文章源自JAVA秀-https://www.javaxiu.com/40865.html
文章源自JAVA秀-https://www.javaxiu.com/40865.html
文章源自JAVA秀-https://www.javaxiu.com/40865.html
文章源自JAVA秀-https://www.javaxiu.com/40865.html
最近更新《芋道 SpringBoot 2.X 入门》系列,已经 101 余篇,覆盖了 MyBatis、Redis、MongoDB、ES、分库分表、读写分离、SpringMVC、Webflux、权限、WebSocket、Dubbo、RabbitMQ、RocketMQ、Kafka、性能测试等等内容。文章源自JAVA秀-https://www.javaxiu.com/40865.html
提供近 3W 行代码的 SpringBoot 示例,以及超 6W 行代码的电商微服务项目。文章源自JAVA秀-https://www.javaxiu.com/40865.html
获取方式:点“在看”,关注公众号并回复 666 领取,更多内容陆续奉上。文章源自JAVA秀-https://www.javaxiu.com/40865.html
文章源自JAVA秀-https://www.javaxiu.com/40865.html
文章有帮助的话,在看,转发吧。谢谢支持哟 (*^__^*)文章源自JAVA秀-https://www.javaxiu.com/40865.html
阅读原文文章源自JAVA秀-https://www.javaxiu.com/40865.html

评论