Commit daa2b629 by 钟明宏

推个代码测试一下

parent f53b4cfe
package cn.yunmaozj.tools.excel.core;
import cn.yunmaozj.tools.excel.core.utils.ExcelRowDataModel;
import cn.yunmaozj.tools.excel.core.utils.ExcelRowTitleModel;
import cn.yunmaozj.tools.excel.model.ModelPropertyDescriptor;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import java.io.*;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
/**
* 默认的excel导入工具
*
* @author zhongminghong
* @email zhongmh@yunmaozj.com
* @create 2020-06-24 15:04
*/
public class DefaultExcelImport<T> {
private ModelPropertyDescriptor modelPropertyDescriptor;
private InputStream inputStream;
public DefaultExcelImport(Class<T> model, String path) throws FileNotFoundException {
this(model, new File(path));
}
public DefaultExcelImport(Class<T> model, File file) throws FileNotFoundException {
this(model, new FileInputStream(file));
}
public DefaultExcelImport(Class<T> model, InputStream inputStream) {
this.modelPropertyDescriptor = new ModelPropertyDescriptor(model);
this.inputStream = inputStream;
}
public List<T> getData() throws IOException {
List<T> data = new ArrayList<>();
Workbook workbook = new XSSFWorkbook(inputStream);
Sheet sheet = workbook.getSheet("Sheet1");
Iterator<Row> iterable = sheet.rowIterator();
ExcelRowDataModel<T> excelRowDataModel = null;
int i = 0;
while (iterable.hasNext()) {
if (i++ == 0) {
ExcelRowTitleModel excelRowTitleModel = new ExcelRowTitleModel(iterable.next());
excelRowDataModel = new ExcelRowDataModel<>(modelPropertyDescriptor, excelRowTitleModel);
} else {
T entity = excelRowDataModel.getEntity(iterable.next());
data.add(entity);
}
}
return data;
}
}
......@@ -2,6 +2,7 @@ package cn.yunmaozj.tools.excel.core;
import java.util.Map;
import cn.yunmaozj.tools.excel.core.utils.ValueSelector;
import cn.yunmaozj.tools.excel.utils.StringUtils;
import cn.yunmaozj.tools.excel.utils.TagUtils;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
......@@ -13,7 +14,6 @@ import org.apache.poi.ss.util.RegionUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import cn.yunmaozj.tools.excel.core.utils.ValueSelector;
/**
* @author 24252
......
package cn.yunmaozj.tools.excel.core.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* excel 标题行注解,用于标注实体字段
*
* @author zhongminghong
* @email zhongmh@yunmaozj.com
* @create 2020-04-15 18:17
*/
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface ExcelTitleRow {
/**
* excel 中显示的标题
*
* @return
*/
String value();
/**
* 标题排序字段 默认降序
*
* @return
*/
int sort() default 0;
}
package cn.yunmaozj.tools.excel.core.utils;
import cn.yunmaozj.tools.excel.model.ModelPropertyDescriptor;
import cn.yunmaozj.tools.excel.utils.ValueSelector;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
/**
* 数据行对象
*
* @author zhongminghong
* @email zhongmh@yunmaozj.com
* @create 2020-06-24 15:34
*/
public class ExcelRowDataModel<T> {
private ModelPropertyDescriptor<T> modelPropertyDescriptor;
private ExcelRowTitleModel excelRowTitleModel;
public ExcelRowDataModel(ModelPropertyDescriptor<T> modelPropertyDescriptor, ExcelRowTitleModel excelRowTitleModel) {
this.modelPropertyDescriptor = modelPropertyDescriptor;
this.excelRowTitleModel = excelRowTitleModel;
}
public T getEntity(Row row) {
try {
T entity = modelPropertyDescriptor.getInstance();
for (int i = 0; i < row.getLastCellNum(); i++) {
Cell cell = row.getCell(i);
String excelTitle = excelRowTitleModel.getTitle(i);
PropertyDescriptor propertyDescriptor = modelPropertyDescriptor.getPropertyDescriptorByExcelTitle(excelTitle);
Field field = modelPropertyDescriptor.getFiledByExcelTitle(excelTitle);
if (propertyDescriptor != null && field != null) {
propertyDescriptor.getWriteMethod().invoke(entity, ValueSelector.select(cell, field));
}
}
return entity;
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
return null;
}
}
package cn.yunmaozj.tools.excel.core.utils;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import java.util.List;
/**
* @author zhongminghong
* @email zhongmh@yunmaozj.com
* @create 2020-06-24 15:35
*/
public class ExcelRowTitleModel {
/**
* 表头
*/
private Cell[] titles;
public ExcelRowTitleModel(Row row) {
titles = new Cell[row.getLastCellNum()];
for (int i = 0; i < titles.length; i++) {
titles[i] = row.getCell(i);
}
}
public String getTitle(int index) {
return titles[index].getStringCellValue();
}
}
package cn.yunmaozj.tools.excel.database;
import cn.yunmaozj.tools.excel.core.Excel;
import cn.yunmaozj.tools.excel.core.annotation.ExcelTitleRow;
import cn.yunmaozj.tools.excel.model.annotations.ExcelFieldRow;
import java.util.List;
......@@ -90,15 +90,15 @@ public class DataBaseTableModel {
*/
public static class Column {
@ExcelTitleRow("字段名")
@ExcelFieldRow("字段名")
private String name;
@ExcelTitleRow("数据类型")
@ExcelFieldRow("数据类型")
private String type;
@ExcelTitleRow("备注")
@ExcelFieldRow("备注")
private String comment;
@ExcelTitleRow("字符集")
@ExcelFieldRow("字符集")
private String charset;
@ExcelTitleRow("是否可以为空")
@ExcelFieldRow("是否可以为空")
private boolean isNull;
public String getName() {
......
package cn.yunmaozj.tools.excel.utils;
package cn.yunmaozj.tools.excel.model;
import cn.yunmaozj.tools.excel.core.annotation.ExcelTitleRow;
import cn.yunmaozj.tools.excel.model.annotations.ExcelFieldRow;
import java.beans.IntrospectionException;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.util.*;
/**
......@@ -14,6 +15,7 @@ import java.util.*;
*/
public class ModelPropertyDescriptor<T> {
private final Class<T> model;
/**
* 模型类对应的 方法属性描述其
*/
......@@ -24,36 +26,37 @@ public class ModelPropertyDescriptor<T> {
*/
private Map<String, PropertyDescriptor> excelTitlePropertyDescriptorMap = new LinkedHashMap<>();
private Map<ExcelTitleRow, Field> excelTitleRowFieldMap = new LinkedHashMap<>();
private Map<ExcelFieldRow, Field> excelTitleRowFieldMap = new LinkedHashMap<>();
private Map<String, Field> excelTitleFieldMap = new HashMap<>();
private Map<String, ExcelTitleRow> modelTitleFileMap = new HashMap<>();
private Map<String, ExcelFieldRow> modelTitleFileMap = new HashMap<>();
/**
* 这个导入的时候提供的构造方法,或过滤掉没有的字段
*
* @param clazz
* @param model
*/
public ModelPropertyDescriptor(Class<T> clazz,List<String> excelTitle) {
Field[] fields = clazz.getDeclaredFields();
public ModelPropertyDescriptor(Class<T> model, List<String> excelTitle) {
this.model = model;
Field[] fields = model.getDeclaredFields();
Arrays.stream(fields)
.filter(F -> (excelTitle.size() == 0 && F.getAnnotation(ExcelTitleRow.class) != null) ||
(excelTitle.size() != 0 && F.getAnnotation(ExcelTitleRow.class) != null &&
excelTitle.contains(F.getAnnotation(ExcelTitleRow.class).value())))
.filter(F -> (excelTitle.size() == 0 && F.getAnnotation(ExcelFieldRow.class) != null) ||
(excelTitle.size() != 0 && F.getAnnotation(ExcelFieldRow.class) != null &&
excelTitle.contains(F.getAnnotation(ExcelFieldRow.class).value())))
.forEach((F) -> {
ExcelTitleRow excelTitleRow = F.getAnnotation(ExcelTitleRow.class);
ExcelFieldRow excelTitleRow = F.getAnnotation(ExcelFieldRow.class);
excelTitleRowFieldMap.put(excelTitleRow, F);
excelTitleFieldMap.put(excelTitleRow.value(), F);
modelTitleFileMap.put(F.getName(), excelTitleRow);
});
Set<ExcelTitleRow> excelTitleRowSet = new TreeSet<>(new Comparator<ExcelTitleRow>() {
Set<ExcelFieldRow> excelTitleRowSet = new TreeSet<>(new Comparator<ExcelFieldRow>() {
@Override
public int compare(ExcelTitleRow o1, ExcelTitleRow o2) {
public int compare(ExcelFieldRow o1, ExcelFieldRow o2) {
return o1.sort() > o2.sort() ? -1 : 1;
}
});
Set<ExcelTitleRow> excelTitleRowSet1 = excelTitleRowFieldMap.keySet();
Set<ExcelFieldRow> excelTitleRowSet1 = excelTitleRowFieldMap.keySet();
excelTitleRowSet.addAll(excelTitleRowSet1);
excelTitleRowSet.stream().forEach((ETR) -> {
Field field = excelTitleRowFieldMap.get(ETR);
......@@ -67,12 +70,14 @@ public class ModelPropertyDescriptor<T> {
});
}
/**
* 这个是导出的时候提供的构造方法,会自动解析类的字段注解
*
* @param clazz
*/
public ModelPropertyDescriptor(Class<T> clazz) {
this(clazz,new ArrayList<>());
this(clazz, new ArrayList<>());
}
/**
......@@ -94,7 +99,42 @@ public class ModelPropertyDescriptor<T> {
return modelFieldPropertyDescriptorMap.keySet();
}
/**
* 通过excel的标题获取字段对象
*
* @param excelTitle
* @return
*/
public Field getFiledByExcelTitle(String excelTitle) {
return excelTitleFieldMap.get(excelTitle);
}
/**
* 根据excel标题获取类属性描述对象
*
* @param excelTitle
* @return
*/
public PropertyDescriptor getPropertyDescriptorByExcelTitle(String excelTitle) {
return excelTitlePropertyDescriptorMap.get(excelTitle);
}
/**
* 根据字段名字获取 类属性描述对象
*
* @param fieldName
* @return
*/
public PropertyDescriptor getPropertyDescriptorByFieldName(String fieldName) {
return modelFieldPropertyDescriptorMap.get(fieldName);
}
private PropertyDescriptor getPropertyDescriptor(Field field) throws IntrospectionException {
return new PropertyDescriptor(field.getName(), field.getDeclaringClass());
}
public T getInstance() throws IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {
return this.model.getDeclaredConstructor().newInstance();
}
}
......@@ -14,9 +14,10 @@ import java.lang.annotation.Target;
*/
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface ExcelField {
public @interface ExcelFieldRow {
String value();
/**
* 是否必填
*
......@@ -37,6 +38,27 @@ public @interface ExcelField {
* @return
*/
String[] allowableValues() default {};
/**
* 用正则匹配
*
* @return
*/
String regex() default "";
/**
* 默认值
*
* @return
*/
String defaultValue() default "";
/**
* 参数最大值
*
* @return
*/
int maxLength() default 0;
}
package cn.yunmaozj.tools.excel.model.annotations;
import java.lang.annotation.*;
/**
* 生成文件信息的注解
* @author 24252
*
*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface ExcelSummaryInformation {
//设置xls文件的作者信息
String author() default "zhongmh";
//创建程序信息
String applicationName() default "excel-tools";
//文件最后保存的信息
String lastAuthor() default "zhongmh";
//增加文件作者信息
String comments() default "未来的架构师";
//增加文件的标题信息
String title() default "标题";
//增加文件标题信息
String subject() default "增加文件主题信息";
boolean createDateTime() default false;
/**
* 自适应大小
* @return
*/
boolean autoSizeColumn() default true;
}
package cn.yunmaozj.tools.excel.model.annotations;
import java.lang.annotation.*;
/**
* @author zhongminghong
* @email zhongmh@yunmaozj.com
* @create 2020-06-24 15:10
*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Sheet {
String value();
}
package cn.yunmaozj.tools.excel.utils;
import cn.yunmaozj.tools.excel.model.ModelPropertyDescriptor;
/**
* 模型工具
*
......
package cn.yunmaozj.tools.excel.utils;
import org.apache.poi.ss.usermodel.Cell;
import java.lang.reflect.Field;
import java.math.BigDecimal;
import static org.apache.poi.ss.usermodel.CellType.BOOLEAN;
import static org.apache.poi.ss.usermodel.CellType.NUMERIC;
import static org.apache.poi.ss.usermodel.CellType.STRING;
/**
* @author zhongminghong
* @email zhongmh@yunmaozj.com
* @create 2020-06-24 17:03
*/
public class ValueSelector {
public static Object select(Cell cell, Field field) {
if (field.getType().equals(String.class)) {
if (cell.getCellTypeEnum() == STRING) {
return cell.getStringCellValue();
}
if (cell.getCellTypeEnum() == BOOLEAN) {
return Boolean.toString(cell.getBooleanCellValue());
}
if (cell.getCellTypeEnum() == NUMERIC) {
return new BigDecimal(cell.getNumericCellValue()).toString();
}
return null;
}
if (field.getType().equals(Integer.class)) {
if (cell.getCellTypeEnum() == STRING) {
return Integer.parseInt(cell.getStringCellValue());
}
if (cell.getCellTypeEnum() == BOOLEAN) {
return cell.getBooleanCellValue() ? 0 : 1;
}
if (cell.getCellTypeEnum() == NUMERIC) {
return new BigDecimal(cell.getNumericCellValue()).intValue();
}
return false;
}
return cell;
}
}
package cn.yunmaozj.tools.excel.core;
import cn.yunmaozj.tools.excel.AbstractExcelToolsTest;
import org.junit.Before;
import org.junit.Test;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
/**
* @author zhongminghong
* @email zhongmh@yunmaozj.com
* @create 2020-04-15 17:00
*/
public class TestDemo extends AbstractExcelToolsTest {
@Before
public void setUp() {
}
@Test
public void test() throws IOException {
}
}
package cn.yunmaozj.tools.excel.core.annotation;
import cn.yunmaozj.tools.excel.AbstractExcelToolsTest;
import org.junit.Test;
import java.lang.reflect.Field;
/**
* @author zhongminghong
* @email zhongmh@yunmaozj.com
* @create 2020-04-15 18:22
*/
public class ExcelTitleRowTest extends AbstractExcelToolsTest {
@Test
public void analyze() {
Class<TestModel> clazz = TestModel.class;
//获取所有的属性
Field[] fields = clazz.getDeclaredFields();
for (Field field : fields) {
System.out.println(field.getName());
}
}
class TestModel {
@ExcelTitleRow("年龄")
private Integer age;
@ExcelTitleRow(value = "姓名", sort = 2)
private String name;
@ExcelTitleRow(value = "薪水", sort = 1)
private Double salary;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public Double getSalary() {
return salary;
}
public void setSalary(Double salary) {
this.salary = salary;
}
}
}
package cn.yunmaozj.tools.excel.utils;
package cn.yunmaozj.tools.excel.model;
import cn.yunmaozj.tools.excel.AbstractExcelToolsTest;
import cn.yunmaozj.tools.excel.core.annotation.ExcelTitleRow;
import org.junit.Assert;
import org.junit.Test;
......@@ -22,7 +21,7 @@ public class ModelPropertyDescriptorTest extends AbstractExcelToolsTest {
*/
@Test
public void excelTitle() {
ModelPropertyDescriptor<ModelTest> descriptor = new ModelPropertyDescriptor<>(ModelTest.class);
ModelPropertyDescriptor<UserModel> descriptor = new ModelPropertyDescriptor<>(UserModel.class);
Set<String> stringSet = descriptor.excelTitle();
String[] titles = stringSet.toArray(new String[stringSet.size()]);
Assert.assertEquals("姓名", titles[0]);
......@@ -30,7 +29,7 @@ public class ModelPropertyDescriptorTest extends AbstractExcelToolsTest {
Assert.assertEquals("年龄", titles[2]);
Assert.assertEquals("邮箱", titles[3]);
//测试一下过滤后的属性
descriptor = new ModelPropertyDescriptor<>(ModelTest.class, Arrays.asList("姓名", "薪水", "邮箱"));
descriptor = new ModelPropertyDescriptor<>(UserModel.class, Arrays.asList("姓名", "薪水", "邮箱"));
stringSet = descriptor.excelTitle();
titles = stringSet.toArray(new String[stringSet.size()]);
Assert.assertTrue(3 == titles.length);
......@@ -44,7 +43,7 @@ public class ModelPropertyDescriptorTest extends AbstractExcelToolsTest {
*/
@Test
public void modelTitle() {
ModelPropertyDescriptor<ModelTest> descriptor = new ModelPropertyDescriptor<>(ModelTest.class);
ModelPropertyDescriptor<UserModel> descriptor = new ModelPropertyDescriptor<>(UserModel.class);
Set<String> fieldSets = descriptor.modelTitle();
Assert.assertThat(fieldSets.size(), is(4));
Assert.assertTrue(fieldSets.contains("age"));
......@@ -52,71 +51,11 @@ public class ModelPropertyDescriptorTest extends AbstractExcelToolsTest {
Assert.assertTrue(fieldSets.contains("salary"));
Assert.assertTrue(fieldSets.contains("email"));
//测试一下过滤后的属性
descriptor = new ModelPropertyDescriptor<>(ModelTest.class, Arrays.asList("姓名", "薪水", "邮箱"));
descriptor = new ModelPropertyDescriptor<>(UserModel.class, Arrays.asList("姓名", "薪水", "邮箱"));
fieldSets = descriptor.modelTitle();
Assert.assertThat(fieldSets.size(), is(3));
Assert.assertTrue(fieldSets.contains("name"));
Assert.assertTrue(fieldSets.contains("salary"));
Assert.assertTrue(fieldSets.contains("email"));
}
/**
* 测试模拟模型类
*/
class ModelTest {
@ExcelTitleRow("年龄")
private Integer age;
@ExcelTitleRow(value = "姓名", sort = 2)
private String name;
@ExcelTitleRow(value = "薪水", sort = 1)
private Double salary;
@ExcelTitleRow(value = "邮箱")
private String email;
//备注
private String remarks;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public Double getSalary() {
return salary;
}
public void setSalary(Double salary) {
this.salary = salary;
}
public String getRemarks() {
return remarks;
}
public void setRemarks(String remarks) {
this.remarks = remarks;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {