All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.orion.office.excel.reader.ExcelBeanReader Maven / Gradle / Ivy

There is a newer version: 1.0.9
Show newest version
package com.orion.office.excel.reader;

import com.orion.lang.utils.Exceptions;
import com.orion.lang.utils.Objects1;
import com.orion.lang.utils.Strings;
import com.orion.lang.utils.Valid;
import com.orion.lang.utils.codec.Base64s;
import com.orion.lang.utils.reflect.Annotations;
import com.orion.lang.utils.reflect.Constructors;
import com.orion.lang.utils.reflect.Fields;
import com.orion.lang.utils.reflect.Methods;
import com.orion.office.excel.Excels;
import com.orion.office.excel.annotation.ImportField;
import com.orion.office.excel.annotation.ImportIgnore;
import com.orion.office.excel.option.CellOption;
import com.orion.office.excel.option.ImportFieldOption;
import com.orion.office.excel.type.ExcelReadType;
import org.apache.poi.ss.usermodel.*;

import java.io.ByteArrayOutputStream;
import java.io.OutputStream;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Consumer;

/**
 * excel bean 读取器
 * 

* 支持高级数据类型 *

* {@link Excels#getCellValue(Cell, ExcelReadType, CellOption)} * * @author Jiahang Li * @version 1.0.0 * @since 2021/1/6 17:10 */ public class ExcelBeanReader extends BaseExcelReader { private final Class targetClass; private final Constructor constructor; private final Map setters; /** * 如果列为null是否调用setter(null) */ private boolean nullInvoke; /** * 如果行为null是否添加一个新的实例对象 */ private boolean nullAddEmptyBean; public ExcelBeanReader(Workbook workbook, Sheet sheet, Class targetClass) { this(workbook, sheet, targetClass, new ArrayList<>(), null); } public ExcelBeanReader(Workbook workbook, Sheet sheet, Class targetClass, List store) { this(workbook, sheet, targetClass, store, null); } public ExcelBeanReader(Workbook workbook, Sheet sheet, Class targetClass, Consumer consumer) { this(workbook, sheet, targetClass, null, consumer); } protected ExcelBeanReader(Workbook workbook, Sheet sheet, Class targetClass, List rows, Consumer consumer) { super(workbook, sheet, rows, consumer); this.targetClass = Valid.notNull(targetClass, "target class is null"); this.constructor = Valid.notNull(Constructors.getDefaultConstructor(targetClass), "target class not found default constructor"); this.setters = new HashMap<>(); this.options = new HashMap<>(); this.analysisField(); this.init = false; } /** * 如果列为null是否调用setter(null) * * @return this */ public ExcelBeanReader nullInvoke() { this.nullInvoke = true; return this; } /** * 如果行为null是否添加实例对象 * * @return this */ public ExcelBeanReader nullAddEmptyBean() { this.nullAddEmptyBean = true; return this; } /** * 添加配置 * * @param field field * @param option 配置 * @return this */ public ExcelBeanReader option(String field, ImportFieldOption option) { this.addOption(field, option); return this; } /** * 添加配置 * * @param column 列 * @param field field * @param type 类型 * @return this */ public ExcelBeanReader option(int column, String field, ExcelReadType type) { this.addOption(field, new ImportFieldOption(column, type)); return this; } /** * 添加配置 * * @param field field * @param option 配置 */ @Override protected void addOption(String field, ImportFieldOption option) { Valid.notNull(option, "field option is null"); Valid.notNull(setters.get(field), "not found setter method ({}) in {}", field, targetClass); super.addOption(field, option); } @Override protected T parserRow(Row row) { if (row == null) { if (nullAddEmptyBean) { return Constructors.newInstance(constructor); } return null; } T t = Constructors.newInstance(constructor); options.forEach((field, option) -> { Method setter = setters.get(field); int index = option.getIndex(); Cell cell = row.getCell(index); Object value; if (option.getType().equals(ExcelReadType.PICTURE)) { // 图片 value = this.getPicture(setter, row.getRowNum(), index); } else { // 值 value = Excels.getCellValue(cell, option.getType(), option.getCellOption()); } if (value != null) { if (trim && value instanceof String) { value = ((String) value).trim(); } // 调用setter try { Methods.invokeSetterInfer(t, setter, value); } catch (Exception e) { // ignore } } else if (nullInvoke) { Methods.invokeMethod(t, setter, (Object) null); } }); return t; } /** * 读取图片 * * @param setter setter * @param row row * @param col col * @return value */ private Object getPicture(Method setter, int row, int col) { if (pictureParser == null) { return null; } // 获取图片 PictureData picture = pictureParser.getPicture(row, col); if (picture == null) { return null; } Class parameterType = setter.getParameterTypes()[0]; if (parameterType == String.class) { return Base64s.img64Encode(picture.getData(), picture.getMimeType()); } else if (parameterType == byte[].class) { return picture.getData(); } else if (parameterType == OutputStream.class || parameterType == ByteArrayOutputStream.class) { ByteArrayOutputStream out = new ByteArrayOutputStream(); try { out.write(picture.getData()); } catch (Exception e) { throw Exceptions.ioRuntime(e); } return out; } return null; } /** * 解析field */ private void analysisField() { // setter cache List setterMethodList = Methods.getSetterMethodsByCache(targetClass); // 扫描field List fieldList = Fields.getFieldsByCache(targetClass); for (Field field : fieldList) { this.analysisColumn(Annotations.getAnnotation(field, ImportField.class), Annotations.getAnnotation(field, ImportIgnore.class), Methods.getSetterMethodByField(targetClass, field), field.getName()); } // 扫描setter for (Method method : setterMethodList) { String fieldName = Fields.getFieldNameByMethod(method); setters.put(fieldName, method); // 解析 this.analysisColumn(Annotations.getAnnotation(method, ImportField.class), Annotations.getAnnotation(method, ImportIgnore.class), method, fieldName); } } /** * 解析 field ignore * * @param field field * @param ignore ignore * @param method method * @param fieldName fieldName */ private void analysisColumn(ImportField field, ImportIgnore ignore, Method method, String fieldName) { if (field == null || ignore != null) { return; } ImportFieldOption option = new ImportFieldOption(); option.setIndex(field.index()); option.setType(field.type()); String parseFormat = field.parseFormat(); if (!Strings.isEmpty(parseFormat)) { option.setCellOption(new CellOption(parseFormat)); } // 解析 this.analysisColumn(option, fieldName, method); } /** * 解析option * * @param option option * @param fieldName fieldName * @param method method */ private void analysisColumn(ImportFieldOption option, String fieldName, Method method) { Valid.notNull(option, "option is null"); Valid.notNull(method, fieldName + " setter method not found from " + targetClass); Valid.gte(option.getIndex(), 0, "index must >= 0"); // check ExcelReadType type = Objects1.def(option.getType(), ExcelReadType.TEXT); option.setType(type); // 判断是否支持流式操作 this.checkStreamingSupportType(type); Class parameterType = method.getParameterTypes()[0]; switch (type) { case LINK_ADDRESS: // 超链接 if (!parameterType.equals(String.class)) { throw Exceptions.parse("read hyperlink address parameter type must be String"); } break; case PICTURE: // 图片 if (!parameterType.equals(byte[].class) && !parameterType.equals(String.class) && !parameterType.equals(OutputStream.class) && !parameterType.equals(ByteArrayOutputStream.class)) { throw Exceptions.parse("read picture parameter type must be byte[], String, OutputStream or ByteArrayOutputStream"); } break; case TEXT: default: break; } options.put(fieldName, option); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy