实现思路java
实现步骤c++
<dependency> <groupId>org.apache.poi</groupId> <artifactId>poi</artifactId> <version>3.17</version> </dependency> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-ooxml</artifactId> <version>3.17</version> </dependency> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-ooxml-schemas</artifactId> <version>3.17</version> </dependency> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-excelant</artifactId> <version>3.17</version> </dependency> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-examples</artifactId> <version>3.17</version> </dependency>
ExcelUtils utils = new ExcelUtils(); //字段名读取开始索引 utils.setFieldReadIndex(4); //数据读取开始索引 utils.setDataReadIndex(6); List<Map> maps = utils.getExcelInfo(file.getOriginalFilename(), file);
for(Map map :maps){ //这里Bean是要用来接收的自定义实体类 Bean obj = MapToBeanUtils.getModel(map,Bean.class); //处理相关业务逻辑 }
实现思路web
实现步骤spring
<dependency> <groupId>org.apache.poi</groupId> <artifactId>poi</artifactId> <version>3.17</version> </dependency> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-ooxml</artifactId> <version>3.17</version> </dependency> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-ooxml-schemas</artifactId> <version>3.17</version> </dependency> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-excelant</artifactId> <version>3.17</version> </dependency> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-examples</artifactId> <version>3.17</version> </dependency>
@Target(ElementType.FIELD) @Documented @Retention(RetentionPolicy.RUNTIME) public @interface ExcelColumn { String title(); }
@ExcelColumn(title="uuid") private String uuid;
//这里Bean是要用来导出的自定义实体类 ExcelUtils.export(Bean.class, list, DateUtil.format(new Date(),DateUtil.INT_STRING_FORMAT), response);
ExcelUtils.javashell
package com.demo.util; import com.andacx.core.log.LogFactory; import com.andacx.tool.Asserts; import org.apache.poi.hssf.usermodel.HSSFWorkbook; import org.apache.poi.hssf.util.HSSFColor; import org.apache.poi.ss.usermodel.*; import org.apache.poi.ss.util.CellUtil; import org.apache.poi.xssf.streaming.SXSSFSheet; import org.apache.poi.xssf.streaming.SXSSFWorkbook; import org.apache.poi.xssf.usermodel.XSSFWorkbook; import org.slf4j.Logger; import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.commons.CommonsMultipartFile; import javax.servlet.http.HttpServletResponse; import java.io.*; import java.lang.reflect.Field; import java.util.*; /** * <p>@description:【Excel写入和导出工具】</p> * <p>@author:【Boomer】</p> * <p>@date:【2018/1/11 11:18】</p> **/ public class ExcelUtils { private static final Logger LOGGER = LogFactory.get(ExcelUtils.class); /*** 总行数 **/ private int totalRows = 0; /*** 总条数 **/ private int totalCells = 0; /*** 数据读取开始索引 **/ private int dataReadIndex = 3; /*** 字段名读取开始索引 **/ private int fieldReadIndex = 2; public ExcelUtils() { } public int getTotalRows() { return totalRows; } public int getTotalCells() { return totalCells; } public int getDataReadIndex() { return dataReadIndex; } public void setDataReadIndex(int dataReadIndex) { this.dataReadIndex = dataReadIndex; } public int getFieldReadIndex() { return fieldReadIndex; } public void setFieldReadIndex(int fieldReadIndex) { this.fieldReadIndex = fieldReadIndex; } /** * <p>Description:【验证EXCEL文件】</p> * <p>Author:【Boomer】</p> * <p>Date:【2018/1/11 14:07】</p> * @param filePath * @return **/ public boolean validateExcel(String filePath) { Asserts.notNull(filePath, "文件名不是excel格式"); Asserts.isTrue((isExcel2003(filePath) || isExcel2007(filePath)), "文件名不是excel格式"); return true; } /** * <p>Description:【是不是2003的excel,返回true是2003】</p> * <p>Author:【Boomer】</p> * <p>Date:【2018/1/11 14:07】</p> * @param filePath * @return **/ public static boolean isExcel2003(String filePath) { return filePath.matches("^.+.(xls)$"); } /** * <p>Description:【是不是2007的excel,返回true是2007】</p> * <p>Author:【Boomer】</p> * <p>Date:【2018/1/11 14:07】</p> * @param filePath * @return **/ public static boolean isExcel2007(String filePath) { return filePath.matches("^.+.(xlsx)$"); } /** * <p>Description:【读EXCEL文件,获取客户信息集合】</p> * <p>Author:【Boomer】</p> * <p>Date:【2018/1/11 14:07】</p> * @param fileName * @param Mfile * @return **/ public List<Map> getExcelInfo(String fileName, MultipartFile Mfile) { //把spring文件上传的MultipartFile转换成CommonsMultipartFile类型 CommonsMultipartFile cf = (CommonsMultipartFile) Mfile; //获取本地存储路径 File fileFolder = new File(Sysutils.getUploadFilePath()); if (!fileFolder.exists()) { fileFolder.mkdirs(); } //新建一个文件 File uploadFile = new File(Sysutils.getUploadFilePath() + System.currentTimeMillis() + ".xlsx"); //将上传的文件写入新建的文件中 try { cf.getFileItem().write(uploadFile); } catch (Exception e) { e.printStackTrace(); } //初始化信息的集合 List<Map> list = new ArrayList<>(); //初始化输入流 InputStream is = null; try { //验证文件名是否合格 if (!validateExcel(fileName)) { return null; } //根据新建的文件实例化输入流 is = new FileInputStream(uploadFile); //根据excel里面的内容读取客户信息 list = getExcelInfo(is, isExcel2003(fileName)); is.close(); } catch (Exception e) { e.printStackTrace(); } finally { if (is != null) { try { is.close(); } catch (IOException e) { e.printStackTrace(); } } } return list; } /** * <p>Description:【根据excel里面的内容读取客户信息】</p> * <p>Author:【Boomer】</p> * <p>Date:【2018/1/11 14:07】</p> * @param is 输入流 * @param isExcel2003 excel是2003仍是2007版本 * @return * @throws IOException **/ public List<Map> getExcelInfo(InputStream is, boolean isExcel2003) { List<Map> list; try { /** 根据版本选择建立Workbook的方式 */ Workbook wb; //当excel是2003时 if (isExcel2003) { wb = new HSSFWorkbook(is); } else {//当excel是2007时 wb = new XSSFWorkbook(is); } //读取Excel里面客户的信息 list = readExcelValue(wb); } catch (IOException e) { throw new RuntimeException(e.getMessage()); } catch (NumberFormatException e) { throw new RuntimeException("读取错误,请确认Excel是否包含错误字符"); } return list; } /** * <p>Description:【读取Excel里面客户的信息】</p> * <p>Author:【Boomer】</p> * <p>Date:【2018/1/11 14:07】</p> * @param wb * @return **/ private List<Map> readExcelValue(Workbook wb) { //获得第一个shell Sheet sheet = wb.getSheetAt(0); //获得Excel的行数 this.totalRows = sheet.getPhysicalNumberOfRows(); //获得Excel的列数(前提是有行数) if (totalRows >= this.dataReadIndex && sheet.getRow(0) != null) { this.totalCells = sheet.getRow(0).getPhysicalNumberOfCells(); } List<Map> list = new ArrayList<>(); Map tempMap; //获取列数据对应的字段 Row title = sheet.getRow(this.fieldReadIndex); List<String> header = new ArrayList<>(); //循环Excel的列 for (int c = 0; c < this.totalCells; c++) { Cell cell = title.getCell(c); header.add(cell.getStringCellValue()); } //循环Excel行数,从第二行开始。标题不入库 for (int r = this.dataReadIndex; r < totalRows; r++) { Row row = sheet.getRow(r); if (row == null) { continue; } tempMap = new HashMap(this.totalCells); //循环Excel的列 for (int c = 0; c < this.totalCells; c++) { Cell cell = row.getCell(c); if (null != cell) { cell.setCellType(CellType.STRING); tempMap.put(header.get(c), cell.getStringCellValue()); } } //添加客户 list.add(tempMap); } return list; } /** * <p>Description:【导出到file】</p> * <p>Author:【Boomer】</p> * <p>Date:【2018/1/11 14:07】</p> * @param clz * @param data * @param filePath * @param <T> * @throws IOException **/ public static <T> void export(Class<T> clz, List<? extends T> data, String filePath) throws IOException { FileOutputStream out = new FileOutputStream(filePath); getBook(clz, data).write(out); out.close(); } /** * <p>Description:【导出到httpServletResponse】</p> * <p>Author:【Boomer】</p> * <p>Date:【2018/1/11 14:07】</p> * @param clz * @param data * @param fileName * @param response * @param <T> **/ public static <T> void export(Class<T> clz, List<? extends T> data, String fileName, HttpServletResponse response) { try { response.setContentType("application/vnd.ms-excel"); response.setHeader("Content-disposition", "attachment;filename=\"" + new String(fileName.getBytes("gb2312"), "ISO8859-1") + ".xlsx" + "\""); getBook(clz, data).write(response.getOutputStream()); } catch (Exception e) { throw new RuntimeException("系统异常"); } finally { try { response.getOutputStream().close(); } catch (IOException e) { LOGGER.error("流关闭异常:" + e.getMessage()); } } } /** * <p>Description:【生成Excel】</p> * <p>Author:【Boomer】</p> * <p>Date:【2018/1/11 14:07】</p> * @param clz * @param data * @return **/ private static <T> SXSSFWorkbook getBook(Class<T> clz, List<? extends T> data) { if (null == clz || null == data || data.size() <= 0) { throw new RuntimeException("参数异常"); } XSSFWorkbook workbook = new XSSFWorkbook(); SXSSFWorkbook sxssfWorkbook = new SXSSFWorkbook(workbook, 100); //第一个工做本 SXSSFSheet sheet = sxssfWorkbook.createSheet(); sheet.trackAllColumnsForAutoSizing(); //表头 Row header = sheet.createRow(0); //读取类字段、注解信息 Field[] fields = clz.getDeclaredFields(); //写入表头 int invalidFieldNum = 0; for (Field field : fields) { ExcelColumn excelColumn = field.getAnnotation(ExcelColumn.class); if (excelColumn == null) { continue; } Cell headerCell = header.createCell(invalidFieldNum++); headerCell.setCellStyle(headerCellStyle(sxssfWorkbook)); headerCell.setCellValue(excelColumn.title()); } //写入数据 for (int i = 0; i < data.size(); i++) { //第0行为表头 Row row = sheet.createRow(i + 1); //循环读取字段 int cellIndex = 0; for (int j = 0; j < fields.length; j++) { Field field = fields[j]; field.setAccessible(true); Object cellValue; ExcelColumn excelColumn = field.getAnnotation(ExcelColumn.class); if (null == excelColumn) { continue; } Object o; try { o = field.get(data.get(i)); cellValue = o; } catch (Exception e) { throw new RuntimeException("系统异常"); } CellUtil.createCell(row, cellIndex++, String.valueOf(cellValue)); } } //自适应宽度 for (int i = 0; i < invalidFieldNum; i++) { sheet.autoSizeColumn(i); } return sxssfWorkbook; } /** * <p>Description:【设置Excel表头样式】</p> * <p>Author:【Boomer】</p> * <p>Date:【2018/1/11 14:07】</p> * @param wb * @return **/ public static CellStyle headerCellStyle(Workbook wb) { CellStyle style = wb.createCellStyle(); Font font = wb.createFont(); font.setFontName("宋体"); //设置字体大小 font.setFontHeightInPoints((short) 12); //加粗 font.setBold(true); // 设置背景色 style.setFillForegroundColor(HSSFColor.HSSFColorPredefined.SKY_BLUE.getIndex()); style.setFillPattern(FillPatternType.SOLID_FOREGROUND); //让单元格居中 style.setAlignment(HorizontalAlignment.CENTER_SELECTION); // 左右居中 style.setAlignment(HorizontalAlignment.CENTER); // 上下居中 style.setVerticalAlignment(VerticalAlignment.CENTER); //设置自动换行 style.setWrapText(true); style.setFont(font); return style; } }
map转实体工具类apache
package com.andacx.lbs.util; import com.andacx.tool.StringUtil; import org.apache.commons.collections.MapUtils; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.text.SimpleDateFormat; import java.util.Date; import java.util.HashMap; import java.util.Map; /** * Created by Boomer on 2017/5/19. * @author Boomer */ public class MapToBeanUtils { /** * 获取类类型的全部Field包括父类中的Field * * @param clazz 类类型 * @return 返回类类型的全部Field包括父类中的Field */ public static Field[] getAllFields(Class clazz) { Map<String, Field> map = new HashMap<String, Field>(); for (Field field : clazz.getDeclaredFields()) { Class fieldType = field.getType(); String fieldName = field.getName(); if(isBaseType(fieldType)){ try { map.put(fieldName, field); } catch (Exception e) { e.printStackTrace(); } } } while (clazz.getSuperclass() != null) { clazz = clazz.getSuperclass(); if (clazz == Object.class) { break; } for (Field field : clazz.getDeclaredFields()) { if (!map.containsKey(field.getName())) { map.put(field.getName(), field); } } } return map.values().toArray(new Field[map.size()]); } /** * <p>Description:【判断是不是基本类型】</p> * <p>Author:【Boomer】</p> * <p>Date:【2018/1/8 16:13】</p> * @param fieldType * @return **/ public static Boolean isBaseType(Class fieldType){ if (fieldType == String.class) { return true; } else if (fieldType == double.class || fieldType == Double.class) { return true; } else if (fieldType == int.class || fieldType == Integer.class) { return true; } else if (fieldType == Boolean.class || fieldType == boolean.class) { return true; } else if (fieldType == Date.class) { return true; } return false; } /** * <p>Description:【将首字母转换为大写】</p> * <p>Author:【Boomer】</p> * <p>Date:【2018/1/5 15:54】</p> * * @param a * @return **/ public static String firstCharToUpper(String a) { return (new StringBuilder()).insert(0, a.substring(0, 1).toUpperCase()).append(a.substring(1)).toString(); } /** * <p>Description:【将map隐射到实体类】</p> * <p>Author:【Boomer】</p> * <p>Date:【2018/1/5 16:27】</p> * * @param map * @param model * @return **/ public static <T> T getModel(Map map, Class<T> model) { Field[] fields = getAllFields(model); String value; Method method; T obj; try { obj = model.newInstance(); } catch (Exception e) { throw new RuntimeException(e); } for (Field field : fields) { int modifiers = field.getModifiers(); if (Modifier.isStatic(modifiers) || Modifier.isFinal(modifiers)) { continue; } //根据传入的获取str来判断用哪一个字符串获取参数 value = MapUtils.getString(map, field.getName()); if (StringUtil.isEmpty(value)) { if (field.getType() == String.class) { try { method = model.getMethod("get" + firstCharToUpper(field.getName())); Object invokeValue = method.invoke(obj); if (invokeValue != null) { value = invokeValue.toString(); } } catch (Exception e) { if (field.getType() == Boolean.class || field.getType() == boolean.class) { try { String fieldName = field.getName(); method = model.getMethod("get" + firstCharToUpper(fieldName.startsWith("is") ? fieldName.replace("is", "") : fieldName)); Object invokeValue = method.invoke(obj); if (invokeValue != null) { value = invokeValue.toString(); } } catch (Exception e1) { System.out.println(e1.getMessage()); } } else { System.out.println(e.getMessage()); } } } } if (StringUtil.isNotEmpty(value)) { invokeMethod(model, obj, value, field.getName(), field.getType()); } } return obj; } /** * <p>Description:【调用方法】</p> * <p>Author:【Boomer】</p> * <p>Date:【2018/1/5 16:26】</p> * * @param modelClass * @param object * @param value * @param fieldName * @param fieldType * @return **/ private static <T> void invokeMethod(Class<T> modelClass, T object, String value, String fieldName, Class fieldType) { Method method = null; try { method = modelClass.getMethod("set" + firstCharToUpper(fieldName), fieldType); } catch (NoSuchMethodException e) { if (fieldType == Boolean.class || fieldType == boolean.class) { try { method = modelClass.getMethod("set" + firstCharToUpper(fieldName.startsWith("is") ? fieldName.replace("is", "") : fieldName), fieldType); } catch (NoSuchMethodException e1) { } } else { } } try { if (null != method) { if (fieldType == String.class) { method.invoke(object, value); } else if (fieldType == double.class || fieldType == Double.class) { try { method.invoke(object, Double.parseDouble(value)); } catch (NumberFormatException e) { e.printStackTrace(); } } else if (fieldType == int.class || fieldType == Integer.class) { try { method.invoke(object, Integer.parseInt(value)); } catch (NumberFormatException e) { e.printStackTrace(); } } else if (fieldType == Boolean.class || fieldType == boolean.class) { try { method.invoke(object, Boolean.parseBoolean(value)); } catch (Exception e) { e.printStackTrace(); } } else if (fieldType == Date.class) { try { SimpleDateFormat sdf = (value.length() == 10 ? new SimpleDateFormat("yyyy-MM-dd") : new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")); method.invoke(object, sdf.parse(value)); } catch (Exception e) { e.printStackTrace(); } } } } catch (Exception e) { e.printStackTrace(); } } }
public static <T> List<T> mapToBean(List<Map> maps, Class<T> obj) throws IllegalAccessException, InstantiationException { List<T> list = new ArrayList<>(); for (Map<String, Object> map : maps) { T module = obj.newInstance(); BeanWrapper wapper = new BeanWrapperImpl(module); for (Map.Entry entry : map.entrySet()) { if (wapper.isWritableProperty(entry.getKey().toString())) { wapper.setPropertyValue(entry.getKey().toString(), entry.getValue().toString()); } } list.add(module); } return list; }