...
 
Commits (4)
......@@ -12,8 +12,6 @@
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" scope="TEST" name="Maven: junit:junit:4.12" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.hamcrest:hamcrest-core:1.3" level="project" />
<orderEntry type="library" name="Maven: org.apache.poi:poi:3.17" level="project" />
<orderEntry type="library" name="Maven: commons-codec:commons-codec:1.10" level="project" />
<orderEntry type="library" name="Maven: org.apache.commons:commons-collections4:4.1" level="project" />
......@@ -35,8 +33,8 @@
<orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-databind:2.8.8" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-annotations:2.8.0" level="project" />
<orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-core:2.8.8" level="project" />
<orderEntry type="library" name="Maven: org.slf4j:slf4j-log4j12:1.7.25" level="project" />
<orderEntry type="library" name="Maven: log4j:log4j:1.2.17" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: junit:junit:4.12" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.hamcrest:hamcrest-core:1.3" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: mysql:mysql-connector-java:8.0.15" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: com.google.protobuf:protobuf-java:3.6.1" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.projectlombok:lombok:1.18.12" level="project" />
......
......@@ -11,7 +11,7 @@
<groupId>cn.yunmaozj.tools</groupId>
<artifactId>excel-tools</artifactId>
<version>1.6.2-SNAPSHOT</version>
<version>1.6.3-SNAPSHOT</version>
<packaging>jar</packaging>
<description>一个简单易用的Excel操作工具</description>
......@@ -57,14 +57,6 @@
<dependencies>
<!-- https://mvnrepository.com/artifact/junit/junit -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
......@@ -101,11 +93,12 @@
<version>1.2.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.slf4j/slf4j-log4j12 -->
<!-- https://mvnrepository.com/artifact/junit/junit -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.25</version>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
......@@ -122,6 +115,15 @@
<version>1.18.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.3</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
......
......@@ -36,14 +36,16 @@ public class DefaultExcelImport {
this.workbook = new XSSFWorkbook(inputStream);
}
public <T>List<T> getData(ImportSheet<T> sheet) throws IOException {
public <T> List<T> getData(ImportSheet<T> sheet) throws IOException {
return sheet.getData(workbook);
}
public <T>List<T> getData(String sheetName,ImportSheet<T> sheet) throws IOException {
return sheet.getData(sheetName,workbook);
public <T> List<T> getData(String sheetName, ImportSheet<T> sheet) throws IOException {
return sheet.getData(sheetName, workbook);
}
public <T>List<T> getData(int index,ImportSheet<T> sheet) throws IOException {
return sheet.getData(index,workbook);
public <T> List<T> getData(int index, ImportSheet<T> sheet) throws IOException {
return sheet.getData(index, workbook);
}
public static class ImportSheet<T> {
......@@ -74,7 +76,7 @@ public class DefaultExcelImport {
ExcelRowDataModel<T> excelRowDataModel = null;
int i = 0;
while (iterable.hasNext()) {
if (i++ == 0) {
if (i++ == 0) { // 读取第一行,确认表头
ExcelRowTitleModel excelRowTitleModel = new ExcelRowTitleModel(iterable.next());
excelRowDataModel = new ExcelRowDataModel<>(modelPropertyDescriptor, excelRowTitleModel);
} else {
......
package cn.yunmaozj.tools.excel.core.utils;
import cn.yunmaozj.tools.excel.exception.ExcelToolsException;
import cn.yunmaozj.tools.excel.model.ModelPropertyDescriptor;
import cn.yunmaozj.tools.excel.utils.StringUtils;
import cn.yunmaozj.tools.excel.utils.ValueSelector;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
......@@ -24,6 +26,9 @@ public class ExcelRowDataModel<T> {
public ExcelRowDataModel(ModelPropertyDescriptor<T> modelPropertyDescriptor, ExcelRowTitleModel excelRowTitleModel) {
this.modelPropertyDescriptor = modelPropertyDescriptor;
this.excelRowTitleModel = excelRowTitleModel;
for (String modeTitle : modelPropertyDescriptor.modelTitle()) {
}
}
public T getEntity(Row row) {
......@@ -34,9 +39,17 @@ public class ExcelRowDataModel<T> {
String excelTitle = excelRowTitleModel.getTitle(i);
PropertyDescriptor propertyDescriptor = modelPropertyDescriptor.getPropertyDescriptorByExcelTitle(excelTitle);
Field field = modelPropertyDescriptor.getFiledByExcelTitle(excelTitle);
if (propertyDescriptor != null && field != null) {
Object value = ValueSelector.select(cell, field);
propertyDescriptor.getWriteMethod().invoke(entity, value);
//判断数据是否为空,这里应该放到selector里面
if (cell == null) {
if (modelPropertyDescriptor.getExcelFieldRowByExcelTitle(excelTitle).require())
throw new ExcelToolsException("数据为空", row.getRowNum(), i + 1, excelTitle);
} else {
Object value = ValueSelector.select(cell, field);
propertyDescriptor.getWriteMethod().invoke(entity, value);
}
}
}
return entity;
......
......@@ -19,7 +19,6 @@ public class ExcelRowTitleModel {
* 表头
*/
private Cell[] titles;
private String[] excelTitles;
private Row row;
public ExcelRowTitleModel(Row row) {
......
......@@ -90,15 +90,15 @@ public class DataBaseTableModel {
*/
public static class Column {
@ExcelFieldRow("字段名")
@ExcelFieldRow(title = "字段名")
private String name;
@ExcelFieldRow("数据类型")
@ExcelFieldRow(title = "数据类型")
private String type;
@ExcelFieldRow("备注")
@ExcelFieldRow(title = "备注")
private String comment;
@ExcelFieldRow("字符集")
@ExcelFieldRow(title = "字符集")
private String charset;
@ExcelFieldRow("是否可以为空")
@ExcelFieldRow(title = "是否可以为空")
private boolean isNull;
public String getName() {
......
package cn.yunmaozj.tools.excel.exception;
/**
* @author zhongminghong
* @email zhongmh@yunmaozj.com
* @create 2020-07-15 10:04
*/
public class ExcelToolsException extends RuntimeException {
private int rowNumber;
private int cellNumber;
private String title;
public ExcelToolsException(String message, int rowNumber, int cellNumber, String title) {
super(message);
this.rowNumber = rowNumber;
this.cellNumber = cellNumber;
this.title = title;
}
@Override
public String getMessage() {
return "第" + rowNumber + "行" + cellNumber + "列标题 " + title + ":" + super.getMessage();
}
}
......@@ -31,7 +31,9 @@ public class ModelPropertyDescriptor<T> {
private Map<String, Field> excelTitleFieldMap = new HashMap<>();
private Map<String, ExcelFieldRow> modelTitleFileMap = new HashMap<>();
private Map<String, ExcelFieldRow> modelTitleExcelFieldRowMap = new HashMap<>();
private Map<String, ExcelFieldRow> excelTitleExcelFieldRowMap = new HashMap<>();
/**
* 这个导入的时候提供的构造方法,或过滤掉没有的字段
......@@ -44,12 +46,13 @@ public class ModelPropertyDescriptor<T> {
Arrays.stream(fields)
.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())))
excelTitle.contains(F.getAnnotation(ExcelFieldRow.class).title())))
.forEach((F) -> {
ExcelFieldRow excelTitleRow = F.getAnnotation(ExcelFieldRow.class);
excelTitleRowFieldMap.put(excelTitleRow, F);
excelTitleFieldMap.put(excelTitleRow.value(), F);
modelTitleFileMap.put(F.getName(), excelTitleRow);
excelTitleFieldMap.put(excelTitleRow.title(), F);
modelTitleExcelFieldRowMap.put(F.getName(), excelTitleRow);
excelTitleExcelFieldRowMap.put(excelTitleRow.title(), excelTitleRow);
});
Set<ExcelFieldRow> excelTitleRowSet = new TreeSet<>(new Comparator<ExcelFieldRow>() {
@Override
......@@ -64,13 +67,53 @@ public class ModelPropertyDescriptor<T> {
try {
PropertyDescriptor propertyDescriptor = getPropertyDescriptor(field);
modelFieldPropertyDescriptorMap.put(field.getName(), propertyDescriptor);
excelTitlePropertyDescriptorMap.put(ETR.value(), propertyDescriptor);
excelTitlePropertyDescriptorMap.put(ETR.title(), propertyDescriptor);
} catch (IntrospectionException e) {
e.printStackTrace();
}
});
}
/**
* 通过excel表头对象获取ExcelFieldRow 信息
*
* @param title
* @return
*/
public ExcelFieldRow getExcelFieldRowByExcelTitle(String title) {
return excelTitleExcelFieldRowMap.get(title);
}
public ExcelFieldRow getExcelFieldRowByModelTitle(String title) {
return modelTitleExcelFieldRowMap.get(title);
}
public Map<ExcelFieldRow, Field> getExcelTitleRowFieldMap() {
return Collections.unmodifiableMap(excelTitleRowFieldMap);
}
public Map<String, Field> getExcelTitleFieldMap() {
return Collections.unmodifiableMap(excelTitleFieldMap);
}
/**
* 返回 字段表头 和 ExcelFieldRow 的map
*
* @return
*/
public Map<String, ExcelFieldRow> getModelTitleExcelFieldRowMap() {
return Collections.unmodifiableMap(modelTitleExcelFieldRowMap);
}
/**
* 返回 excel 表头 和 ExcelFieldRow 的map
*
* @return
*/
public Map<String, ExcelFieldRow> getExcelTitleExcelFieldRowMap() {
return Collections.unmodifiableMap(excelTitleExcelFieldRowMap);
}
/**
* 这个是导出的时候提供的构造方法,会自动解析类的字段注解
......
......@@ -16,8 +16,11 @@ import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
public @interface ExcelFieldRow {
String value();
/**
* excel 表头,如果没有默认采用字段名
* @return
*/
String title();
/**
* 是否必填
*
......
package cn.yunmaozj.tools.excel.utils;
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.util.StringUtil;
import java.lang.reflect.Field;
import java.math.BigDecimal;
......@@ -16,7 +16,13 @@ import static org.apache.poi.ss.usermodel.CellType.STRING;
* @email zhongmh@yunmaozj.com
* @create 2020-06-24 17:03
*/
public class ValueSelector {
public class ValueSelector<T> {
private ModelPropertyDescriptor<T> modelPropertyDescriptor;
public ValueSelector(ModelPropertyDescriptor<T> modelPropertyDescriptor) {
this.modelPropertyDescriptor = modelPropertyDescriptor;
}
public static Object select(Cell cell, Field field) {
if (field.getType().equals(String.class)) {
......
......@@ -19,16 +19,16 @@ import org.openxmlformats.schemas.spreadsheetml.x2006.main.impl.WorkbookDocument
@AllArgsConstructor
public class UserModel {
@ExcelFieldRow("年龄")
@ExcelFieldRow(title = "年龄")
private Integer age;
@ExcelFieldRow(value = "姓名", sort = 2)
@ExcelFieldRow(title = "姓名", sort = 2)
private String name;
@ExcelFieldRow(value = "薪水", sort = 1)
@ExcelFieldRow(title = "薪水", sort = 1)
private Double salary;
@ExcelFieldRow(value = "邮箱")
@ExcelFieldRow(title = "邮箱")
private String email;
//备注
private String remarks;
......
......@@ -19,34 +19,34 @@ import lombok.ToString;
@Sheet("作品")
public class OpusModel {
@ExcelFieldRow("标题")
@ExcelFieldRow(title = "标题")
private String title;
@ExcelFieldRow("内容")
@ExcelFieldRow(title = "内容")
private String content;
@ExcelFieldRow("手机号")
@ExcelFieldRow(title = "手机号", require = true)
private String mobile;
@ExcelFieldRow("资源")
@ExcelFieldRow(title = "资源")
private String resource;
@ExcelFieldRow("作品类型")
@ExcelFieldRow(title = "作品类型", require = true)
private String opusType;
@ExcelFieldRow("话题")
@ExcelFieldRow(title = "话题")
private String topics;
@ExcelFieldRow("browseNumber")
private Integer browseNumber;
@ExcelFieldRow(title = "点赞数量")
private Integer likeNumber;
@ExcelFieldRow("like number")
private int likeNumber;
@ExcelFieldRow(title = "浏览数量")
private Integer browseNumber;
@ExcelFieldRow("opus weight")
@ExcelFieldRow(title = "opus weight")
private Double opusWeight;
@ExcelFieldRow("sys weight")
@ExcelFieldRow(title = "sys weight")
private double sysWeight;
public String getTitle() {
......@@ -105,11 +105,11 @@ public class OpusModel {
this.browseNumber = browseNumber;
}
public int getLikeNumber() {
public Integer getLikeNumber() {
return likeNumber;
}
public void setLikeNumber(int likeNumber) {
public void setLikeNumber(Integer likeNumber) {
this.likeNumber = likeNumber;
}
......
......@@ -35,6 +35,7 @@ public class DefaultExcelImportTest {
model.setResource("/2020/22/2/2/2.jpg");
model.setOpusType("video");
model.setTopics("test");
model.setLikeNumber(null);
DefaultExcelExport excelExport = new DefaultExcelExport();
excelExport.writeData(new DefaultExcelExport.ExportSheet(OpusModel.class, Arrays.asList(model)));
......