点击上方 蓝字关注我们
各位小伙伴大家好,上一篇文章给大家介绍了后台是如何生成动态菜单的,简单的说就是数据库的菜单在程序中通过父级菜单id这个字段,把表里的菜单变为一个有层级的菜单,然后通过递归,将菜单构建出来。今天呢给大家带来excel的导入功能。excel的导入功能在系统中非常常见,是基于反射原理写的,供大家参考。
No.1
excel的导入其实就是把excel的数据导入到数据库中,想想我们的思路是什么呢,是不是将excel的数据转换成一个list,然后进行批量插入?那么这样做问题就来了?如果再来一个excel的导入,那是不是需要再写一个list转换,这样做会导致代码的冗余,看起来非常不爽,我们可以通过java的泛型,反射来解决导入的问题。
No.2
首先是我们的excel的工具类了,这是核心,少了它可不行。下面我将完整的工具类展示给大家。
package com.zboot.zbootadmin.common.utils;import com.alibaba.fastjson.JSONObject;import com.zboot.zbootadmin.common.constant.HttpStatus;import com.zboot.zbootadmin.common.domain.ResponseData;import lombok.extern.slf4j.Slf4j;import org.apache.poi.ss.usermodel.CellStyle;import org.apache.poi.ss.usermodel.CellType;import org.apache.poi.ss.usermodel.FillPatternType;import org.apache.poi.ss.usermodel.IndexedColors;import org.apache.poi.xssf.streaming.SXSSFCell;import org.apache.poi.xssf.streaming.SXSSFRow;import org.apache.poi.xssf.streaming.SXSSFSheet;import org.apache.poi.xssf.streaming.SXSSFWorkbook;import org.apache.poi.xssf.usermodel.XSSFRow;import org.apache.poi.xssf.usermodel.XSSFSheet;import org.apache.poi.xssf.usermodel.XSSFWorkbook;import org.springframework.web.multipart.MultipartFile;import javax.servlet.ServletOutputStream;import javax.servlet.http.HttpServletResponse;import java.io.IOException;import java.io.InputStream;import java.io.OutputStream;import java.net.URLEncoder;import java.text.DecimalFormat;import java.util.ArrayList;import java.util.List;import java.util.UUID;/** * @Author: zyt * @Description: excle工具类 * @Date: Created in 14:57 2020/3/29 */@Slf4jpublic class ExcelUtils { public ExcelUtils() { } public SXSSFWorkbook getTemplateWorkBook(String[] titles,String sheetName) throws IOException { SXSSFCell sxssfCell = null; SXSSFWorkbook sxssfWorkbook = new SXSSFWorkbook(); SXSSFSheet sxssfSheet = sxssfWorkbook.createSheet(sheetName); sxssfSheet.setDefaultColumnWidth(21); SXSSFRow sxssfRow = sxssfSheet.createRow(0); for (int i = 0;i sxssfCell = sxssfRow.createCell(i); sxssfCell.setCellType(CellType.STRING); sxssfCell.setCellValue(titles[i]); this.setCellStyle(sxssfWorkbook,sxssfCell); this.setFont(sxssfWorkbook); } return sxssfWorkbook; } public void exportTemplate (HttpServletResponse response, SXSSFWorkbook sxssfWorkbook) throws IOException { response.setContentType("application/vnd.ms-excel;charset=UTF-8"); response.setHeader("Content-disposition", "attachment;filename=" + UUID.randomUUID().toString()); ServletOutputStream outputStream = response.getOutputStream(); try { sxssfWorkbook.write(outputStream); }catch (Exception e){ e.printStackTrace(); }finally { outputStream.flush(); outputStream.close(); } } public void setCellStyle (SXSSFWorkbook sxssfWorkbook,SXSSFCell sxssfCell) { CellStyle cellStyle = sxssfWorkbook.createCellStyle(); cellStyle.setFillForegroundColor(IndexedColors.CORNFLOWER_BLUE.getIndex()); cellStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND); sxssfCell.setCellStyle(cellStyle); } public void setFont(SXSSFWorkbook sxssfWorkbook) { sxssfWorkbook.createFont().setColor((short) 0); } public List importUser (MultipartFile multipartFile, String[] properties, Class clazz) { List excelValue = new ArrayList<>(); DecimalFormat df = new DecimalFormat("0"); try { XSSFRow row = null; InputStream inputStream = multipartFile.getInputStream(); XSSFWorkbook workbook = new XSSFWorkbook(inputStream); XSSFSheet sheet = workbook.getSheetAt(0); // 获取总行数 int lastRowNum = sheet.getLastRowNum(); for (int i=1;i<=lastRowNum;i++) { row = sheet.getRow(i); T t = clazz.newInstance(); for (int j=0;j String setMethod = ReflectionUtils.getSetMethod(properties[j]); String data = row.getCell(j).toString(); ReflectionUtils.setValue(clazz,t,setMethod,data); } excelValue.add(t); } workbook.close(); } catch (Exception e) { e.printStackTrace(); } return excelValue; } public void downExcel(String[] titles, List data, HttpServletResponse response, Class clazz, String[] properties){ try { response.setContentType("application/octet-stream;charset=utf-8"); String uuid = UUID.randomUUID().toString(); String fileName = uuid+".xlsx"; response.setHeader("Content-disposition", "attachment;fileName="+ URLEncoder.encode(fileName, "utf-8")); ServletOutputStream outputStream = response.getOutputStream(); SXSSFWorkbook sxssfWorkbook = new SXSSFWorkbook(); SXSSFSheet hssfSheet = sxssfWorkbook.createSheet("sheet1"); SXSSFRow sxssfRow = hssfSheet.createRow(0); hssfSheet.setDefaultColumnWidth(21); SXSSFCell sxssfCell ; for (int i=0;i sxssfCell = sxssfRow.createCell(i); sxssfCell.setCellValue(titles[i]); } for (int i=0;i sxssfRow = hssfSheet.createRow(i+1); T t = data.get(i); for (int j=0;j String getMethod = ReflectionUtils.getGetMethod(properties[j]); Object value = ReflectionUtils.getValue(clazz,t,getMethod); sxssfRow.createCell(j).setCellValue(value.toString()); } } try { sxssfWorkbook.write(outputStream); outputStream.flush(); outputStream.close(); } catch (Exception e) { e.printStackTrace(); } }catch (Exception e) { e.printStackTrace(); } } /** * @param src 源字符串 * @return 字符串,将src的第一个字母转换为大写,src为空时返回null */ private String change(String src) { if (src != null) { StringBuilder stringBuilder = new StringBuilder(src); stringBuilder.setCharAt(0, Character.toUpperCase(stringBuilder.charAt(0))); return stringBuilder.toString(); } else { return null; } }}
我这里简单给大家说下这个工具类的大致功能有哪些:excel的样式设置(简单的样式修改,后续可以新增。),导入,与导出。这里就给大家介绍导入功能。
No.3
大家只看上述方法中的importUser这个方法就可以了,这个方法的参数有multipartFile,这个参数是用来接收前端传来的文件,properties是实体类的字段,我们根据properties实现反射,clazz是我们的实体类,在使用的时候我们只需传入这三个参数就可以了。
下面就是将文件转为list集合了。代码如下:
for (int i=1;i<=lastRowNum;i++) { row = sheet.getRow(i); T t = clazz.newInstance(); for (int j=0;j String setMethod = ReflectionUtils.getSetMethod(properties[j]); String data = row.getCell(j).toString(); ReflectionUtils.setValue(clazz,t,setMethod,data); } excelValue.add(t); }
首先需要对excel中的行进行循环处理,在循环处理的过程中创建实例,利用反射生成的set方法设置值,最后将每一个创建的对象放至集合中就ok了。最后在利用mybatis-plus的批量添加方法进行批量操作,我们的导入功能就完成了。
最后附上反射工具类:
package com.zboot.zbootadmin.common.utils;import java.lang.reflect.Method;/** * @Author: zyt * @Description:反射工具类 * @Date: Created in 15:42 2020/4/5 */public class ReflectionUtils { public static String getSetMethod(String string) { char[] cs=string.toCharArray(); cs[0]-=32; //string.substring(0,1).toUpperCase()+string.substring(1) return "set"+String.valueOf(cs); } public static String getGetMethod(String string) { char[] cs=string.toCharArray(); cs[0]-=32; return "get"+String.valueOf(cs); } public static void setValue(Class> clazz,T t,String methods,Object value) throws Exception { Method method = clazz.getDeclaredMethod(methods,String.class); method.setAccessible(true); method.invoke(t,value); } public static Object getValue(Class> clazz,T t,String methods) throws Exception { Method method = clazz.getDeclaredMethod(methods); /*method.setAccessible(true);*/ return method.invoke(t); }}
No.4
excel到导入就介绍这么多,核心就是要大家明白如何使用泛型,如何使用反射,这是今天的要点。这两个知识点在java里面也是比较重要的,小z到时会写一个专题,把反射和泛型的常用用法介绍给大家。
不知大家是否觉得今天的文章有所收货呢?
让我知道你在看