/* * * Copyright 2017 Crab2Died * All rights reserved. * * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * Browse for more information : * 1) https://gitee.com/Crab2Died/Excel4J * 2) https://github.com/Crab2died/Excel4J * */ package com.github.crab2died.utils; import com.github.crab2died.annotation.ExcelField; import com.github.crab2died.converter.DefaultConvertible; import com.github.crab2died.converter.WriteConvertible; import com.github.crab2died.exceptions.Excel4JException; import com.github.crab2died.handler.ExcelHeader; import org.apache.poi.ss.usermodel.Cell; import org.apache.poi.ss.usermodel.CellValue; import org.apache.poi.ss.usermodel.DateUtil; import org.apache.poi.ss.usermodel.Row; import java.beans.BeanInfo; import java.beans.IntrospectionException; import java.beans.Introspector; import java.beans.PropertyDescriptor; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.math.BigDecimal; import java.util.*; import java.util.regex.Pattern; /** * Excel4J工具类 * author : Crab2Died * date : 2017/5/24 9:43 */ public class Utils { /** * getter或setter枚举 */ public enum FieldAccessType { GETTER, SETTER } /** * <p>根据JAVA对象注解获取Excel表头信息</p> * * @param clz 类型 * @return 表头信息 */ public static List<ExcelHeader> getHeaderList(Class<?> clz) throws Excel4JException { List<ExcelHeader> headers = new ArrayList<>(); List<Field> fields = new ArrayList<>(); for (Class<?> clazz = clz; clazz != Object.class; clazz = clazz.getSuperclass()) { fields.addAll(Arrays.asList(clazz.getDeclaredFields())); } for (Field field : fields) { // 是否使用ExcelField注解 if (field.isAnnotationPresent(ExcelField.class)) { ExcelField er = field.getAnnotation(ExcelField.class); try { headers.add(new ExcelHeader( er.title(), er.order(), er.writeConverter().newInstance(), er.readConverter().newInstance(), field.getName(), field.getType() )); } catch (InstantiationException | IllegalAccessException e) { throw new Excel4JException(e); } } } Collections.sort(headers); return headers; } /** * 获取excel列表头 * * @param titleRow excel行 * @param clz 类型 * @return ExcelHeader集合 * @throws Excel4JException 异常 */ public static Map<Integer, ExcelHeader> getHeaderMap(Row titleRow, Class<?> clz) throws Excel4JException { List<ExcelHeader> headers = getHeaderList(clz); Map<Integer, ExcelHeader> maps = new HashMap<>(); for (Cell c : titleRow) { String title = c.getStringCellValue(); for (ExcelHeader eh : headers) { if (eh.getTitle().equals(title.trim())) { maps.put(c.getColumnIndex(), eh); break; } } } return maps; } /** * 获取单元格内容 * * @param c 单元格 * @return 单元格内容 */ public static String getCellValue(Cell c) { String o; switch (c.getCellType()) { case BLANK: o = ""; break; case BOOLEAN: o = String.valueOf(c.getBooleanCellValue()); break; case FORMULA: o = calculationFormula(c); break; case NUMERIC: if (DateUtil.isCellDateFormatted(c)) { o = DateUtils.date2Str(c.getDateCellValue()); } else { o = String.valueOf(c.getNumericCellValue()); o = matchDoneBigDecimal(o); o = RegularUtils.converNumByReg(o); } break; case STRING: o = c.getStringCellValue(); break; default: o = null; break; } return o; } /** * 字符串转对象 * * @param strField 字符串 * @param clazz 待转类型 * @return 转换后数据 */ public static Object str2TargetClass(String strField, Class<?> clazz) { if (null == strField || "".equals(strField)) return null; if ((Long.class == clazz) || (long.class == clazz)) { strField = matchDoneBigDecimal(strField); strField = RegularUtils.converNumByReg(strField); return Long.parseLong(strField); } if ((Integer.class == clazz) || (int.class == clazz)) { strField = matchDoneBigDecimal(strField); strField = RegularUtils.converNumByReg(strField); return Integer.parseInt(strField); } if ((Float.class == clazz) || (float.class == clazz)) { strField = matchDoneBigDecimal(strField); return Float.parseFloat(strField); } if ((Double.class == clazz) || (double.class == clazz)) { strField = matchDoneBigDecimal(strField); return Double.parseDouble(strField); } if ((Character.class == clazz) || (char.class == clazz)) { return strField.toCharArray()[0]; } if ((Boolean.class == clazz) || (boolean.class == clazz)) { return Boolean.parseBoolean(strField); } if (Date.class == clazz) { return DateUtils.str2DateUnmatch2Null(strField); } return strField; } /** * 科学计数法数据转换 * * @param bigDecimal 科学计数法 * @return 数据字符串 */ private static String matchDoneBigDecimal(String bigDecimal) { // 对科学计数法进行处理 boolean flg = Pattern.matches("^-?\\d+(\\.\\d+)?(E-?\\d+)?$", bigDecimal); if (flg) { BigDecimal bd = new BigDecimal(bigDecimal); bigDecimal = bd.toPlainString(); } return bigDecimal; } /** * <p>根据java对象属性{@link Field}获取该属性的getter或setter方法名, * 另对{@link boolean}及{@link Boolean}做了行管处理</p> * * @param clazz 操作对象 * @param fieldName 对象属性 * @param methodType 方法类型,getter或setter枚举 * @return getter或setter方法 * @throws IntrospectionException 异常 * @author Crab2Died */ public static Method getterOrSetter(Class clazz, String fieldName, FieldAccessType methodType) throws IntrospectionException { if (null == fieldName || "".equals(fieldName)) return null; BeanInfo beanInfo = Introspector.getBeanInfo(clazz); PropertyDescriptor[] props = beanInfo.getPropertyDescriptors(); for (PropertyDescriptor prop : props) { if (fieldName.equals(prop.getName())) { if (FieldAccessType.SETTER == methodType) { return prop.getWriteMethod(); } if (FieldAccessType.GETTER == methodType) { return prop.getReadMethod(); } } } throw new IntrospectionException("Can not get the getter or setter method"); } /** * <p>根据对象的属性名{@code fieldName}获取某个java的属性{@link java.lang.reflect.Field}</p> * * @param clazz java对象的class属性 * @param fieldName 属性名 * @return {@link java.lang.reflect.Field} java对象的属性 * @author Crab2Died */ private static Field matchClassField(Class clazz, String fieldName) { List<Field> fields = new ArrayList<>(); for (; clazz != Object.class; clazz = clazz.getSuperclass()) { fields.addAll(Arrays.asList(clazz.getDeclaredFields())); } for (Field field : fields) { if (fieldName.equals(field.getName())) { return field; } } throw new IllegalArgumentException("[" + clazz.getName() + "] can`t found field with [" + fieldName + "]"); } /** * 根据属性名与属性类型获取字段内容 * * @param bean 对象 * @param fieldName 字段名 * @param writeConvertible 写入转换器 * @return 对象指定字段内容 * @throws Excel4JException 异常 */ public static String getProperty(Object bean, String fieldName, WriteConvertible writeConvertible) throws Excel4JException { if (bean == null || fieldName == null) throw new IllegalArgumentException("Operating bean or filed class must not be null"); Method method; Object object; try { method = getterOrSetter(bean.getClass(), fieldName, FieldAccessType.GETTER); object = method.invoke(bean); } catch (IntrospectionException | IllegalAccessException | InvocationTargetException e) { throw new Excel4JException(e); } if (null != writeConvertible && writeConvertible.getClass() != DefaultConvertible.class) { // 写入转换器 object = writeConvertible.execWrite(object); } return object == null ? "" : object.toString(); } /** * 根据属性名与属性类型获取字段内容 * * @param bean 对象 * @param name 字段名 * @param value 字段类型 */ public static void copyProperty(Object bean, String name, Object value) throws Excel4JException { if (null == name || null == value) return; Field field = matchClassField(bean.getClass(), name); if (null == field) return; Method method; try { method = getterOrSetter(bean.getClass(), name, FieldAccessType.SETTER); if (value.getClass() == field.getType()) { method.invoke(bean, value); } else { method.invoke(bean, str2TargetClass(value.toString(), field.getType())); } } catch (IntrospectionException | IllegalAccessException | InvocationTargetException e) { throw new Excel4JException(e); } } /** * 计算公式结果 * * @param cell 单元格类型为公式的单元格 * @return 返回单元格计算后的值 格式化成String * @author QingMings * Email:[email protected] * date 2018-01-13 */ public static String calculationFormula(Cell cell) { CellValue cellValue = cell.getSheet().getWorkbook().getCreationHelper() .createFormulaEvaluator().evaluate(cell); return cellValue.formatAsString(); } }