From d011846d84ceb24d71e29c9b3473f32c116b5b5c Mon Sep 17 00:00:00 2001
From: wangbing <1919101440@qq.com>
Date: Mon, 11 Nov 2019 00:00:36 +0800
Subject: [PATCH] init
---
.gitignore | 16 +
pom.xml | 40 +
src/main/java/com/wb/excel/api/Excel.java | 341 +++++
.../com/wb/excel/api/annotation/Enum.java | 17 +
.../wb/excel/api/annotation/EnumValue.java | 26 +
.../excel/api/annotation/ExcelCollection.java | 39 +
.../wb/excel/api/annotation/ExcelVerify.java | 94 ++
.../api/annotation/HeaderDescription.java | 17 +
.../wb/excel/api/annotation/HeaderName.java | 31 +
.../wb/excel/api/annotation/IsDuplicated.java | 17 +
.../com/wb/excel/api/annotation/NoRepeat.java | 17 +
.../wb/excel/api/annotation/ParentFirst.java | 16 +
.../com/wb/excel/api/annotation/Split.java | 28 +
.../wb/excel/api/annotation/Substring.java | 18 +
.../com/wb/excel/api/annotation/Type.java | 19 +
.../java/com/wb/excel/api/datatable/Cell.java | 59 +
.../com/wb/excel/api/datatable/Column.java | 109 ++
.../com/wb/excel/api/datatable/DataExcel.java | 60 +
.../com/wb/excel/api/datatable/DataRow.java | 14 +
.../com/wb/excel/api/datatable/DataTable.java | 1194 +++++++++++++++++
.../wb/excel/api/datatable/ExcelImport.java | 601 +++++++++
.../wb/excel/api/datatable/ImportParams.java | 62 +
.../wb/excel/api/entity/DataVerifyResult.java | 51 +
.../api/entity/ExcelCollectionEntity.java | 61 +
.../com/wb/excel/api/entity/ExcelEntity.java | 124 ++
.../excel/api/entity/ExcelImportEntity.java | 37 +
.../excel/api/entity/ExcelImportResult.java | 183 +++
.../excel/api/entity/ExcelVerifyEntity.java | 141 ++
.../wb/excel/api/enumeration/DataType.java | 119 ++
.../com/wb/excel/api/enumeration/Gender.java | 18 +
.../com/wb/excel/api/enumeration/Status.java | 50 +
.../com/wb/excel/api/enumeration/YesNo.java | 18 +
.../ColumnNameNotExistException.java | 32 +
.../com/wb/excel/api/exception/Error.java | 52 +
.../com/wb/excel/api/exception/ErrorType.java | 38 +
.../exception/ExistedColumnNameException.java | 32 +
.../exception/IllegalParameterException.java | 32 +
.../exception/TemplateNotMatchException.java | 29 +
.../wb/excel/api/interfaces/EnumSupport.java | 38 +
.../api/interfaces/IExcelVerifyHandler.java | 34 +
.../com/wb/excel/api/style/BaseCellStyle.java | 29 +
.../java/com/wb/excel/api/style/BaseFont.java | 29 +
.../api/style/CheckFailureCellStyle.java | 44 +
.../api/style/CheckMessageCellStyle.java | 24 +
.../api/style/CheckSuccessCellStyle.java | 40 +
.../wb/excel/api/style/ErrorCellStyle.java | 39 +
.../excel/api/style/ErrorNumberCellStyle.java | 17 +
.../com/wb/excel/api/style/HeadCellStyle.java | 39 +
.../wb/excel/api/style/NormalCellStyle.java | 28 +
.../com/wb/excel/api/style/NormalFont.java | 18 +
.../api/style/NormalNumberCellStyle.java | 17 +
.../java/com/wb/excel/api/style/RedFont.java | 18 +
.../com/wb/excel/api/util/BaseVerifyUtil.java | 135 ++
.../java/com/wb/excel/api/util/ClassUtil.java | 195 +++
.../com/wb/excel/api/util/DataTableUtil.java | 46 +
.../java/com/wb/excel/api/util/EnumUtil.java | 127 ++
.../java/com/wb/excel/api/util/ExcelUtil.java | 32 +
.../com/wb/excel/api/util/StringUtil.java | 206 +++
.../com/wb/excel/api/util/StringUtils.java | 146 ++
.../com/wb/excel/api/util/TransferUtil.java | 101 ++
.../com/wb/excel/api/util/ValidationUtil.java | 241 ++++
.../com/wb/excel/api/util/VerifyDataUtil.java | 64 +
src/test/java/ExampleTest.java | 109 ++
src/test/java/User.java | 55 +
64 files changed, 5723 insertions(+)
create mode 100644 pom.xml
create mode 100644 src/main/java/com/wb/excel/api/Excel.java
create mode 100644 src/main/java/com/wb/excel/api/annotation/Enum.java
create mode 100644 src/main/java/com/wb/excel/api/annotation/EnumValue.java
create mode 100644 src/main/java/com/wb/excel/api/annotation/ExcelCollection.java
create mode 100644 src/main/java/com/wb/excel/api/annotation/ExcelVerify.java
create mode 100644 src/main/java/com/wb/excel/api/annotation/HeaderDescription.java
create mode 100644 src/main/java/com/wb/excel/api/annotation/HeaderName.java
create mode 100644 src/main/java/com/wb/excel/api/annotation/IsDuplicated.java
create mode 100644 src/main/java/com/wb/excel/api/annotation/NoRepeat.java
create mode 100644 src/main/java/com/wb/excel/api/annotation/ParentFirst.java
create mode 100644 src/main/java/com/wb/excel/api/annotation/Split.java
create mode 100644 src/main/java/com/wb/excel/api/annotation/Substring.java
create mode 100644 src/main/java/com/wb/excel/api/annotation/Type.java
create mode 100644 src/main/java/com/wb/excel/api/datatable/Cell.java
create mode 100644 src/main/java/com/wb/excel/api/datatable/Column.java
create mode 100644 src/main/java/com/wb/excel/api/datatable/DataExcel.java
create mode 100644 src/main/java/com/wb/excel/api/datatable/DataRow.java
create mode 100644 src/main/java/com/wb/excel/api/datatable/DataTable.java
create mode 100644 src/main/java/com/wb/excel/api/datatable/ExcelImport.java
create mode 100644 src/main/java/com/wb/excel/api/datatable/ImportParams.java
create mode 100644 src/main/java/com/wb/excel/api/entity/DataVerifyResult.java
create mode 100644 src/main/java/com/wb/excel/api/entity/ExcelCollectionEntity.java
create mode 100644 src/main/java/com/wb/excel/api/entity/ExcelEntity.java
create mode 100644 src/main/java/com/wb/excel/api/entity/ExcelImportEntity.java
create mode 100644 src/main/java/com/wb/excel/api/entity/ExcelImportResult.java
create mode 100644 src/main/java/com/wb/excel/api/entity/ExcelVerifyEntity.java
create mode 100644 src/main/java/com/wb/excel/api/enumeration/DataType.java
create mode 100644 src/main/java/com/wb/excel/api/enumeration/Gender.java
create mode 100644 src/main/java/com/wb/excel/api/enumeration/Status.java
create mode 100644 src/main/java/com/wb/excel/api/enumeration/YesNo.java
create mode 100644 src/main/java/com/wb/excel/api/exception/ColumnNameNotExistException.java
create mode 100644 src/main/java/com/wb/excel/api/exception/Error.java
create mode 100644 src/main/java/com/wb/excel/api/exception/ErrorType.java
create mode 100644 src/main/java/com/wb/excel/api/exception/ExistedColumnNameException.java
create mode 100644 src/main/java/com/wb/excel/api/exception/IllegalParameterException.java
create mode 100644 src/main/java/com/wb/excel/api/exception/TemplateNotMatchException.java
create mode 100644 src/main/java/com/wb/excel/api/interfaces/EnumSupport.java
create mode 100644 src/main/java/com/wb/excel/api/interfaces/IExcelVerifyHandler.java
create mode 100644 src/main/java/com/wb/excel/api/style/BaseCellStyle.java
create mode 100644 src/main/java/com/wb/excel/api/style/BaseFont.java
create mode 100644 src/main/java/com/wb/excel/api/style/CheckFailureCellStyle.java
create mode 100644 src/main/java/com/wb/excel/api/style/CheckMessageCellStyle.java
create mode 100644 src/main/java/com/wb/excel/api/style/CheckSuccessCellStyle.java
create mode 100644 src/main/java/com/wb/excel/api/style/ErrorCellStyle.java
create mode 100644 src/main/java/com/wb/excel/api/style/ErrorNumberCellStyle.java
create mode 100644 src/main/java/com/wb/excel/api/style/HeadCellStyle.java
create mode 100644 src/main/java/com/wb/excel/api/style/NormalCellStyle.java
create mode 100644 src/main/java/com/wb/excel/api/style/NormalFont.java
create mode 100644 src/main/java/com/wb/excel/api/style/NormalNumberCellStyle.java
create mode 100644 src/main/java/com/wb/excel/api/style/RedFont.java
create mode 100644 src/main/java/com/wb/excel/api/util/BaseVerifyUtil.java
create mode 100644 src/main/java/com/wb/excel/api/util/ClassUtil.java
create mode 100644 src/main/java/com/wb/excel/api/util/DataTableUtil.java
create mode 100644 src/main/java/com/wb/excel/api/util/EnumUtil.java
create mode 100644 src/main/java/com/wb/excel/api/util/ExcelUtil.java
create mode 100644 src/main/java/com/wb/excel/api/util/StringUtil.java
create mode 100644 src/main/java/com/wb/excel/api/util/StringUtils.java
create mode 100644 src/main/java/com/wb/excel/api/util/TransferUtil.java
create mode 100644 src/main/java/com/wb/excel/api/util/ValidationUtil.java
create mode 100644 src/main/java/com/wb/excel/api/util/VerifyDataUtil.java
create mode 100644 src/test/java/ExampleTest.java
create mode 100644 src/test/java/User.java
diff --git a/.gitignore b/.gitignore
index 32858aa..2034201 100644
--- a/.gitignore
+++ b/.gitignore
@@ -10,3 +10,19 @@
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
hs_err_pid*
+
+
+/.idea
+*.iml
+/.settings
+/bin
+/gen
+/build
+/gradle
+/classes
+.classpath
+.project
+*.gradle
+*.bat
+gradlew
+local.properties
diff --git a/pom.xml b/pom.xml
new file mode 100644
index 0000000..e5f6851
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,40 @@
+
+
+ 4.0.0
+
+ xyx.wbsite
+ wexcel
+ 1.0-SNAPSHOT
+
+
+
+ org.hibernate
+ hibernate-validator
+
+
+ org.hibernate
+ hibernate-validator
+ 5.1.2.Final
+
+
+
+ org.apache.poi
+ poi-ooxml
+ 3.8
+
+
+
+
+
+
+ maven-compiler-plugin
+
+
+ 1.8
+
+
+
+
+
\ No newline at end of file
diff --git a/src/main/java/com/wb/excel/api/Excel.java b/src/main/java/com/wb/excel/api/Excel.java
new file mode 100644
index 0000000..8976295
--- /dev/null
+++ b/src/main/java/com/wb/excel/api/Excel.java
@@ -0,0 +1,341 @@
+package com.wb.excel.api;
+
+import com.wb.excel.api.annotation.HeaderDescription;
+import com.wb.excel.api.datatable.Cell;
+import com.wb.excel.api.datatable.Column;
+import com.wb.excel.api.datatable.DataTable;
+import com.wb.excel.api.enumeration.DataType;
+import com.wb.excel.api.enumeration.Status;
+import com.wb.excel.api.style.*;
+import org.apache.poi.ss.usermodel.CellStyle;
+import org.apache.poi.ss.usermodel.Font;
+import org.apache.poi.ss.usermodel.Row;
+import org.apache.poi.ss.usermodel.Workbook;
+import org.apache.poi.xssf.usermodel.*;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.lang.reflect.Field;
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * Excel帮助类.
+ *
+ * Created on 2014/9/27.
+ *
+ * @author
+ * @since 0.1.0
+ */
+public class Excel {
+ /**
+ * Excel表格
+ */
+ private XSSFWorkbook workbook;
+
+ /**
+ * 表头样式
+ */
+ private CellStyle headCellStyle;
+
+ /**
+ * 错误单元格的样式
+ */
+ private CellStyle errorCellStyle;
+
+ /**
+ * 错误的数字单元格的样式(数字靠右)
+ */
+ private CellStyle errorNumberCellStyle;
+
+ /**
+ * 普通单元格的样式
+ */
+ private CellStyle normalCellStyle;
+
+ /**
+ * 普通数字单元格的样式
+ */
+ private CellStyle normalNumberCellStyle;
+
+ /**
+ * 检查消息单元格的样式(最右边一列)
+ */
+ private CellStyle checkMessageCellStyle;
+
+ /**
+ * 检查结果失败的单元格的样式
+ */
+ private CellStyle checkFailureCellStyle;
+
+ /**
+ * 检查结果通过的单元格的样式
+ */
+ private CellStyle checkSuccessCellStyle;
+
+ /**
+ * 正常的文字
+ */
+ private Font normalFont;
+
+ /**
+ * 红色文字
+ */
+ private Font redFont;
+
+ /**
+ * 初始化一个Excel文件.
+ */
+ public void init() {
+ workbook = new XSSFWorkbook();
+
+ //---------- 创建样式 ------------------
+ headCellStyle = new HeadCellStyle(workbook).getStyle();
+ errorCellStyle = new ErrorCellStyle(workbook).getStyle();
+ errorNumberCellStyle = new ErrorNumberCellStyle(workbook).getStyle();
+ normalCellStyle = new NormalCellStyle(workbook).getStyle();
+ normalNumberCellStyle = new NormalNumberCellStyle(workbook).getStyle();
+ checkMessageCellStyle = new CheckMessageCellStyle(workbook).getStyle();
+ checkFailureCellStyle = new CheckFailureCellStyle(workbook).getStyle();
+ checkSuccessCellStyle = new CheckSuccessCellStyle(workbook).getStyle();
+
+ //----------- 创建字体 ----------------
+ normalFont = new NormalFont(workbook).getFont();
+ redFont = new RedFont(workbook).getFont();
+ }
+
+ /**
+ * 默认无参构造方法.
+ */
+ public Excel() {
+ init();
+ }
+
+ /**
+ * 将一个DataTable转换为Excel对象,不显示检查结果和错误消息栏.
+ * 通常用于导出报表.
+ * {@link Excel#Excel(boolean flag, DataTable... dataTable)}
+ *
+ * @param tables 要导出的DataTable集合
+ */
+ public Excel(DataTable... tables) {
+ workbook = this.initExcel(false, tables);
+ }
+
+ /**
+ * 将一个DataTable转换为Excel对象.
+ *
+ * @param table DataTable
+ * @param flag 是否需要添加检查结果和错误消息栏(true,会添加;false,不会添加)
+ */
+ @Deprecated
+ public Excel(DataTable table, boolean flag) {
+ workbook = this.initExcel(flag, table);
+ }
+
+ /**
+ * 将若干DataTable转换为Excel对象.
+ *
+ * @param flag 是否需要添加检查结果和错误消息栏(true,会添加;false,不会添加)
+ * @param tables DataTable列表
+ */
+ public Excel(boolean flag, DataTable... tables) {
+ workbook = this.initExcel(flag, tables);
+ }
+
+ public XSSFWorkbook initExcel(boolean flag, DataTable... tables) {
+ init();
+ Set nameSet = new HashSet<>(tables.length);
+ for (DataTable table : tables) {
+ String name = table.getName();
+ int index = 1;
+ while (nameSet.contains(name)) {
+ name = table.getName() + "(" + index + ")";
+ index++;
+ }
+ nameSet.add(name);
+
+ //创建一个Sheet表
+ XSSFSheet sheet = workbook.createSheet(name);
+ sheet.setDefaultRowHeightInPoints(20);
+ Row firstRow = sheet.createRow(0); // 下标为0的行开始
+ XSSFDrawing drawing = sheet.createDrawingPatriarch();
+
+ //----------------表头--------------------
+ if (flag) {
+ // 检查结果栏
+ org.apache.poi.ss.usermodel.Cell firstCell = firstRow.createCell(0);
+ String columnName = DataTable.CHECK_STATUS_NAME;
+ firstCell.setCellStyle(headCellStyle);
+ firstCell.setCellValue(new XSSFRichTextString(columnName));
+ sheet.setColumnWidth(0, (4 + 8) * 256);
+ }
+ // 数据栏
+ int hiddenNumber = 0;
+ for (int j = 0; j < table.getColumnIndex(); j++) {
+ Column column = table.getColumns()[j];
+ if (column.isHidden()) {
+ hiddenNumber++;
+ continue;
+ }
+ int k = j - hiddenNumber;
+ if (flag) {
+ k++;
+ }
+ org.apache.poi.ss.usermodel.Cell firstCell = firstRow.createCell(k);
+ String columnName = column.getName();
+ XSSFRichTextString textString;
+ if (column.isRequired()) {
+ textString = new XSSFRichTextString("*" + columnName);
+ textString.applyFont(0, 1, redFont);
+ textString.applyFont(1, textString.length(), normalFont);
+ } else {
+ textString = new XSSFRichTextString(columnName);
+ textString.applyFont(normalFont);
+ }
+ StringBuilder sb = new StringBuilder();
+ sb.append(column.getDescription()).append("\n");
+ if (column.getDataType() != DataType.STRING) {
+ // 如果数据类型不是字符串类型,添加特殊数据类型的说明信息。
+ Field[] fields = DataType.class.getDeclaredFields();
+ for (Field field : fields) {
+ if (field.getName().equals(column.getDataType().name())) {
+ if (field.isAnnotationPresent(HeaderDescription.class)) {
+
+ // 获取声明字段上的Description信息。
+ HeaderDescription headerDescription = field.getAnnotation(HeaderDescription.class);
+ if (headerDescription.value() != null) {
+ sb.append(headerDescription.value());
+ }
+ }
+ }
+ }
+ }
+
+ // 如果填写了注释信息
+ if (sb.length() > 1) {
+ XSSFClientAnchor anchor = new XSSFClientAnchor(0, 0, 0, 0, (short) 3, 3, (short) 5, 6);
+ XSSFComment comment = drawing.createCellComment(anchor);
+ comment.setString(sb.toString());
+ firstCell.setCellComment(comment);
+ }
+ firstCell.setCellValue(textString);
+ firstCell.setCellStyle(headCellStyle);
+ sheet.setColumnWidth(k, (4 + column.getCellWidth()) * 256);
+ }
+
+ // 错误消息栏
+ if (flag) {
+ org.apache.poi.ss.usermodel.Cell firstCell = firstRow.createCell(table.getColumnIndex() + 1 - hiddenNumber);
+ String columnName = DataTable.CHECK_STATUS_RESULT;
+ firstCell.setCellStyle(headCellStyle);
+ firstCell.setCellValue(new XSSFRichTextString(columnName));
+ sheet.setColumnWidth(table.getColumnIndex() + 1, (4 + 10) * 256);
+ }
+
+ // 冻结第一行
+ //sheet.createFreezePane(255,1);
+
+ //------------------数据--------------------
+ for (int i = 0; i < table.getRowIndex(); i++) {
+ Row row = sheet.createRow(i + 1);
+ boolean rowFlag = true;
+
+ //如果该行有错误
+ if (flag) {
+ org.apache.poi.ss.usermodel.Cell xssfCell = row.createCell(0);
+ if (table.getRowError(i) != null) {
+ rowFlag = false;
+ xssfCell.setCellValue("不通过");
+ xssfCell.setCellStyle(checkFailureCellStyle);
+ } else {
+ xssfCell.setCellValue("通过");
+ xssfCell.setCellStyle(checkSuccessCellStyle);
+ }
+ }
+
+ int j = 0;
+ hiddenNumber = 0;
+ for (; j < table.getColumnIndex(); j++) {
+ Column column = table.getColumns()[j];
+ if (column.isHidden()) {
+ hiddenNumber++;
+ continue;
+ }
+ int k = j - hiddenNumber;
+ if (flag) {
+ k++;
+ }
+
+ org.apache.poi.ss.usermodel.Cell xssfCell = row.createCell(k);
+ Cell cell = table.getCell(i, j);
+ if (null == cell) {
+ continue;
+ }
+ String value = cell.getValue();
+ xssfCell.setCellValue(value);
+
+ // 如果该列是数字类型,则靠右
+ if (table.getColumns()[j].getDataType() == DataType.DECIMAL
+ || table.getColumns()[j].getDataType() == DataType.NUMBER
+ || table.getColumns()[j].getDataType() == DataType.LONG) {
+ if (flag && !cell.getStatus().equals(Status.PASS)) {
+ xssfCell.setCellStyle(errorNumberCellStyle);
+ } else {
+ xssfCell.setCellStyle(normalNumberCellStyle);
+ }
+ } else {
+ if (flag && !cell.getStatus().equals(Status.PASS)) {
+ xssfCell.setCellStyle(errorCellStyle);
+ } else {
+ xssfCell.setCellStyle(normalCellStyle);
+ }
+ }
+ }
+
+ if (flag && !rowFlag) {
+ org.apache.poi.ss.usermodel.Cell xssfCell = row.createCell(j + 1 - hiddenNumber);
+ xssfCell.setCellValue(table.getRowError(i));
+ xssfCell.setCellStyle(checkMessageCellStyle);
+ }
+ }
+ }
+ return workbook;
+ }
+
+ /**
+ * 将一个DataTable转换为Excel对象
+ *
+ * @param table DataTable
+ * @param flag 是否需要添加检查结果和错误消息栏
+ * @return Excel的Workbook对象
+ */
+ @Deprecated
+ public XSSFWorkbook initExcel(DataTable table, boolean flag) {
+ return initExcel(flag, table);
+ }
+
+ /**
+ * 得到已生成好的Excel文件的字节流信息
+ *
+ * @return 字节流信息
+ * @throws IOException
+ */
+ public byte[] getBytes() throws IOException {
+ if (workbook != null) {
+ ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+ workbook.write(outputStream);
+ return outputStream.toByteArray();
+ }
+ return null;
+ }
+
+ //------------ getter & setter --------------------
+ public Workbook getWorkbook() {
+ return workbook;
+ }
+
+ public void setWorkbook(XSSFWorkbook workbook) {
+ this.workbook = workbook;
+ }
+}
diff --git a/src/main/java/com/wb/excel/api/annotation/Enum.java b/src/main/java/com/wb/excel/api/annotation/Enum.java
new file mode 100644
index 0000000..76fe5b3
--- /dev/null
+++ b/src/main/java/com/wb/excel/api/annotation/Enum.java
@@ -0,0 +1,17 @@
+package com.wb.excel.api.annotation;
+
+import java.lang.annotation.*;
+
+/**
+ * 优先通过target来判断枚举的值
+ * Created on 2014/9/26.
+ *
+ * @author
+ * @version v1.0.0.0
+ */
+@Target(ElementType.FIELD)
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+public @interface Enum {
+ public Class target();
+}
diff --git a/src/main/java/com/wb/excel/api/annotation/EnumValue.java b/src/main/java/com/wb/excel/api/annotation/EnumValue.java
new file mode 100644
index 0000000..6acc43b
--- /dev/null
+++ b/src/main/java/com/wb/excel/api/annotation/EnumValue.java
@@ -0,0 +1,26 @@
+package com.wb.excel.api.annotation;
+
+import java.lang.annotation.*;
+
+/**
+ * 枚举类的key所对应的value数组。
+ * 导出时:
+ * 如果一个字段上出现了多个value,会取出第一个作为导出内容。
+ * 如果未定义值,会把字段名作为导出内容。
+ *
+ * 导入时:
+ * 如果value数组中出现了导入的值,返回该value对应的key值。
+ * 但是,如果同一个文件里出现了重复的value,DataTable会默认使用第一个出现该value的Key值
+ * 不能保证第一个出现的地方是你想要的结果,所以可能会返回无法预料的结果。
+ * 所以,强烈建议使用时避免出现重复的内容。
+ * Created on 2014/9/28.
+ *
+ * @author
+ * @version 0.1.0
+ */
+@Target(ElementType.FIELD)
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+public @interface EnumValue {
+ String[] value() default "";
+}
diff --git a/src/main/java/com/wb/excel/api/annotation/ExcelCollection.java b/src/main/java/com/wb/excel/api/annotation/ExcelCollection.java
new file mode 100644
index 0000000..7ae4a05
--- /dev/null
+++ b/src/main/java/com/wb/excel/api/annotation/ExcelCollection.java
@@ -0,0 +1,39 @@
+package com.wb.excel.api.annotation;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+import java.util.ArrayList;
+
+/**
+ * ***************************************************************
+ *
+ *
+ * Copyright (c) 2014 –
+ * HeaderDescription: 导入导出接合
+ * ***************************************************************
+ *
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.FIELD)
+public @interface ExcelCollection {
+ /**
+ * 名称
+ *
+ * @return
+ */
+ public String value();
+
+ /**
+ * 所属的排序
+ *
+ * @return
+ */
+ public String orderNum() default "0";
+
+ /**
+ * 创建时创建的类型 默认值是 arrayList
+ */
+ public Class> type() default ArrayList.class;
+}
diff --git a/src/main/java/com/wb/excel/api/annotation/ExcelVerify.java b/src/main/java/com/wb/excel/api/annotation/ExcelVerify.java
new file mode 100644
index 0000000..f4a8468
--- /dev/null
+++ b/src/main/java/com/wb/excel/api/annotation/ExcelVerify.java
@@ -0,0 +1,94 @@
+/**
+ * Copyright 2013-2015 JueYue (qrb.jueyue@gmail.com)
+ *
+ * Licensed 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.
+ */
+package com.wb.excel.api.annotation;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Excel 导入校验
+ *
+ * @author JueYue
+ * @date 2014年6月23日 下午10:46:26
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.FIELD)
+public @interface ExcelVerify {
+ /**
+ * 接口校验
+ * @return
+ */
+ public boolean interHandler() default false;
+
+ /**
+ * 是电子邮件
+ *
+ * @return
+ */
+ public boolean isEmail() default false;
+
+ /**
+ * 是13位移动电话
+ *
+ * @return
+ */
+ public boolean isMobile() default false;
+
+ /**
+ * 是座机号码
+ *
+ * @return
+ */
+ public boolean isTel() default false;
+
+ /**
+ * 最大长度
+ *
+ * @return
+ */
+ public int maxLength() default -1;
+
+ /**
+ * 最小长度
+ *
+ * @return
+ */
+ public int minLength() default -1;
+
+ /**
+ * 不允许空
+ *
+ * @return
+ */
+ public boolean notNull() default false;
+
+ /**
+ * 正在表达式
+ *
+ * @return
+ */
+ public String regex() default "";
+
+ /**
+ * 正在表达式,错误提示信息
+ *
+ * @return
+ */
+ public String regexTip() default "数据不符合规范";
+
+}
diff --git a/src/main/java/com/wb/excel/api/annotation/HeaderDescription.java b/src/main/java/com/wb/excel/api/annotation/HeaderDescription.java
new file mode 100644
index 0000000..b6dc28b
--- /dev/null
+++ b/src/main/java/com/wb/excel/api/annotation/HeaderDescription.java
@@ -0,0 +1,17 @@
+package com.wb.excel.api.annotation;
+
+import java.lang.annotation.*;
+
+/**
+ * Created on 2014/9/24.
+ *
+ * @author
+ * @version v1.0.0.0
+ */
+@Target(ElementType.FIELD)
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+public @interface HeaderDescription {
+ String value() default "";
+
+}
diff --git a/src/main/java/com/wb/excel/api/annotation/HeaderName.java b/src/main/java/com/wb/excel/api/annotation/HeaderName.java
new file mode 100644
index 0000000..a4b0c1a
--- /dev/null
+++ b/src/main/java/com/wb/excel/api/annotation/HeaderName.java
@@ -0,0 +1,31 @@
+package com.wb.excel.api.annotation;
+
+import java.lang.annotation.*;
+
+/**
+ * 为字段、方法或类注解名称。
+ * Created on 2014/9/24.
+ *
+ * @author
+ * @version v1.0.0.0
+ */
+@Target({ElementType.FIELD, ElementType.METHOD, ElementType.TYPE})
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+public @interface HeaderName {
+ String value();
+
+ /**
+ * 排序
+ *
+ * @return
+ */
+ public String orderNum() default "0";
+
+ /**
+ * 日期格式化
+ *
+ * @return
+ */
+ public String dateFormat() default "yyyy-MM-dd";
+}
diff --git a/src/main/java/com/wb/excel/api/annotation/IsDuplicated.java b/src/main/java/com/wb/excel/api/annotation/IsDuplicated.java
new file mode 100644
index 0000000..3131370
--- /dev/null
+++ b/src/main/java/com/wb/excel/api/annotation/IsDuplicated.java
@@ -0,0 +1,17 @@
+package com.wb.excel.api.annotation;
+
+import java.lang.annotation.*;
+
+/**
+ * 是否允许该列重复。默认为false(不允许重复)
+ * Created on 2014/9/24.
+ *
+ * @author
+ * @version v1.0.0.0
+ */
+@Target(ElementType.FIELD)
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+public @interface IsDuplicated {
+ boolean value() default false;
+}
diff --git a/src/main/java/com/wb/excel/api/annotation/NoRepeat.java b/src/main/java/com/wb/excel/api/annotation/NoRepeat.java
new file mode 100644
index 0000000..4a62af4
--- /dev/null
+++ b/src/main/java/com/wb/excel/api/annotation/NoRepeat.java
@@ -0,0 +1,17 @@
+package com.wb.excel.api.annotation;
+
+import java.lang.annotation.*;
+
+/**
+ * Created on 2014/9/24.
+ *
+ * @author
+ * @version v1.0.0.0
+ */
+@Target(ElementType.FIELD)
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+public @interface NoRepeat {
+ String value() default "";
+
+}
diff --git a/src/main/java/com/wb/excel/api/annotation/ParentFirst.java b/src/main/java/com/wb/excel/api/annotation/ParentFirst.java
new file mode 100644
index 0000000..a5347ee
--- /dev/null
+++ b/src/main/java/com/wb/excel/api/annotation/ParentFirst.java
@@ -0,0 +1,16 @@
+package com.wb.excel.api.annotation;
+
+import java.lang.annotation.*;
+
+/**
+ * Created on 2015/5/28.
+ *
+ * @author 金洋
+ * @since 2.1.0
+ */
+@Target(ElementType.TYPE)
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+public @interface ParentFirst {
+ boolean value() default true;
+}
diff --git a/src/main/java/com/wb/excel/api/annotation/Split.java b/src/main/java/com/wb/excel/api/annotation/Split.java
new file mode 100644
index 0000000..5ce2f12
--- /dev/null
+++ b/src/main/java/com/wb/excel/api/annotation/Split.java
@@ -0,0 +1,28 @@
+package com.wb.excel.api.annotation;
+
+import java.lang.annotation.*;
+
+/**
+ * Created on 2014/9/26.
+ *
+ * @author
+ * @version v1.0.0.0
+ */
+@Target(ElementType.FIELD)
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+public @interface Split {
+ /**
+ * 分隔字符
+ *
+ * @return
+ */
+ String reg() default "";
+
+ /**
+ * 取分隔后的结果的下标。从0开始。
+ *
+ * @return
+ */
+ int index() default 0;
+}
diff --git a/src/main/java/com/wb/excel/api/annotation/Substring.java b/src/main/java/com/wb/excel/api/annotation/Substring.java
new file mode 100644
index 0000000..155c6c0
--- /dev/null
+++ b/src/main/java/com/wb/excel/api/annotation/Substring.java
@@ -0,0 +1,18 @@
+package com.wb.excel.api.annotation;
+
+import java.lang.annotation.*;
+
+/**
+ * Created on 2014/9/26.
+ *
+ * @author
+ * @version v1.0.0.0
+ */
+@Target(ElementType.FIELD)
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+public @interface Substring {
+ int start() default 0;
+
+ int end() default 0;
+}
diff --git a/src/main/java/com/wb/excel/api/annotation/Type.java b/src/main/java/com/wb/excel/api/annotation/Type.java
new file mode 100644
index 0000000..43fa41d
--- /dev/null
+++ b/src/main/java/com/wb/excel/api/annotation/Type.java
@@ -0,0 +1,19 @@
+package com.wb.excel.api.annotation;
+
+
+import com.wb.excel.api.enumeration.DataType;
+
+import java.lang.annotation.*;
+
+/**
+ * Created on 2014/9/24.
+ *
+ * @author
+ * @version v1.0.0.0
+ */
+@Target(ElementType.FIELD)
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+public @interface Type {
+ public DataType value() default DataType.STRING;
+}
diff --git a/src/main/java/com/wb/excel/api/datatable/Cell.java b/src/main/java/com/wb/excel/api/datatable/Cell.java
new file mode 100644
index 0000000..a53199c
--- /dev/null
+++ b/src/main/java/com/wb/excel/api/datatable/Cell.java
@@ -0,0 +1,59 @@
+package com.wb.excel.api.datatable;
+
+
+import com.wb.excel.api.enumeration.Status;
+
+import java.io.Serializable;
+
+/**
+ * 单元格.
+ * Created on 2014/9/23.
+ *
+ * @author
+ * @since 0.1.0
+ */
+public class Cell implements Serializable {
+ /**
+ * 单元格的状态
+ */
+ private Status status;
+
+ /**
+ * 单元格的值
+ */
+ private String value;
+
+ /**
+ * 默认无参构造方法.会将单元格的状态设为通过.
+ */
+ public Cell() {
+ this.status = Status.PASS;
+ this.value = "";
+ }
+
+ /**
+ * 传入默认单元格值的构造方法.
+ *
+ * @param value 单元格的值.
+ */
+ public Cell(String value) {
+ this.value = value;
+ this.status = Status.PASS;
+ }
+
+ public Status getStatus() {
+ return status;
+ }
+
+ public void setStatus(Status status) {
+ this.status = status;
+ }
+
+ public String getValue() {
+ return value;
+ }
+
+ public void setValue(String value) {
+ this.value = value;
+ }
+}
diff --git a/src/main/java/com/wb/excel/api/datatable/Column.java b/src/main/java/com/wb/excel/api/datatable/Column.java
new file mode 100644
index 0000000..2224b96
--- /dev/null
+++ b/src/main/java/com/wb/excel/api/datatable/Column.java
@@ -0,0 +1,109 @@
+package com.wb.excel.api.datatable;
+
+
+import com.wb.excel.api.enumeration.DataType;
+import com.wb.excel.api.util.StringUtil;
+
+import java.io.Serializable;
+
+/**
+ * DataTable中的表头,包含本列的一些限制条件。
+ * 现有:列名、是否必须、是否允许重复、说明字段以及数据类型
+ * Created by edward on 9/19/14.
+ */
+public class Column implements Serializable {
+ /**
+ * 列名
+ */
+ private String name;
+ /**
+ * 该列的最大宽度
+ */
+ private int cellWidth;
+ /**
+ * 是否为隐藏列,如果为隐藏列,在导出Excel文件时会被忽略
+ */
+ private boolean isHidden;
+ /**
+ * 是否是必输列
+ */
+ private boolean isRequired;
+ /**
+ * 该列的描述字段
+ */
+ private String description;
+ /**
+ * 该列的数据类型
+ */
+ private DataType dataType;
+
+ public Column() {
+ this.name = "";
+ this.cellWidth = 1;
+ this.isHidden = false;
+ this.isRequired = false;
+ this.description = "";
+ this.dataType = DataType.STRING;
+ }
+
+ public Column(String name) {
+ this.name = name;
+ this.cellWidth = 1;
+ this.isHidden = false;
+ this.isRequired = false;
+ this.description = "";
+ this.dataType = DataType.STRING;
+ }
+
+ //----------- getter & setter --------------
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ if (StringUtil.getByteLength(name) > cellWidth) {
+ cellWidth = StringUtil.getByteLength(name);
+ }
+ this.name = name;
+ }
+
+ public int getCellWidth() {
+ return cellWidth;
+ }
+
+ public void setCellWidth(int cellWidth) {
+ this.cellWidth = cellWidth;
+ }
+
+ public boolean isHidden() {
+ return isHidden;
+ }
+
+ public void setHidden(boolean isHidden) {
+ this.isHidden = isHidden;
+ }
+
+ public boolean isRequired() {
+ return isRequired;
+ }
+
+ public void setRequired(boolean isRequired) {
+ this.isRequired = isRequired;
+ }
+
+ public String getDescription() {
+ return description;
+ }
+
+ public void setDescription(String description) {
+ this.description = description;
+ }
+
+ public DataType getDataType() {
+ return dataType;
+ }
+
+ public void setDataType(DataType dataType) {
+ this.dataType = dataType;
+ }
+}
diff --git a/src/main/java/com/wb/excel/api/datatable/DataExcel.java b/src/main/java/com/wb/excel/api/datatable/DataExcel.java
new file mode 100644
index 0000000..3295859
--- /dev/null
+++ b/src/main/java/com/wb/excel/api/datatable/DataExcel.java
@@ -0,0 +1,60 @@
+package com.wb.excel.api.datatable;
+
+
+import com.wb.excel.api.entity.ExcelImportResult;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * ***************************************************************
+ *
+ *
+ * Copyright (c) 2014 –
+ * HeaderDescription:
+ * ***************************************************************
+ *
+ */
+public class DataExcel {
+// static Logger LOGGER = Logger.getLogger(DataExcel.class);
+
+ /**
+ * @param file
+ * @param pojoClass
+ * @param
+ * @return
+ */
+ public static ExcelImportResult importExcel(File file, Class> pojoClass, ImportParams importParams) {
+ FileInputStream in = null;
+ try {
+ in = new FileInputStream(file);
+ return new ExcelImport().importExcelByIs(in, pojoClass, importParams);
+ } catch (Exception e) {
+// LOGGER.error(e.getMessage(), e);
+ } finally {
+ try {
+ in.close();
+ } catch (IOException e) {
+// LOGGER.error(e.getMessage(), e);
+ }
+ }
+ return null;
+ }
+
+
+ /**
+ * Excel 导入 数据源IO流,不返回校验结果 导入 字段类型 Integer,Long,Double,Date,String,Boolean
+ *
+ * @param inputstream
+ * @param pojoClass
+ * @return
+ * @throws Exception
+ */
+ public static ExcelImportResult importExcel(InputStream inputstream, Class> pojoClass, ImportParams importParams) throws Exception {
+ return new ExcelImport().importExcelByIs(inputstream, pojoClass, importParams);
+ }
+
+
+}
diff --git a/src/main/java/com/wb/excel/api/datatable/DataRow.java b/src/main/java/com/wb/excel/api/datatable/DataRow.java
new file mode 100644
index 0000000..89a9879
--- /dev/null
+++ b/src/main/java/com/wb/excel/api/datatable/DataRow.java
@@ -0,0 +1,14 @@
+package com.wb.excel.api.datatable;
+
+import java.io.Serializable;
+import java.util.HashMap;
+
+/**
+ * DataTable中的行对象.
+ * Created on 2014/09/19.
+ *
+ * @author
+ * @since 0.1.0
+ */
+public class DataRow extends HashMap implements Serializable {
+}
diff --git a/src/main/java/com/wb/excel/api/datatable/DataTable.java b/src/main/java/com/wb/excel/api/datatable/DataTable.java
new file mode 100644
index 0000000..1f1c358
--- /dev/null
+++ b/src/main/java/com/wb/excel/api/datatable/DataTable.java
@@ -0,0 +1,1194 @@
+package com.wb.excel.api.datatable;
+
+import com.wb.excel.api.annotation.*;
+import com.wb.excel.api.annotation.Enum;
+import com.wb.excel.api.enumeration.DataType;
+import com.wb.excel.api.enumeration.Status;
+import com.wb.excel.api.exception.*;
+import com.wb.excel.api.exception.Error;
+import com.wb.excel.api.util.*;
+import org.apache.poi.hssf.usermodel.HSSFWorkbook;
+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 org.hibernate.validator.constraints.Length;
+
+import javax.validation.constraints.DecimalMax;
+import javax.validation.constraints.DecimalMin;
+import javax.validation.constraints.NotNull;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Serializable;
+import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.text.SimpleDateFormat;
+import java.util.*;
+
+/**
+ * 数据表的定义。
+ * Created on 2014/09/19.
+ *
+ * @author 沈振家
+ * @since 0.1.0
+ */
+public class DataTable implements Serializable, Cloneable {
+
+ public final static String CHECK_STATUS_NAME = "检查状态";
+ public final static String CHECK_STATUS_RESULT = "结果消息";
+
+ /**
+ * 初始化时最大的行数
+ */
+ private int MAX_ROW_NUMBER = 100;
+
+ /**
+ * 初始化时最大的列数
+ */
+ private int MAX_COLUMN_NUMBER = 20;
+
+ /**
+ * 表名
+ */
+ private String name;
+
+ /**
+ * 表头的集合
+ */
+ private Column[] columns;
+
+ /**
+ * 当前的行数
+ */
+ private int rowIndex;
+ private int columnIndex;
+
+ /**
+ * 单元格里存放的对象
+ */
+ private Cell[][] data;
+
+ /**
+ * 整个Table的错误列表
+ */
+ private List errorList;
+
+ /**
+ * 每一行的错误情况。
+ */
+ private List> errorLists;
+
+ /**
+ * 初始化准备工作。在构造方法前调用。
+ */
+ public void init() {
+ rowIndex = 0;
+ columnIndex = 0;
+
+ columns = new Column[MAX_COLUMN_NUMBER];
+ data = new Cell[MAX_ROW_NUMBER][MAX_COLUMN_NUMBER];
+
+ errorList = new ArrayList<>();
+ errorLists = new ArrayList<>(MAX_ROW_NUMBER);
+ for (int i = 0; i < MAX_ROW_NUMBER; i++) {
+ errorLists.add(new ArrayList());
+ }
+ }
+
+ /**
+ * 默认构造方法。
+ */
+ public DataTable() {
+ init();
+ }
+
+ /**
+ * 根据输入的模板类打印下载模板。
+ *
+ * @param clazz 模板类
+ */
+ public DataTable(Class clazz) {
+ init();
+ setColumns(clazz);
+ }
+
+ /**
+ * 根据模板类对DataTable添加相应的列。
+ *
+ * @param clazz 模板类
+ * @return 包含@Name标记的字段Set
+ */
+ private Set setColumns(Class> clazz) {
+ HeaderName tempHeaderName = clazz.getAnnotation(HeaderName.class);
+ ParentFirst parentFirstAnnotation = clazz.getAnnotation(ParentFirst.class);
+ boolean parentFirst = parentFirstAnnotation != null && parentFirstAnnotation.value();
+ if (tempHeaderName != null) {
+ this.setName(tempHeaderName.value());
+ } else {
+ this.setName(clazz.getName());
+ }
+ //Field [] fields = clazz.getDeclaredFields();
+ Field[] fields = ClassUtil.getFields(clazz, parentFirst);
+ Set set = new HashSet<>();
+ for (Field field : fields) {
+ set.add(field);
+ Column column = null;
+ if (!field.isAnnotationPresent(HeaderName.class)) {
+ String name = field.getName();
+ column = new Column(name);
+ } else {
+ HeaderName columnHeaderName = field.getAnnotation(HeaderName.class);
+ column = new Column(columnHeaderName.value());
+ }
+ if (field.isAnnotationPresent(NotNull.class)) {
+ column.setRequired(true);
+ }
+
+ if (field.isAnnotationPresent(Type.class)) {
+ Type type = field.getAnnotation(Type.class);
+ column.setDataType(type.value());
+ } else {
+ column.setDataType(DataType.STRING);
+ }
+
+ if (field.isAnnotationPresent(HeaderDescription.class)) {
+ column.setDescription(field.getAnnotation(HeaderDescription.class).value());
+ }
+ this.addColumn(column);
+ }
+ return set;
+ }
+
+ /**
+ * 此构造方法仅用于转换对象列表。
+ * 并不会对数据的格式和合法性进行检验。
+ *
+ * @param list 需要导出的对象列表
+ * @throws NoSuchMethodException
+ * @throws InvocationTargetException
+ * @throws IllegalAccessException
+ */
+ public DataTable(List list)
+ throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
+ init();
+ if (list == null || list.size() == 0) {
+ throw new IllegalParameterException("不允许传入空的列表");
+ }
+ if (list.size() > 0) {
+ T tClass = list.get(0);
+ Set set = setColumns(tClass.getClass());
+
+ for (T t : list) {
+ DataRow row = new DataRow();
+ for (Field field : set) {
+
+ // 获取字段上的名称注解(作为列名使用)
+ String HeaderName = "";
+ HeaderName fieldHeaderName = field.getAnnotation(HeaderName.class);
+ if (fieldHeaderName == null) {
+ HeaderName = field.getName();
+ } else {
+ HeaderName = fieldHeaderName.value();
+ }
+ String att = StringUtil.upperFirstWord(field.getName());
+ Method method = t.getClass().getMethod("get" + att);
+ Object value = method.invoke(t);
+ if (null == value) {
+ row.put(fieldHeaderName.value(), new Cell());
+ } else {
+ if (field.isAnnotationPresent(Type.class)) {
+ Type type = field.getAnnotation(Type.class);
+ switch (type.value()) {
+ case DATE: {
+ Date date = (Date) value;
+ SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
+ value = sdf.format(date);
+ break;
+ }
+ case DATETIME: {
+ Date date = (Date) value;
+ SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+ value = sdf.format(date);
+ break;
+ }
+ case DATEMINUTE: {
+ Date date = (Date) value;
+ SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm");
+ value = sdf.format(date);
+ break;
+ }
+ case NUMBER:
+ value = StringUtil.transferInteger(value.toString());
+ break;
+ case LONG:
+ value = StringUtil.transferLong(value.toString());
+ break;
+ case BOOLEAN:
+ value = StringUtil.transferBoolean(value.toString());
+ break;
+ default:
+ break;
+ }
+ }
+
+ // 如果该变量包含枚举标签,处理枚举
+ if (field.isAnnotationPresent(Enum.class)) {
+ Enum e = field.getAnnotation(Enum.class);
+ value = EnumUtil.getValue(e.target(), value.toString());
+ }
+ row.put(HeaderName, new Cell(value.toString()));
+ }
+ }
+ this.addRow(row);
+ }
+ }
+ }
+
+ /**
+ * 构造方法。传入Excel流,不需要指定类型。同时,也不会对数据进行检查。
+ *
+ * @param bytes Excel的字节数组。
+ * @throws IOException 可能会出现的错误。通常为以下错误:
+ * 1.流不能转换为Workbook
+ */
+ @Deprecated
+ public DataTable(byte[] bytes) throws IOException, TemplateNotMatchException {
+ init();
+ InputStream inputStream = null; //文件输入流
+ Workbook workbook = null; //导入的文档
+ boolean flag; //用于判断文件的类型
+ try {
+ flag = true;
+ inputStream = new ByteArrayInputStream(bytes);
+ workbook = new HSSFWorkbook(inputStream);
+ } catch (Exception e) {
+ flag = false;
+ }
+ if (!flag) {
+ try {
+ flag = true;
+ inputStream = new ByteArrayInputStream(bytes);
+ workbook = new XSSFWorkbook(inputStream);
+ } catch (Exception e) {
+ flag = false;
+ }
+ }
+ if (inputStream != null) {
+ inputStream.close();
+ }
+ if (!flag) {
+ throw new TemplateNotMatchException("不支持的文件类型");
+ }
+
+ /* 创建导入表的对象 */
+ Sheet sheet = workbook.getSheetAt(0); //默认只处理第一个Sheet表
+ this.setName(sheet.getSheetName());
+
+ /* 读取表头 */
+ Row headRow = sheet.getRow(0);
+ int columnNum = headRow.getPhysicalNumberOfCells();
+ for (int i = 0; i < columnNum; i++) {
+ org.apache.poi.ss.usermodel.Cell cell = headRow.getCell(i);
+ Column column = new Column();
+ column.setName(ExcelUtil.getValue(cell));
+ this.addColumn(column);
+ }
+
+ /* 逐行读取导入文件的数据,从1开始是因为第0行为表头 */
+ int rowNumber = sheet.getLastRowNum();
+ for (int i = 1; i <= rowNumber; i++) {
+ Row inputRow = sheet.getRow(i);
+ DataRow row = new DataRow();
+ if (null != inputRow) {
+ for (int j = 0; j < columnNum; j++) {
+ org.apache.poi.ss.usermodel.Cell excelCell = inputRow.getCell(j);
+ if (null != excelCell) {
+ row.put(this.getColumns()[j].getName(), new Cell(ExcelUtil.getValue(excelCell)));
+ }
+ }
+ }
+ this.addRow(row);
+ }
+ }
+
+ /**
+ * 以Excel文件的字节数组为数据源,为自己赋值的同时,与指定的模板类进行数据校验。
+ * 如果匹配过程中发现了不符合的数据,会在对应的单元中添加错误信息。
+ *
+ * @param bytes Excel文件的字节数组
+ * @param clazz 类型
+ * @throws IOException
1:输入流无法转为Excel文件 - 请检查输入的 bytes 是否正确;
+ * 2:输入流关闭出错;
+ * @throws TemplateNotMatchException
1:Excel文件的列数与对象类型不匹配 - 请检查Excel表与模板类是否一致;
+ * 2:获取枚举类型出错 - 你在模板类中标注了一个变量的值为枚举类型,但程序寻找枚举类时出错;
+ */
+ public DataTable(byte[] bytes, Class clazz) throws IOException, TemplateNotMatchException {
+ init();
+ Workbook workbook = null;
+ InputStream is = null;
+ boolean flag;
+ try {
+ flag = true;
+ is = new ByteArrayInputStream(bytes); //读取文件流
+ workbook = new HSSFWorkbook(is);
+ } catch (Exception e) {
+ flag = false;
+ }
+ if (!flag) {
+ try {
+ flag = true;
+ is = new ByteArrayInputStream(bytes); //读取文件流
+ workbook = new XSSFWorkbook(is);
+ } catch (Exception e) {
+ flag = false;
+ }
+ }
+ if (is != null) {
+ is.close();
+ }
+ if (!flag) {
+ throw new TemplateNotMatchException("不支持的文件类型");
+ }
+
+ Sheet sheet = workbook.getSheetAt(0); //处理第一张Sheet表
+ String tableName = sheet.getSheetName(); //DataTable的名字
+
+ /* 获取指定类所有带有Name注解的属性集合 */
+ HeaderName classHeaderName = clazz.getAnnotation(HeaderName.class); //该类所声明的名字
+ ParentFirst parentFirstAnnotation = clazz.getAnnotation(ParentFirst.class);
+ boolean parentFirst = parentFirstAnnotation != null && parentFirstAnnotation.value();
+ if (classHeaderName != null) {
+ tableName = classHeaderName.value();
+ }
+ this.setName(tableName); //将类名设为表名,如果类名不存在,将Excel表名设为表名
+
+ //Field[] fields = clazz.getDeclaredFields(); //该类所声明的全部属性
+ Field[] fields = ClassUtil.getFields(clazz, parentFirst); //该类所声明的全部属性
+ Set set = new HashSet<>(); //用于保存所有带有Name注解的属性
+ for (Field field : fields) {
+ if (field.isAnnotationPresent(HeaderName.class)) {
+ set.add(field);
+ }
+ }
+
+ /* 读取表头 */
+ Row headRow = sheet.getRow(0);
+ int columnSum = headRow.getPhysicalNumberOfCells(); //获取Excel列的总数
+ int columnMatchNumber = 0; //匹配列的数量。用于判断Excel是否包含所有必须列。
+
+ /* 为Excel表中的每一列分配空间 */
+ List> sets = new ArrayList<>();
+ Type[] types = new Type[columnSum];
+ Enum[] enums = new Enum[columnSum];
+ Split[] splits = new Split[columnSum];
+ Length[] lengths = new Length[columnSum];
+ NotNull[] notNulls = new NotNull[columnSum];
+ Substring[] substrings = new Substring[columnSum];
+ DecimalMin[] decimalMins = new DecimalMin[columnSum];
+ DecimalMax[] decimalMaxs = new DecimalMax[columnSum];
+ HeaderDescription[] headerDescriptions = new HeaderDescription[columnSum];
+ IsDuplicated[] isDuplicateds = new IsDuplicated[columnSum];
+
+ boolean[] matchFlag = new boolean[set.size()]; //保存字段是否出现在Excel文件中。
+
+ /* 查找匹配列的数量 */
+ for (int i = 0; i < columnSum; i++) {
+
+ sets.add(new HashSet());
+
+ org.apache.poi.ss.usermodel.Cell cell = headRow.getCell(i);
+ String headValue = ExcelUtil.getValue(cell); //获取列名
+ headValue = headValue.replace("*", "");
+ headValue = headValue.replace(" ", "");
+
+ int tempFieldIndex = 0; //字段的编号,临时变量
+ for (Field field : set) {
+ HeaderName fieldHeaderName = field.getAnnotation(HeaderName.class);
+ if (headValue.equals(fieldHeaderName.value())) { //如果Excel列名与Class属性名相一致
+ columnMatchNumber++; //标记该列的存在
+ types[i] = field.getAnnotation(Type.class);
+ enums[i] = field.getAnnotation(Enum.class);
+ splits[i] = field.getAnnotation(Split.class);
+ lengths[i] = field.getAnnotation(Length.class);
+ notNulls[i] = field.getAnnotation(NotNull.class);
+ substrings[i] = field.getAnnotation(Substring.class);
+ decimalMins[i] = field.getAnnotation(DecimalMin.class);
+ decimalMaxs[i] = field.getAnnotation(DecimalMax.class);
+ headerDescriptions[i] = field.getAnnotation(HeaderDescription.class);
+ isDuplicateds[i] = field.getAnnotation(IsDuplicated.class);
+
+ matchFlag[tempFieldIndex] = true;
+ break;
+ }
+ tempFieldIndex++;
+ }
+ Column column = new Column();
+ column.setName(ExcelUtil.getValue(cell));
+ if (headerDescriptions[i] != null) {
+ column.setDescription(headerDescriptions[i].value());
+ }
+ if (types[i] != null) {
+ column.setDataType(types[i].value());
+ }
+ if (notNulls[i] != null) {
+ column.setRequired(true);
+ }
+ this.addColumn(column);
+ }
+
+ /* 如果文件不匹配 */
+ if (columnMatchNumber != set.size()) {
+ StringBuilder templateExcept = new StringBuilder();
+ int tempIndex = 0;
+ for (Field field : set) {
+ if (matchFlag[tempIndex++]) {
+ continue;
+ }
+ templateExcept.append(field.getAnnotation(HeaderName.class).value()).append("栏;");
+ }
+ throw new TemplateNotMatchException("不匹配的Excel文件,没有:" + templateExcept.toString());
+ }
+
+ int maxRowNumber = sheet.getLastRowNum(); //Excel文件的总行数
+ /* 逐行读取导入文件的数据 */
+ for (int i = 0; i < maxRowNumber; i++) {
+ Row inputRow = sheet.getRow(i + 1); //Excel中的一行数据,第0行为表头,所以要加1
+ DataRow row = new DataRow(); //DataTable中的一行
+ this.addRow(row);
+
+ if (null != inputRow) {
+ for (int j = 0; j < columnSum; j++) { //逐格扫描
+
+ /* 取得当前格子的值 */
+ org.apache.poi.ss.usermodel.Cell excelCell = inputRow.getCell(j);
+ Cell cell = new Cell();
+ this.setCell(i, columns[j].getName(), cell);
+
+ String value = "";
+ if (null != excelCell) {
+ value = ExcelUtil.getValue(excelCell);
+ }
+ value = value.trim();
+ boolean cellFlag = true;
+
+ /* 如果要对字符进行切分 */
+ if (null != splits[j]) {
+ value = StringUtil.split(value, splits[j].reg(), splits[j].index());
+ }
+
+ /* 如果要截取一段字符 */
+ if (null != substrings[j]) {
+ value = StringUtil.substring(value, substrings[j].start(), substrings[j].end());
+ }
+
+ cell.setValue(value);
+
+ /* 如果要求非空 */
+ if (null != notNulls[j]) {
+ if (value.length() == 0) {
+ this.setStatus(i, j, Status.EMPTY);
+ cellFlag = false;
+ }
+ }
+
+ /* 如果属于枚举类型 */
+ if (cellFlag && null != enums[j]) {
+ Class enumClass = enums[j].target();
+
+ if (!EnumUtil.check(enumClass, value)) {
+ this.setStatus(i, j, Status.ERROR_VALUE);
+ cellFlag = false;
+ }
+ }
+
+ /* 如果对长度有要求 */
+ if (cellFlag && null != lengths[j]) {
+ if (value.length() > lengths[j].max() || value.length() < lengths[j].min()) {
+ this.setStatus(i, j, Status.LENGTH);
+ cellFlag = false;
+ }
+ }
+
+ /* 如果对类型有要求 */
+ if (cellFlag && null != types[j] && !types[j].value().equals(DataType.STRING)) {
+ if (!DataType.check(types[j].value(), cell, value)) {
+ this.setStatus(i, j, Status.FORMAT);
+ cellFlag = false;
+ }
+ }
+
+ // 如果对最小值有要求
+ if (cellFlag && null != decimalMins[j] && value.length() > 0) {
+ Double dou = TransferUtil.transferDouble(value);
+ Double minValue = TransferUtil.transferDouble(decimalMins[j].value());
+ if (dou < minValue) {
+ this.setStatus(i, j, Status.TOO_SMALL);
+ cellFlag = false;
+ }
+ }
+
+ // 如果对最大值有要求
+ if (cellFlag && null != decimalMaxs[j] && value.length() > 0) {
+ Double dou = TransferUtil.transferDouble(value);
+ Double maxValue = TransferUtil.transferDouble(decimalMaxs[j].value());
+ if (dou > maxValue) {
+ this.setStatus(i, j, Status.TOO_BIG);
+ cellFlag = false;
+ }
+ }
+
+ /* 如果不允许重复 */
+ if (cellFlag && null != isDuplicateds[j] && !isDuplicateds[j].value()) {
+ if (value.length() > 0) {
+ int tempSize = sets.get(j).size();
+ sets.get(j).add(value);
+ if (sets.get(j).size() == tempSize) {
+ this.setStatus(i, j, Status.REPEAT);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+
+ /**
+ * 获取所有的表头
+ *
+ * @return 表头数组
+ */
+ public Column[] getColumns() {
+ return this.columns;
+ }
+
+ /**
+ * 通过坐标取得单元格
+ *
+ * @param rowNumber 行坐标
+ * @param columnName 列名
+ * @return 对应坐标的单元格
+ * @throws IndexOutOfBoundsException 下标越界
+ * @throws ColumnNameNotExistException 列名不存在
+ */
+ public Cell getCell(int rowNumber, String columnName)
+ throws IndexOutOfBoundsException, ColumnNameNotExistException {
+ int columnNumber = getColumnIndex(columnName);
+ return getCell(rowNumber, columnNumber);
+ }
+
+ /**
+ * 通过坐标取得单元格
+ *
+ * @param rowNumber 行坐标
+ * @param columnNumber 列坐标
+ * @throws IndexOutOfBoundsException 下标越界
+ */
+ public final Cell getCell(int rowNumber, int columnNumber) throws IndexOutOfBoundsException {
+ if (rowNumber > this.rowIndex || rowNumber < 0) {
+ throw new IndexOutOfBoundsException("不存在的行坐标: " + rowNumber);
+ }
+ if (columnNumber > this.columnIndex || columnNumber < 0) {
+ throw new IndexOutOfBoundsException("不存在的列坐标: " + columnNumber);
+ }
+ return data[rowNumber][columnNumber];
+ }
+
+ /**
+ * 设置某个单元格的值。
+ *
+ * @param rowNumber 行坐标
+ * @param columnNumber 列坐标
+ * @param cell 单元格
+ * @throws IndexOutOfBoundsException 坐标不存在的情况下,会报出异常,提示坐标不存在。
+ */
+ public void setCell(int rowNumber, int columnNumber, Cell cell) throws IndexOutOfBoundsException {
+ if (rowNumber > this.rowIndex || rowNumber < 0) {
+ throw new IndexOutOfBoundsException("不存在的行坐标: " + rowNumber);
+ }
+ if (columnNumber > this.columnIndex || columnNumber < 0) {
+ throw new IndexOutOfBoundsException("不存在的列坐标: " + columnNumber);
+ }
+ data[rowNumber][columnNumber] = cell;
+ this.setStatus(rowNumber, columnNumber, cell.getStatus());
+ }
+
+ /**
+ * 设置某个单元格的值。注意:传入的是值
+ *
+ * @param rowIndex 行坐标
+ * @param columnName 列坐标
+ * @param cell 单元格
+ * @throws IndexOutOfBoundsException 下标越界
+ * @throws ColumnNameNotExistException 列名不存在
+ */
+ public void setCell(int rowIndex, String columnName, Cell cell)
+ throws IndexOutOfBoundsException, ColumnNameNotExistException {
+ int columnNumber = getColumnIndex(columnName);
+ this.setCell(rowIndex, columnNumber, cell);
+ }
+
+ /**
+ * 设置某个单元格的状态值 。注意:传入的是值
+ *
+ * @param rowNumber 行坐标
+ * @param columnNumber 列坐标
+ * @param status 状态值。
+ * @throws IndexOutOfBoundsException 下标越界
+ */
+ public void setStatus(int rowNumber, int columnNumber, Status status) throws IndexOutOfBoundsException {
+ if (!status.equals(Status.PASS)) {
+ Cell cell = this.getCell(rowNumber, columnNumber);
+ if (null == cell) {
+ cell = new Cell();
+ this.setCell(rowNumber, columnNumber, cell);
+ }
+ cell.setStatus(status);
+
+ StringBuilder message = new StringBuilder(this.getColumns()[columnNumber].getName());
+ message.append("栏");
+ switch (status) {
+ case NOTEXIST:
+ message.append("不存在的关联项;");
+ break;
+ case EMPTY:
+ message.append("不能为空;");
+ break;
+ case LENGTH:
+ message.append("长度超出限制;");
+ break;
+ case EXIST:
+ message.append("已存在的记录;");
+ break;
+ case ERROR_VALUE:
+ message.append("的值无法识别;");
+ break;
+ case REPEAT:
+ message.append("重复的值;");
+ break;
+ case TOO_SMALL:
+ message.append("过小的值");
+ break;
+ case TOO_BIG:
+ message.append("过大的值");
+ break;
+ case FORMAT:
+ message.append("格式错误;");
+ break;
+ }
+ this.appendError(rowNumber, message.toString());
+ }
+ }
+
+ /**
+ * 能过列名取得列下标。
+ *
+ * @param columnName 列名
+ * @return 该列对应的下标
+ * @throws ColumnNameNotExistException
+ */
+ private int getColumnIndex(String columnName) throws ColumnNameNotExistException {
+ int columnIndex = -1;
+ for (int i = 0; i < this.getColumnIndex(); i++) {
+ if (this.getColumns()[i].getName().equals(columnName)) {
+ columnIndex = i;
+ break;
+ }
+ }
+ if (columnIndex == -1) {
+ throw new ColumnNameNotExistException("不存在的列名:" + columnName);
+ }
+ return columnIndex;
+ }
+
+ /**
+ * 设置某个单元格的值。注意:传入的是值
+ *
+ * @param rowNumber 行坐标
+ * @param columnName 列坐标
+ * @param status 单元格
+ * @throws IndexOutOfBoundsException 下标越界
+ * @throws ColumnNameNotExistException 列名不存在
+ */
+ public void setStatus(int rowNumber, String columnName, Status status)
+ throws IndexOutOfBoundsException, ColumnNameNotExistException {
+ int currentColumn = getColumnIndex(columnName);
+ this.setStatus(rowNumber, currentColumn, status);
+ }
+
+ /**
+ * 按行获取所有的单元格
+ *
+ * @return 行的数组
+ */
+ public DataRow[] getDataRows() {
+ DataRow[] dataRows = new DataRow[this.rowIndex];
+ for (int i = 0; i < this.rowIndex; i++) {
+ DataRow row = new DataRow();
+ for (int j = 0; j < this.columnIndex; j++) {
+ row.put(this.columns[j].getName(), this.data[i][j]);
+ }
+ dataRows[i] = row;
+ }
+ return dataRows;
+ }
+
+ /**
+ * 按列获取所有的单元格
+ *
+ * @return 获取数据列的Map。
+ */
+ public HashMap> getDataColumns() {
+ HashMap> columns = new HashMap<>();
+ for (int i = 0; i < this.columnIndex; i++) {
+ List list = new ArrayList<>();
+ for (int j = 0; j < this.rowIndex; j++) {
+ list.add(data[j][i]);
+ }
+ columns.put(this.columns[i].getName(), list);
+ }
+ return columns;
+ }
+
+ /**
+ * 添加一行单元格。当数据量超过定义大小的一半时,会扩大容量至之前的1.5倍。
+ *
+ * @param row 一行记录
+ */
+ public void addRow(DataRow row) {
+ /* 如果占用了一半以上,进行扩容 */
+ if (this.rowIndex >= MAX_ROW_NUMBER / 2) {
+ expandRow();
+ }
+ for (int i = 0; i < this.columnIndex; i++) {
+ Cell cell = row.get(this.columns[i].getName());
+ if (null != cell) {
+ this.setCell(this.rowIndex, i, cell);
+ int width = StringUtil.getByteLength(cell.getValue());
+ if (width > this.getColumns()[i].getCellWidth()) {
+ if (width > 100) {
+ width = 100;
+ }
+ this.getColumns()[i].setCellWidth(width);
+ }
+ }
+ }
+ this.rowIndex++;
+ }
+
+ /**
+ * 添加一列表头信息,会进行查重。当列数超过定义大小的一半时,会扩大容量至之前的1.5倍。
+ *
+ * @param column 要加入的表头信息
+ */
+ public void addColumn(Column column) {
+ /* 如果占用了一半以上,进行扩容 */
+ if (this.columnIndex >= MAX_COLUMN_NUMBER / 2) {
+ expandColumn();
+ }
+ boolean exist = false;
+ column.setName(column.getName().replace("*", "")); //删除标题中的星号
+ column.setName(column.getName().replace(" ", "")); //删除标题中的空格
+ for (int i = 0; i < this.columnIndex; i++) {
+ if (column.getName().equals(this.getColumns()[i].getName())) {
+ exist = true;
+ }
+ }
+ if (!exist) {
+ this.columns[this.columnIndex++] = column;
+ } else {
+ throw new ExistedColumnNameException("已存在名称为" + column.getName() + "的列");
+ }
+ }
+
+ /**
+ * 当表空间列数不足时,扩大表和表头的列数。
+ */
+ protected void expandColumn() {
+ MAX_COLUMN_NUMBER *= (3 / 2) + 1;
+ /* 扩展表头 */
+ Column[] temp = new Column[MAX_COLUMN_NUMBER];
+ System.arraycopy(columns, 0, temp, 0, columns.length);
+ columns = temp;
+ expand();
+ }
+
+ /**
+ * 当表空间行数不足时,扩大表的行数。
+ */
+ protected void expandRow() {
+ int begin = MAX_ROW_NUMBER;
+ MAX_ROW_NUMBER *= (3 / 2) + 1;
+ for (int i = 0; i < (MAX_ROW_NUMBER - begin); i++) {
+ errorLists.add(new ArrayList());
+ }
+ expand();
+ }
+
+ /**
+ * 在扩大表的大小后调用。
+ * 会先把数据复制到临时数组中,再把临时数组指向data
+ */
+ protected void expand() {
+ Cell[][] temp = new Cell[MAX_ROW_NUMBER][MAX_COLUMN_NUMBER];
+ for (int i = 0; i < data.length; i++) {
+ System.arraycopy(data[i], 0, temp[i], 0, data[0].length);
+ }
+ data = temp;
+ }
+
+ /**
+ * 转换某行为一个对象
+ *
+ * @param clazz 类型
+ * @param rowIndex 行号
+ * @return 对象
+ * @throws IllegalAccessException
+ * @throws InstantiationException
+ * @throws NoSuchMethodException
+ * @throws InvocationTargetException
+ */
+ public T transferOneObject(Class clazz, int rowIndex)
+ throws IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {
+ T object = clazz.newInstance();
+ ParentFirst parentFirstAnnotation = clazz.getAnnotation(ParentFirst.class);
+ boolean parentFirst = parentFirstAnnotation != null && parentFirstAnnotation.value();
+ //Field[] fields = clazz.getDeclaredFields();
+ Field[] fields = ClassUtil.getFields(clazz, parentFirst);
+ Set set = new HashSet<>();
+ for (Field field : fields) {
+ if (field.isAnnotationPresent(HeaderName.class)) {
+ set.add(field);
+ }
+ }
+
+ for (int j = 0; j < this.getColumnIndex(); j++) {
+ if (this.getColumns()[j].isHidden()) {
+ continue;
+ }
+
+ String key = this.getColumns()[j].getName();
+ if (key.equals(CHECK_STATUS_NAME) || key.equals(CHECK_STATUS_RESULT)) {
+ continue;
+ }
+
+ for (Field field : set) {
+ HeaderName fieldHeaderName = field.getAnnotation(HeaderName.class);
+
+ if (key.equals(fieldHeaderName.value())) {
+
+ String att = StringUtil.upperFirstWord(field.getName());
+ String value;
+ Cell cell = this.getCell(rowIndex, j);
+ if (null != cell) {
+ value = cell.getValue();
+ Method method = clazz.getMethod("set" + att, field.getType());
+ if (field.isAnnotationPresent(Enum.class)) {
+ Enum e = field.getAnnotation(Enum.class);
+ String sValue = EnumUtil.getKey(e.target(), value);
+ if (field.getType() == String.class) {
+ method.invoke(object, sValue);
+ } else {
+ method.invoke(object, EnumUtil.valueOf(e.target(), sValue));
+ }
+ } else if (field.isAnnotationPresent(Type.class)) {
+ Type type = field.getAnnotation(Type.class);
+ switch (type.value()) {
+ case DATETIME:
+ case DATE: {
+ Date date = TransferUtil.transferDate(value);
+ method.invoke(object, date);
+ break;
+ }
+ case DATEMINUTE: {
+ Date date = TransferUtil.transferDateminute(value);
+ method.invoke(object, date);
+ break;
+ }
+ case DECIMAL:
+ Double d = TransferUtil.transferDouble(value);
+ method.invoke(object, d);
+ break;
+
+ case NUMBER:
+ Integer integer = TransferUtil.transferInteger(value);
+ method.invoke(object, integer);
+ break;
+
+ case BOOLEAN:
+ Boolean b = TransferUtil.transferBoolean(value);
+ method.invoke(object, b);
+ break;
+
+ case LONG:
+ Long l = TransferUtil.transferLong(value);
+ method.invoke(object, l);
+ break;
+ default:
+ method.invoke(object, value);
+ break;
+ }
+ } else {
+ method.invoke(object, value);
+ }
+ }
+ break;
+ }
+ }
+ }
+ return object;
+ }
+
+ /**
+ * 将DataTable转为T型的List
+ * 如果你试图这么做,请确保在每个字段上都加上了@Name注解
+ * 并确保该注解的值与DataTable中列的名字一致。
+ * 注解的值在这里作为唯一的标识。
+ *
+ * @return T型列表
+ * @see Column 列名称
+ */
+ public List transferList(Class clazz)
+ throws IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {
+ List list = new ArrayList<>();
+
+ for (int i = 0; i < this.getRowIndex(); i++) {
+ T object = transferOneObject(clazz, i);
+ list.add(object);
+ }
+ return list;
+ }
+
+ /**
+ * 获取表名
+ *
+ * @return 表名
+ */
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * 设置表名
+ *
+ * @param name 表名
+ */
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ /**
+ * 获取当前总行数。
+ *
+ * @return 总行数
+ */
+ public int getRowIndex() {
+ return rowIndex;
+ }
+
+ /**
+ * 获取当前总列数。
+ *
+ * @return 总列数
+ */
+ public int getColumnIndex() {
+ return columnIndex;
+ }
+
+ public final String toCSV() {
+ StringBuilder sb = new StringBuilder();
+
+ for (Column column : this.getColumns()) {
+ if (column != null) {
+ sb.append(column.getName()).append(",");
+ }
+ }
+ sb.append("\n");
+
+ for (int i = 0; i < this.getRowIndex(); i++) {
+ for (int j = 0; j < this.getColumnIndex(); j++) {
+ Cell cell = this.getCell(i, j);
+ if (this.getColumns()[j].getDataType().equals(DataType.STRING)
+ || this.getColumns()[j].getDataType().equals(DataType.DATE)
+ || this.getColumns()[j].getDataType().equals(DataType.DATETIME)
+ || this.getColumns()[j].getDataType().equals(DataType.DATEMINUTE)) {
+ sb.append("\"\t").append(cell.getValue()).append("\",");
+ } else {
+ sb.append(cell.getValue()).append(",");
+ }
+ }
+ sb.append("\n");
+ }
+
+ return sb.toString();
+ }
+
+ @Override
+ public final String toString() {
+ for (int i = 0; i < columnIndex; i++) {
+ for (int j = 0; j < rowIndex; j++) {
+ int length = StringUtil.getByteLength(this.getCell(j, i).getValue());
+ if (columns[i].getCellWidth() < length) {
+ if (length > 100) {
+ length = 100;
+ }
+ columns[i].setCellWidth(length);
+ }
+ }
+ }
+ StringBuilder sb = new StringBuilder("");
+ int sumWidth = 0;
+
+ /* 打印表头 */
+
+ for (int i = 0; i < this.getColumnIndex(); i++) {
+ Column column = this.getColumns()[i];
+ int width = column.getCellWidth() - StringUtil.getByteLength(column.getName()) + 4;
+ int left = width / 2;
+ int right = width - left;
+
+ for (int j = 0; j < left; j++) {
+ sb.append(" ");
+ }
+ sb.append(column.getName());
+ for (int j = 0; j < right; j++) {
+ sb.append(" ");
+ }
+ sumWidth += column.getCellWidth();
+ }
+
+ sb.append(CHECK_STATUS_NAME);
+ sb.append(" ");
+ sb.append(CHECK_STATUS_RESULT);
+ sb.append("\n");
+ for (int i = 0; i < sumWidth + (4 * this.getColumnIndex()) + 18; i++) {
+ sb.append("=");
+ }
+ sb.append("\n");
+
+ /* 打印数据 */
+ for (int i = 0; i < this.getRowIndex(); i++) {
+ for (int j = 0; j < this.getColumnIndex(); j++) {
+ int cellWidth = this.getColumns()[j].getCellWidth();
+ Cell cell = null;
+ try {
+ cell = this.getCell(i, j);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ if (null != cell) {
+ Object obj = cell.getValue();
+ int width = cellWidth - StringUtil.getByteLength(obj.toString()) + 4;
+ int left = width / 2;
+ int right = width - left;
+
+ for (int k = 0; k < left; k++) {
+ sb.append(" ");
+ }
+ sb.append(obj);
+ if (Status.PASS != cell.getStatus()) {
+ sb.append("*");
+ if (right > 1) {
+ right--;
+ }
+ }
+ for (int k = 0; k < right; k++) {
+ sb.append(" ");
+ }
+ } else {
+ for (int k = 0; k < cellWidth + 4; k++) {
+ sb.append(" ");
+ }
+ }
+ }
+ if (errorLists.get(i).size() == 0) {
+ sb.append(" 通过 ");
+ } else {
+ sb.append(" 不通过 ");
+ for (Error error : errorLists.get(i)) {
+ sb.append(error.getMessage());
+ }
+ }
+ sb.append("\n");
+ }
+ return sb.toString();
+ }
+
+ /**
+ * 获取Table内所有的错误消息
+ *
+ * @return 所有的错误集合
+ */
+ public List getErrorList() {
+ return errorList;
+ }
+
+ /**
+ * 获取某一行的错误消息
+ *
+ * @param rowNumber 要获取错误消息的行数
+ * @return 该行的错误消息
+ * @throws IndexOutOfBoundsException 下标越界
+ */
+ public String getRowError(int rowNumber) throws IndexOutOfBoundsException {
+ if (rowNumber > this.rowIndex) {
+ throw new IndexOutOfBoundsException("不存在的行数:" + rowIndex);
+ }
+ StringBuilder stringBuilder = new StringBuilder();
+ if (this.errorLists.get(rowNumber).size() > 0) {
+ for (Error error : this.errorLists.get(rowNumber)) {
+ stringBuilder.append(error.getMessage());
+ }
+ return stringBuilder.toString();
+ }
+ return null;
+ }
+
+ /**
+ * 添加错误信息
+ *
+ * @param rowNumber 错误出现的行数
+ * @param message 错误消息
+ * @throws IndexOutOfBoundsException 下标越界
+ */
+ public void appendError(int rowNumber, String message) throws IndexOutOfBoundsException {
+ if (rowNumber > this.rowIndex) {
+ throw new IndexOutOfBoundsException("不存在的行数:" + rowNumber);
+ }
+ if (errorLists.get(rowNumber) == null) {
+ errorLists.set(rowNumber, new ArrayList());
+ }
+ Error rowError = new Error(ErrorType.INVALID_PARAMETER, message);
+ Error error = new Error(ErrorType.INVALID_PARAMETER, "第" + (rowNumber + 2) + "行:" + message);
+ errorLists.get(rowNumber).add(rowError);
+ errorList.add(error);
+ }
+
+ /**
+ * 判断DataTable是否包含错误信息
+ *
+ * @return 是否包含错误.
+ */
+ public final boolean hasError() {
+ return this.errorList.size() > 0;
+ }
+
+ @Deprecated
+ public final String getErrorMessage() {
+ StringBuilder sb = new StringBuilder();
+ for (Error error : this.errorList) {
+ sb.append(error.getMessage());
+ }
+ return sb.toString();
+ }
+
+ public List> getErrorLists() {
+ return errorLists;
+ }
+
+ public void setErrorLists(List> errorLists) {
+ this.errorLists = errorLists;
+ }
+}
diff --git a/src/main/java/com/wb/excel/api/datatable/ExcelImport.java b/src/main/java/com/wb/excel/api/datatable/ExcelImport.java
new file mode 100644
index 0000000..42c10fa
--- /dev/null
+++ b/src/main/java/com/wb/excel/api/datatable/ExcelImport.java
@@ -0,0 +1,601 @@
+package com.wb.excel.api.datatable;
+
+import com.wb.excel.api.annotation.HeaderDescription;
+import com.wb.excel.api.annotation.ExcelCollection;
+import com.wb.excel.api.annotation.ExcelVerify;
+import com.wb.excel.api.annotation.IsDuplicated;
+import com.wb.excel.api.entity.*;
+import com.wb.excel.api.style.ErrorCellStyle;
+import com.wb.excel.api.util.ClassUtil;
+import com.wb.excel.api.util.EnumUtil;
+import com.wb.excel.api.util.StringUtils;
+import com.wb.excel.api.util.VerifyDataUtil;
+import org.apache.poi.POIXMLDocument;
+import org.apache.poi.hssf.usermodel.HSSFWorkbook;
+import org.apache.poi.openxml4j.opc.OPCPackage;
+import org.apache.poi.poifs.filesystem.POIFSFileSystem;
+import org.apache.poi.ss.formula.functions.T;
+import org.apache.poi.ss.usermodel.Cell;
+import org.apache.poi.ss.usermodel.*;
+import org.apache.poi.xssf.usermodel.XSSFWorkbook;
+import com.wb.excel.api.annotation.HeaderName;
+import com.wb.excel.api.annotation.Enum;
+import java.io.InputStream;
+import java.io.PushbackInputStream;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.lang.reflect.ParameterizedType;
+import java.sql.Time;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.*;
+
+/**
+ * ***************************************************************
+ *
+ *
+ * Copyright (c) 2014 –
+ * HeaderDescription:
+ * ***************************************************************
+ *
+ */
+public class ExcelImport {
+ /**
+ * 异常数据styler
+ */
+ private CellStyle errorMessageStyle;
+ private boolean verfiyFail = false;
+ private VerifyDataUtil verifyDataUtil = new VerifyDataUtil();
+ private Map verifyResultMap = new HashMap<>();
+ private CellStyle errorcellStyle;
+
+ /**
+ * 根据数据流解析Excel
+ *
+ * @param inputstream
+ * @param pojoClass
+ * @return
+ */
+ public ExcelImportResult importExcelByIs(InputStream inputstream, Class> pojoClass, ImportParams importParams) throws Exception {
+ List result = new ArrayList();
+ Workbook book = null;
+ if (!(inputstream.markSupported())) {
+ inputstream = new PushbackInputStream(inputstream, 8);
+ }
+ if (POIFSFileSystem.hasPOIFSHeader(inputstream)) {
+ book = new HSSFWorkbook(inputstream);
+// isXSSFWorkbook = false;
+ } else if (POIXMLDocument.hasOOXMLHeader(inputstream)) {
+ book = new XSSFWorkbook(OPCPackage.open(inputstream));
+ }
+// createErrorCellStyle(book);
+ errorcellStyle = new ErrorCellStyle(book).getStyle();
+ for (int i = 0; i < importParams.getSheetNum(); i++) {
+ result.addAll(importExcel(result, book.getSheetAt(i), pojoClass, importParams));
+ }
+ return new ExcelImportResult(result, verfiyFail, book, verifyResultMap);
+ }
+
+ /**
+ * @param result
+ * @param sheet
+ * @param pojoClass
+ * @param
+ * @return
+ */
+ private Collection extends T> importExcel(List result, Sheet sheet, Class> pojoClass, ImportParams importParams) throws Exception {
+ List collection = new ArrayList();
+ //Excel Field 对象
+ Map excelParams = new HashMap();
+ //Excel Line 对象
+ List excelCollection = new ArrayList();
+ if (!Map.class.equals(pojoClass)) {
+ //获取所有的参数信息
+ Field fields[] = ClassUtil.getClassFields(pojoClass);
+ getAllExcelField(fields, excelParams, excelCollection, pojoClass, null);
+ }
+ Iterator rows = sheet.rowIterator();
+ Map titlemap = null;
+ Row row = null;
+ Object object = null;
+ if (rows.hasNext()) {
+ row = rows.next();// 排除标题信息
+ titlemap = getTitleMap(row, excelParams, excelCollection);
+ }
+ while (rows.hasNext() && (row == null || sheet.getLastRowNum() - row.getRowNum() > 0)) {
+ row = rows.next();//获取某一行信息
+ // 判断是集合元素还是不是集合元素,如果是就继续加入这个集合,不是就创建新的对象
+ if (isLineRow(row, excelParams, titlemap) && object != null) {
+ for (ExcelCollectionEntity param : excelCollection) {
+ addListContinue(object, param, row, titlemap, importParams);
+ }
+ } else {
+ object = ClassUtil.createObject(pojoClass);
+ try {
+ for (int i = row.getFirstCellNum(), le = row.getLastCellNum(); i < le; i++) {
+ Cell cell = row.getCell(i) == null ? row.createCell(i) : row.getCell(i);
+ String titleString = (String) titlemap.get(i);
+ if (excelParams.containsKey(titleString) || Map.class.equals(pojoClass)) {
+ saveFieldValue(object, cell, excelParams, titleString, row, importParams);
+ }
+ }
+ for (ExcelCollectionEntity param : excelCollection) {
+ addListContinue(object, param, row, titlemap, importParams);
+ }
+ collection.add(object);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+ }
+ return collection;
+ }
+
+
+ /**
+ * 获取列数据,根据列属性
+ *
+ * @param cell
+ * @return
+ */
+ private Object getCellValue(Cell cell) {
+ Object result = null;
+ if (cell != null) {
+ if (Cell.CELL_TYPE_NUMERIC == cell.getCellType()) {
+ result = cell.getNumericCellValue();
+ } else if (Cell.CELL_TYPE_BOOLEAN == cell.getCellType()) {
+ result = cell.getBooleanCellValue();
+ } else {
+ result = cell.getStringCellValue();
+ }
+ }
+ result = result == null ? "" : result;
+ return result;
+ }
+
+ /**
+ * 保存数据
+ *
+ * @param object
+ * @param cell
+ * @param excelParams
+ * @param titleString
+ * @param row
+ */
+ private void saveFieldValue(Object object, Cell cell, Map excelParams, String titleString, Row row, ImportParams importParams) throws Exception {
+ ExcelImportEntity entity = excelParams.get(titleString);
+ String xclass = "class java.lang.Object";
+ if (!(object instanceof Map)) {
+
+ Method setMethod = entity.getMethods() != null && entity.getMethods().size() > 0 ? entity
+ .getMethods().get(entity.getMethods().size() - 1) : entity.getMethod();
+ java.lang.reflect.Type[] ts = setMethod.getGenericParameterTypes();
+ xclass = ts[0].toString();
+ }
+ Object result = getCellValue(xclass, cell, entity);
+
+// if (entity != null) {
+ // 做值处理
+// result = replaceValue(entity., result);
+// }
+ if (entity != null && entity.getEnum() != null) {
+ boolean ischeck = EnumUtil.check(entity.getEnum(), String.valueOf(result));
+ if (!ischeck) {
+ DataVerifyResult verifyResult = new DataVerifyResult();
+ verifyResult.setSuccess(false);
+ verifyResult.setMsg("参数[" + entity.getShowname() + "," + result + "]未匹配相应的值信息");
+ verifyResultMap.put(row.getRowNum(), verifyResult);
+ } else {
+ result = EnumUtil.getKey(entity.getEnum(), String.valueOf(result));
+ setValues(entity, object, result);
+ }
+ }
+ if (result instanceof Map) {
+ ((Map) object).put(titleString, result);
+ } else {
+ //可以做值校验
+ DataVerifyResult verifyResult = verifyDataUtil.verifyData(object, result, entity.getFiledName(), entity.getShowname(), entity.getVerify(), importParams.getVerifyHanlder());
+ //设置校验结果(第一列)
+ if (verifyResult.isSuccess()) {
+ setValues(entity, object, result);
+ } else {
+ Integer rowNum = Integer.valueOf(row.getRowNum());
+ if (verifyResultMap.containsKey(rowNum)) {
+ // 如果有错误信息,则添加错误数据
+ DataVerifyResult tempresult = verifyResultMap.get(rowNum);
+ tempresult.setMsg(tempresult.getMsg() + " " + verifyResult.getMsg());
+ verifyResultMap.put(rowNum, tempresult);
+ } else {
+ verifyResultMap.put(rowNum, verifyResult);
+ }
+ verfiyFail = true;
+ }
+ }
+ }
+
+ public void setValues(ExcelImportEntity entity, Object object, Object value) throws Exception {
+ if (entity.getMethods() != null) {
+ setFieldBySomeMethod(entity.getMethods(), object, value);
+ } else {
+ /*
+ if (String.class.isAssignableFrom(entity.getMethod().getParameterTypes()[0])) {
+ entity.getMethod().invoke(object, value);
+ } else if (Long.class.isAssignableFrom(entity.getMethod().getParameterTypes()[0])) {
+ entity.getMethod().invoke(object, Long.valueOf(value.toString()));
+ } else if (int.class.isAssignableFrom(entity.getMethod().getParameterTypes()[0])) {
+ entity.getMethod().invoke(object, Integer.valueOf(value.toString()));
+ } else if (boolean.class.isAssignableFrom(entity.getMethod().getParameterTypes()[0])) {
+ entity.getMethod().invoke(object, Boolean.valueOf(value.toString()));
+ } else if (Boolean.class.isAssignableFrom(entity.getMethod().getParameterTypes()[0])) {
+ entity.getMethod().invoke(object, Boolean.valueOf(value.toString()));
+ } else if (Double.class.isAssignableFrom(entity.getMethod().getParameterTypes()[0])) {
+ entity.getMethod().invoke(object, Double.valueOf(value.toString()));
+ } else if (Integer.class.isAssignableFrom(entity.getMethod().getParameterTypes()[0])) {
+ entity.getMethod().invoke(object, Integer.valueOf(value.toString()));
+ } else if (Long.class.isAssignableFrom(entity.getMethod().getParameterTypes()[0])) {
+ entity.getMethod().invoke(object, Long.valueOf(value.toString()));
+ } else if (Float.class.isAssignableFrom(entity.getMethod().getParameterTypes()[0])) {
+ entity.getMethod().invoke(object, Float.valueOf(value.toString()));
+ } else if (Short.class.isAssignableFrom(entity.getMethod().getParameterTypes()[0])) {
+ entity.getMethod().invoke(object, Short.valueOf(value.toString()));
+ } else if (Number.class.isAssignableFrom(entity.getMethod().getParameterTypes()[0])) {
+ entity.getMethod().invoke(object, (Number) value);
+ } else {
+
+ }*/
+ entity.getMethod().invoke(object, value);
+ }
+ }
+
+ public void setFieldBySomeMethod(List setMethods, Object object, Object value)
+ throws Exception {
+ Object t = getFieldBySomeMethod(setMethods, object);
+ setMethods.get(setMethods.size() - 1).invoke(t, value);
+ }
+
+ public Object getFieldBySomeMethod(List list, Object t) throws Exception {
+ Method m;
+ for (int i = 0; i < list.size() - 1; i++) {
+ m = list.get(i);
+ t = m.invoke(t, new Object[]{});
+ }
+ return t;
+ }
+
+ /**
+ * 获取单元格内的值
+ *
+ * @param xclass
+ * @param cell
+ * @param entity
+ * @return
+ */
+ private Object getCellValue(String xclass, Cell cell, ExcelImportEntity entity) {
+ if (cell == null) {
+ return "";
+ }
+ Object result = null;
+ // 日期格式比较特殊,和cell格式不一致
+ if ("class java.util.Date".equals(xclass) || ("class java.sql.Time").equals(xclass)) {
+ if (Cell.CELL_TYPE_NUMERIC == cell.getCellType()) {
+ // 日期格式
+ result = cell.getDateCellValue();
+ } else {
+ cell.setCellType(Cell.CELL_TYPE_STRING);
+ result = getDateData(entity, cell.getStringCellValue());
+ }
+ if (("class java.sql.Time").equals(xclass)) {
+ result = new Time(((Date) result).getTime());
+ }
+ } else if (Cell.CELL_TYPE_NUMERIC == cell.getCellType()) {
+ result = cell.getNumericCellValue();
+ } else if (Cell.CELL_TYPE_BOOLEAN == cell.getCellType()) {
+ result = cell.getBooleanCellValue();
+ } else {
+ result = cell.getStringCellValue();
+ }
+ if ("class java.lang.String".equals(xclass)) {
+ result = String.valueOf(result);
+ }
+ return result;
+ }
+
+ /**
+ * 获取日期类型数据
+ *
+ * @param entity
+ * @param value
+ * @return
+ * @Author JueYue
+ * @date 2013年11月26日
+ */
+ private Date getDateData(ExcelImportEntity entity, String value) {
+ if (StringUtils.isNotEmpty(entity.getDateFormat()) && StringUtils.isNotEmpty(value)) {
+ SimpleDateFormat format = new SimpleDateFormat(entity.getDateFormat());
+ try {
+ return format.parse(value);
+ } catch (ParseException e) {
+// LOGGER.error("时间格式化失败,格式化:" + entity.getDateFormat() + ",值:" + value);
+ e.printStackTrace();
+ }
+ }
+ return null;
+ }
+
+ /**
+ * 向List 里面添加元素
+ *
+ * @param object
+ * @param param
+ * @param row
+ * @param titlemap
+ */
+ private void addListContinue(Object object, ExcelCollectionEntity param, Row row, Map titlemap, ImportParams importParams) throws Exception {
+ Collection collection = (Collection) ClassUtil.getMethod(param.getName(),
+ object.getClass()).invoke(object, new Object[]{});
+ Object entity = ClassUtil.createObject(param.getType());
+ boolean isUsed = false;// 是否需要加上这个对象
+ for (int i = row.getFirstCellNum(); i < row.getLastCellNum(); i++) {
+ Cell cell = row.getCell(i);
+ String titleString = (String) titlemap.get(i);
+ if (param.getExcelParams().containsKey(titleString)) {
+ saveFieldValue(entity, cell, param.getExcelParams(), titleString, row, importParams);
+ isUsed = true;
+ }
+ }
+ if (isUsed) {
+ collection.add(entity);
+ }
+
+ }
+
+ /**
+ * 查看某些列的数据,是否存在
+ *
+ * @param row
+ * @param excelParams
+ * @return
+ */
+ private Boolean isLineRow(Row row, Map excelParams, Map titlemap) {
+ Boolean isLineRow = true;
+ for (Integer index : titlemap.keySet()) {
+ String titleName = titlemap.get(index);
+ if (excelParams.containsKey(titleName)) {
+ Cell cell = row.getCell(index);
+ Object value = getCellValue("", cell, excelParams.get(titleName));
+ if (!StringUtils.isEmpty(String.valueOf(value))) {
+ isLineRow = false;
+ break;
+ }
+ }
+ }
+ return isLineRow;
+ }
+
+ /**
+ * 获取Title 与Index 关系
+ *
+ * @param row
+ * @param excelParams
+ * @param excelCollection
+ * @return
+ */
+ private Map getTitleMap(Row row, Map excelParams, List excelCollection) throws Exception {
+ Map titlemap = new HashMap();
+ Iterator cellTitle = row.cellIterator();
+ while (cellTitle.hasNext()) {
+ Cell cell = cellTitle.next();
+ String value = getKeyValue(cell).replace("*", "").replace("\n", "");
+ int i = cell.getColumnIndex();
+ //支持重名导入
+ if (StringUtils.isNotEmpty(value)) {
+ //判断当前列索引,是否为明细值
+ if (!excelParams.containsKey(value)) {
+ if (excelCollection != null && !excelCollection.isEmpty()) {
+ for (ExcelCollectionEntity entity : excelCollection) {
+ if (entity.getExcelParams().containsKey(entity.getExcelName() + "_" + value)) {
+ ExcelImportEntity excelImportEntity = entity.getExcelParams().get(entity.getExcelName() + "_" + value);
+ excelImportEntity.setFiledName(entity.getName() + "_" + excelImportEntity.getFiledName());
+ titlemap.put(i, entity.getExcelName() + "_" + value);
+ break;
+ }
+ }
+ }
+ } else {
+ titlemap.put(i, value);
+ }
+ }
+ }
+ //判断是否所有的列都满足,不满足抛Exception
+ //1判断主要信息
+ Set params = excelParams.keySet();
+ StringBuffer sb = new StringBuffer();
+ for (String key : params) {
+ if (!titlemap.containsValue(key)) {
+ sb.append(key).append(" ");
+ }
+ }
+ for (ExcelCollectionEntity entity : excelCollection) {
+ Set eparams = entity.getExcelParams().keySet();
+ for (String key : eparams) {
+ if (!titlemap.containsValue(key)) {
+ sb.append(key).append(" ");
+ }
+ }
+ }
+ if (sb.length() > 0) {
+ throw new Exception("不匹配的Excel文件,缺少如下标题:" + sb.toString());
+ }
+ return titlemap;
+ }
+
+ /**
+ * 获取key的值,针对不同类型获取不同的值
+ *
+ * @param cell
+ * @return
+ * @Author JueYue
+ * @date 2013-11-21
+ */
+ private String getKeyValue(Cell cell) {
+ Object obj = null;
+ switch (cell.getCellType()) {
+ case Cell.CELL_TYPE_STRING:
+ obj = cell.getStringCellValue();
+ break;
+ case Cell.CELL_TYPE_BOOLEAN:
+ obj = cell.getBooleanCellValue();
+ break;
+ case Cell.CELL_TYPE_NUMERIC:
+ obj = cell.getNumericCellValue();
+ break;
+ }
+ return obj == null ? null : obj.toString().trim();
+ }
+
+ /**
+ * 解析获取Excel 信息
+ *
+ * @param fields
+ * @param excelParams
+ * @param excelCollection
+ * @param pojoClass
+ * @param getMethods
+ */
+ private void getAllExcelField(Field[] fields, Map excelParams, List excelCollection, Class> pojoClass, List getMethods) throws Exception {
+ ExcelImportEntity excelEntity = null;
+ for (int i = 0; i < fields.length; i++) {
+ Field field = fields[i];
+ // 判断是否有注解,没有注解,不需要解析
+ HeaderName headerName = field.getAnnotation(HeaderName.class);
+ ExcelCollection collectionannotation = field.getAnnotation(ExcelCollection.class);
+ if (headerName != null || collectionannotation != null) {
+ //如果是List 类型
+ if (ClassUtil.isCollection(field.getType())) {
+ // 集合对象设置属性
+ ExcelCollectionEntity collection = new ExcelCollectionEntity();
+ collection.setName(field.getName());
+ Map temp = new HashMap();
+ ParameterizedType pt = (ParameterizedType) field.getGenericType();
+ Class> clz = (Class>) pt.getActualTypeArguments()[0];
+ collection.setType(clz);
+ getExcelFieldList(ClassUtil.getClassFields(clz), clz, temp, null);
+ collection.setExcelParams(temp);
+ collection.setExcelName(field.getAnnotation(ExcelCollection.class).value());
+ additionalCollectionName(collection);
+ excelCollection.add(collection);
+ } else if (ClassUtil.isJavaClass(field)) {
+ addEntityToMap(field, excelEntity, pojoClass, getMethods, excelParams);
+ } else {
+ List newMethods = new ArrayList();
+ if (getMethods != null) {
+ newMethods.addAll(getMethods);
+ }
+ newMethods.add(ClassUtil.getMethod(field.getName(), pojoClass));
+ getAllExcelField(ClassUtil.getClassFields(field.getType()),
+ excelParams, excelCollection, field.getType(), newMethods);
+ }
+ }
+ }
+
+
+ }
+
+ private void addEntityToMap(Field field, ExcelImportEntity excelEntity, Class> pojoClass, List getMethods, Map temp) throws Exception {
+ HeaderName excel = field.getAnnotation(HeaderName.class);
+ if (excel != null) {
+ excelEntity = new ExcelImportEntity();
+ excelEntity.setShowname(excel.value());
+ excelEntity.setFiledName(field.getName());
+ Enum targetEnum = field.getAnnotation(Enum.class);
+ if (targetEnum != null) {
+ excelEntity.setEnum(targetEnum.target());
+ }
+ excelEntity.setVerify(getImportVerify(field));
+ HeaderDescription headerDescription = field.getAnnotation(HeaderDescription.class);
+ excelEntity.setDescription(headerDescription == null ? "" : headerDescription.value());
+ IsDuplicated isDuplicated = field.getAnnotation(IsDuplicated.class);
+ if (isDuplicated != null) {
+ excelEntity.setIsDuplicated(isDuplicated.value());
+ }
+ getExcelField(field, excelEntity, excel, pojoClass);
+ if (getMethods != null) {
+ List newMethods = new ArrayList();
+ newMethods.addAll(getMethods);
+ newMethods.add(excelEntity.getMethod());
+ excelEntity.setMethods(newMethods);
+ }
+ temp.put(excelEntity.getShowname(), excelEntity);
+ }
+ }
+
+ /**
+ * 获取导入校验参数
+ *
+ * @param field
+ * @return
+ */
+ public ExcelVerifyEntity getImportVerify(Field field) {
+ ExcelVerify verify = field.getAnnotation(ExcelVerify.class);
+ if (verify != null) {
+ ExcelVerifyEntity entity = new ExcelVerifyEntity();
+ entity.setEmail(verify.isEmail());
+ entity.setInterHandler(verify.interHandler());
+ entity.setMaxLength(verify.maxLength());
+ entity.setMinLength(verify.minLength());
+ entity.setMobile(verify.isMobile());
+ entity.setNotNull(verify.notNull());
+ entity.setRegex(verify.regex());
+ entity.setRegexTip(verify.regexTip());
+ entity.setTel(verify.isTel());
+ return entity;
+ }
+ return null;
+ }
+
+ /**
+ * 获取Excel 列信息
+ *
+ * @param field
+ * @param excelEntity
+ * @param excel
+ * @param pojoClass
+ */
+ private void getExcelField(Field field, ExcelImportEntity excelEntity, HeaderName excel, Class> pojoClass) throws Exception {
+ String fieldname = field.getName();
+ excelEntity.setMethod(ClassUtil.getMethod(fieldname, pojoClass, field.getType()));
+ if (StringUtils.isNotEmpty(excel.dateFormat())) {
+ excelEntity.setDateFormat(excel.dateFormat());
+ }
+ }
+
+ private void additionalCollectionName(ExcelCollectionEntity collection) {
+ Set keys = new HashSet();
+ keys.addAll(collection.getExcelParams().keySet());
+ for (String key : keys) {
+ collection.getExcelParams().put(collection.getExcelName() + "_" + key,
+ collection.getExcelParams().get(key));
+ collection.getExcelParams().remove(key);
+ }
+ }
+
+ private void getExcelFieldList(Field[] fields, Class> pojoClass, Map temp, List getMethods) throws Exception {
+ ExcelImportEntity excelEntity = null;
+ for (int i = 0; i < fields.length; i++) {
+ Field field = fields[i];
+ if (ClassUtil.isJavaClass(field)) {
+ addEntityToMap(field, excelEntity, pojoClass, getMethods, temp);
+ } else {
+ List newMethods = new ArrayList();
+ if (getMethods != null) {
+ newMethods.addAll(getMethods);
+ }
+ newMethods.add(ClassUtil.getMethod(field.getName(), pojoClass, field.getType()));
+ getExcelFieldList(ClassUtil.getClassFields(field.getType()),
+ field.getType(), temp, newMethods);
+ }
+ }
+ }
+
+
+}
diff --git a/src/main/java/com/wb/excel/api/datatable/ImportParams.java b/src/main/java/com/wb/excel/api/datatable/ImportParams.java
new file mode 100644
index 0000000..244583a
--- /dev/null
+++ b/src/main/java/com/wb/excel/api/datatable/ImportParams.java
@@ -0,0 +1,62 @@
+package com.wb.excel.api.datatable;
+
+import com.wb.excel.api.interfaces.IExcelVerifyHandler;
+
+/**
+ * ***************************************************************
+ *
+ *
+ * Copyright (c) 2014 –
+ * HeaderDescription:导入参数设置
+ * ***************************************************************
+ *
+ */
+public class ImportParams {
+// /**
+// * 表格标题行数,默认0
+// */
+// private int titleRows = 0;
+// /**
+// * 表头行数,默认1
+// */
+// private int headRows = 1;
+// /**
+// * 字段真正值和列标题之间的距离 默认0
+// */
+// private int startRows = 0;
+// /**
+// * 主键设置,如何这个cell没有值,就跳过 或者认为这个是list的下面的值
+// */
+// private int keyIndex = 0;
+ /**
+ * 上传表格需要读取的sheet 数量,默认为1
+ */
+ private int sheetNum = 1;
+
+ /**
+ * 校验处理接口
+ */
+ private IExcelVerifyHandler verifyHanlder;
+// /**
+// * 最后的无效行数
+// */
+// private int lastOfInvalidRow = 0;
+
+
+ public int getSheetNum() {
+ return sheetNum;
+ }
+
+ public void setSheetNum(int sheetNum) {
+ this.sheetNum = sheetNum;
+ }
+
+ public IExcelVerifyHandler getVerifyHanlder() {
+ return verifyHanlder;
+ }
+
+ public void setVerifyHanlder(IExcelVerifyHandler verifyHanlder) {
+ this.verifyHanlder = verifyHanlder;
+ }
+
+}
diff --git a/src/main/java/com/wb/excel/api/entity/DataVerifyResult.java b/src/main/java/com/wb/excel/api/entity/DataVerifyResult.java
new file mode 100644
index 0000000..9fb9ed9
--- /dev/null
+++ b/src/main/java/com/wb/excel/api/entity/DataVerifyResult.java
@@ -0,0 +1,51 @@
+package com.wb.excel.api.entity;
+
+import java.io.Serializable;
+
+/**
+ * ***************************************************************
+ *
+ *
+ * Copyright (c) 2014 –
+ * HeaderDescription:数据校验结果
+ * ***************************************************************
+ *
+ */
+public class DataVerifyResult implements Serializable {
+ /**
+ * 是否正确
+ */
+ private boolean success;
+ /**
+ * 错误信息
+ */
+ private String msg;
+
+ public DataVerifyResult() {
+ }
+
+ public DataVerifyResult(boolean issuccess) {
+ this.success = issuccess;
+ }
+
+ public DataVerifyResult(boolean success, String msg) {
+ this.success = success;
+ this.msg = msg;
+ }
+
+ public boolean isSuccess() {
+ return success;
+ }
+
+ public void setSuccess(boolean success) {
+ this.success = success;
+ }
+
+ public String getMsg() {
+ return msg;
+ }
+
+ public void setMsg(String msg) {
+ this.msg = msg;
+ }
+}
diff --git a/src/main/java/com/wb/excel/api/entity/ExcelCollectionEntity.java b/src/main/java/com/wb/excel/api/entity/ExcelCollectionEntity.java
new file mode 100644
index 0000000..f3b676a
--- /dev/null
+++ b/src/main/java/com/wb/excel/api/entity/ExcelCollectionEntity.java
@@ -0,0 +1,61 @@
+package com.wb.excel.api.entity;
+
+import java.util.Map;
+
+/**
+ * ***************************************************************
+ *
+ *
+ * Copyright (c) 2014 –
+ * HeaderDescription:Excel 集合对象
+ * ***************************************************************
+ *
+ */
+public class ExcelCollectionEntity {
+ /**
+ * 集合对应的名称
+ */
+ private String name;
+ /**
+ * Excel 列名称
+ */
+ private String excelName;
+ /**
+ * 实体对象
+ */
+ private Class> type;
+
+ private Map excelParams;
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getExcelName() {
+ return excelName;
+ }
+
+ public void setExcelName(String excelName) {
+ this.excelName = excelName;
+ }
+
+ public Class> getType() {
+ return type;
+ }
+
+ public void setType(Class> type) {
+ this.type = type;
+ }
+
+ public Map getExcelParams() {
+ return excelParams;
+ }
+
+ public void setExcelParams(Map excelParams) {
+ this.excelParams = excelParams;
+ }
+}
diff --git a/src/main/java/com/wb/excel/api/entity/ExcelEntity.java b/src/main/java/com/wb/excel/api/entity/ExcelEntity.java
new file mode 100644
index 0000000..64370ba
--- /dev/null
+++ b/src/main/java/com/wb/excel/api/entity/ExcelEntity.java
@@ -0,0 +1,124 @@
+package com.wb.excel.api.entity;
+
+import java.lang.reflect.Method;
+import java.util.List;
+
+/**
+ * ***************************************************************
+ *
+ *
+ * Copyright (c) 2014 –
+ * HeaderDescription:
+ * ***************************************************************
+ *
+ */
+public class ExcelEntity {
+ /**
+ * 参数名称
+ */
+ protected String filedName;
+ /**
+ * 对应name
+ */
+ protected String showname;
+ /**
+ * 对应的枚举类型
+ */
+ protected Class Enum;
+ /**
+ * 对应的数据格式化
+ */
+ protected String split;
+
+ /**
+ * 注释
+ */
+ protected String description;
+ /**
+ * 是否重复
+ */
+ protected Boolean isDuplicated;
+ /**
+ * 日期格式化
+ */
+ protected String dateFormat = "yyyy-MM-dd";
+
+ /**
+ * set/get方法
+ */
+ private Method method;
+ private List methods;
+
+ public String getFiledName() {
+ return filedName;
+ }
+
+ public void setFiledName(String filedName) {
+ this.filedName = filedName;
+ }
+
+ public String getShowname() {
+ return showname;
+ }
+
+ public void setShowname(String showname) {
+ this.showname = showname;
+ }
+
+ public Class getEnum() {
+ return Enum;
+ }
+
+ public void setEnum(Class anEnum) {
+ Enum = anEnum;
+ }
+
+ public String getSplit() {
+ return split;
+ }
+
+ public void setSplit(String split) {
+ this.split = split;
+ }
+
+
+ public Method getMethod() {
+ return method;
+ }
+
+ public void setMethod(Method method) {
+ this.method = method;
+ }
+
+ public String getDescription() {
+ return description;
+ }
+
+ public void setDescription(String description) {
+ this.description = description;
+ }
+
+ public Boolean getIsDuplicated() {
+ return isDuplicated;
+ }
+
+ public void setIsDuplicated(Boolean isDuplicated) {
+ this.isDuplicated = isDuplicated;
+ }
+
+ public List getMethods() {
+ return methods;
+ }
+
+ public void setMethods(List methods) {
+ this.methods = methods;
+ }
+
+ public String getDateFormat() {
+ return dateFormat;
+ }
+
+ public void setDateFormat(String dateFormat) {
+ this.dateFormat = dateFormat;
+ }
+}
diff --git a/src/main/java/com/wb/excel/api/entity/ExcelImportEntity.java b/src/main/java/com/wb/excel/api/entity/ExcelImportEntity.java
new file mode 100644
index 0000000..996eca0
--- /dev/null
+++ b/src/main/java/com/wb/excel/api/entity/ExcelImportEntity.java
@@ -0,0 +1,37 @@
+package com.wb.excel.api.entity;
+
+/**
+ * ***************************************************************
+ *
+ *
+ * Copyright (c) 2014 –
+ * HeaderDescription:导入的实体信息
+ * ***************************************************************
+ *
+ */
+public class ExcelImportEntity extends ExcelEntity {
+ /**
+ * 校驗參數
+ */
+ private ExcelVerifyEntity verify;
+
+ /**
+ * 校验参数名称
+ */
+// private String verifyFieldName ;
+ public ExcelVerifyEntity getVerify() {
+ return verify;
+ }
+
+ public void setVerify(ExcelVerifyEntity verify) {
+ this.verify = verify;
+ }
+
+// public String getVerifyFieldName() {
+// return verifyFieldName;
+// }
+//
+// public void setVerifyFieldName(String verifyFieldName) {
+// this.verifyFieldName = verifyFieldName;
+// }
+}
diff --git a/src/main/java/com/wb/excel/api/entity/ExcelImportResult.java b/src/main/java/com/wb/excel/api/entity/ExcelImportResult.java
new file mode 100644
index 0000000..d130099
--- /dev/null
+++ b/src/main/java/com/wb/excel/api/entity/ExcelImportResult.java
@@ -0,0 +1,183 @@
+package com.wb.excel.api.entity;
+
+import com.wb.excel.api.style.ErrorCellStyle;
+import org.apache.poi.ss.usermodel.*;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * ***************************************************************
+ *
+ *
+ * Copyright (c) 2014 –
+ * HeaderDescription:导入返回结果
+ * ***************************************************************
+ *
+ */
+public class ExcelImportResult {
+ /**
+ * 结果集
+ */
+ private List list;
+ /**
+ * 是否存在校验失败
+ */
+ private boolean verfiyFail;
+
+ private Map verifyResult;
+
+ /**
+ * 数据源
+ */
+ private Workbook workbook;
+ private CellStyle errorMessageStyle;
+ private ErrorCellStyle errorCellStyle;
+
+ public ExcelImportResult(List list, boolean verfiyFail, Workbook workbook, Map verifyResult) {
+ this.list = list;
+ this.verfiyFail = verfiyFail;
+ this.workbook = workbook;
+ this.verifyResult = verifyResult;
+ this.createErrorCellStyle(workbook);
+ errorCellStyle = new ErrorCellStyle(workbook);
+ }
+
+ public List getList() {
+ return list;
+ }
+
+ public Workbook getWorkbook() {
+ //循环添加错误信息
+ Sheet sheet = workbook.getSheetAt(0);
+ Iterator rows = sheet.rowIterator();
+ //行信息,添加校验结果
+ Row titleRow = rows.next();
+ addValidateTitleInfo(titleRow);
+ //循环,给行添加错误信息
+ Row row = null;
+ while (rows.hasNext() && (row == null || sheet.getLastRowNum() - row.getRowNum() > 0)) {
+ row = rows.next();
+ addValidateInfo(row, verifyResult.get(row.getRowNum()));
+ }
+ return workbook;
+ }
+
+ public byte[] getBytes() throws IOException {
+ Workbook tempworkbook = this.getWorkbook();
+ if (tempworkbook != null) {
+ ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+ tempworkbook.write(outputStream);
+ return outputStream.toByteArray();
+ }
+ return null;
+ }
+
+ /**
+ * 添加校验信息
+ *
+ * @param row
+ */
+ private void addValidateTitleInfo(Row row) {
+ Map temptitle = new HashMap();
+ for (int i = row.getFirstCellNum(), le = row.getLastCellNum(); i < le; i++) {
+ temptitle.put(i, row.getCell(i).getStringCellValue());
+ }
+ for (int i = row.getFirstCellNum(), le = row.getLastCellNum(); i < le; i++) {
+ row.createCell(i + 1).setCellValue(temptitle.get(i));
+ }
+ row.createCell(0).setCellValue("检查状态");
+ row.createCell(row.getLastCellNum()).setCellValue("错误信息");
+ }
+
+ /**
+ * 添加错误行信息
+ *
+ * @param row
+ * @param dataVerifyResult
+ */
+ private void addValidateInfo(Row row, DataVerifyResult dataVerifyResult) {
+ Map temptitle = new HashMap();
+ for (int i = row.getFirstCellNum(), le = row.getLastCellNum(); i < le; i++) {
+ temptitle.put(i, String.valueOf(getCellValue(row.getCell(i))));
+ }
+ for (int i = row.getFirstCellNum(), le = row.getLastCellNum(); i < le; i++) {
+ row.createCell(i + 1).setCellValue(temptitle.get(i));
+ }
+ Boolean result = (dataVerifyResult == null || dataVerifyResult.isSuccess()) ? true : false;
+ Cell statusCell = row.createCell(0);
+ if (!result) {
+ statusCell.setCellStyle(errorCellStyle.getStyle());
+ }
+ statusCell.setCellValue(result ? "通过" : "不通过");
+ Cell errorcell = row.createCell(row.getLastCellNum());
+ errorcell.setCellStyle(errorMessageStyle);
+ errorcell.setCellValue(dataVerifyResult == null ? "" : dataVerifyResult.getMsg());
+ }
+
+ /**
+ * 获取列数据,根据列属性
+ *
+ * @param cell
+ * @return
+ */
+ private Object getCellValue(Cell cell) {
+ Object result = null;
+ if (cell != null) {
+ if (Cell.CELL_TYPE_NUMERIC == cell.getCellType()) {
+ result = cell.getNumericCellValue();
+ } else if (Cell.CELL_TYPE_BOOLEAN == cell.getCellType()) {
+ result = cell.getBooleanCellValue();
+ } else {
+ result = cell.getStringCellValue();
+ }
+ }
+ result = result == null ? "" : result;
+ return result;
+ }
+
+ public boolean isVerfiyFail() {
+ return verfiyFail;
+ }
+
+ public void setList(List list) {
+ this.list = list;
+ }
+
+ public void setVerfiyFail(boolean verfiyFail) {
+ this.verfiyFail = verfiyFail;
+ }
+
+ public void setWorkbook(Workbook workbook) {
+ this.workbook = workbook;
+ }
+
+ public void setVerifyResult(Map verifyResult) {
+ Iterator keys = verifyResult.keySet().iterator();
+ while (keys.hasNext()) {
+ Integer key = keys.next();
+ if (this.verifyResult == null) {
+ this.verifyResult = new HashMap<>();
+ }
+ if (this.verifyResult.containsKey(key)) {
+ DataVerifyResult result = this.verifyResult.get(key);
+ result.setMsg(result.getMsg() + " " + verifyResult.get(key).getMsg());
+ result.setSuccess(verifyResult.get(key).isSuccess());
+ this.verifyResult.put(key, result);
+ } else {
+ this.verifyResult.put(key, verifyResult.get(key));
+ }
+ }
+ }
+
+ private void createErrorCellStyle(Workbook workbook) {
+ errorMessageStyle = workbook.createCellStyle();
+ Font font = workbook.createFont();
+ font.setColor(Font.COLOR_RED);
+ errorMessageStyle.setFont(font);
+ }
+}
diff --git a/src/main/java/com/wb/excel/api/entity/ExcelVerifyEntity.java b/src/main/java/com/wb/excel/api/entity/ExcelVerifyEntity.java
new file mode 100644
index 0000000..a3dd496
--- /dev/null
+++ b/src/main/java/com/wb/excel/api/entity/ExcelVerifyEntity.java
@@ -0,0 +1,141 @@
+package com.wb.excel.api.entity;
+
+/**
+ * Excel 校验对象
+ */
+public class ExcelVerifyEntity {
+
+ /**
+ * 接口校验
+ *
+ * @return
+ */
+ private boolean interHandler;
+
+ /**
+ * 不允许空
+ *
+ * @return
+ */
+ private boolean notNull;
+
+ /**
+ * 是13位移动电话
+ *
+ * @return
+ */
+ private boolean isMobile;
+ /**
+ * 是座机号码
+ *
+ * @return
+ */
+ private boolean isTel;
+
+ /**
+ * 是电子邮件
+ *
+ * @return
+ */
+ private boolean isEmail;
+
+ /**
+ * 最小长度
+ *
+ * @return
+ */
+ private int minLength;
+
+ /**
+ * 最大长度
+ *
+ * @return
+ */
+ private int maxLength;
+
+ /**
+ * 正在表达式
+ *
+ * @return
+ */
+ private String regex;
+ /**
+ * 正在表达式,错误提示信息
+ *
+ * @return
+ */
+ private String regexTip;
+
+ public int getMaxLength() {
+ return maxLength;
+ }
+
+ public int getMinLength() {
+ return minLength;
+ }
+
+ public String getRegex() {
+ return regex;
+ }
+
+ public String getRegexTip() {
+ return regexTip;
+ }
+
+ public boolean isEmail() {
+ return isEmail;
+ }
+
+ public boolean isInterHandler() {
+ return interHandler;
+ }
+
+ public boolean isMobile() {
+ return isMobile;
+ }
+
+ public boolean isNotNull() {
+ return notNull;
+ }
+
+ public boolean isTel() {
+ return isTel;
+ }
+
+ public void setEmail(boolean isEmail) {
+ this.isEmail = isEmail;
+ }
+
+ public void setInterHandler(boolean interHandler) {
+ this.interHandler = interHandler;
+ }
+
+ public void setMaxLength(int maxLength) {
+ this.maxLength = maxLength;
+ }
+
+ public void setMinLength(int minLength) {
+ this.minLength = minLength;
+ }
+
+ public void setMobile(boolean isMobile) {
+ this.isMobile = isMobile;
+ }
+
+ public void setNotNull(boolean notNull) {
+ this.notNull = notNull;
+ }
+
+ public void setRegex(String regex) {
+ this.regex = regex;
+ }
+
+ public void setRegexTip(String regexTip) {
+ this.regexTip = regexTip;
+ }
+
+ public void setTel(boolean isTel) {
+ this.isTel = isTel;
+ }
+
+}
diff --git a/src/main/java/com/wb/excel/api/enumeration/DataType.java b/src/main/java/com/wb/excel/api/enumeration/DataType.java
new file mode 100644
index 0000000..f7b51e6
--- /dev/null
+++ b/src/main/java/com/wb/excel/api/enumeration/DataType.java
@@ -0,0 +1,119 @@
+package com.wb.excel.api.enumeration;
+
+import com.wb.excel.api.annotation.HeaderDescription;
+import com.wb.excel.api.annotation.HeaderName;
+import com.wb.excel.api.datatable.Cell;
+import com.wb.excel.api.util.EnumUtil;
+import com.wb.excel.api.util.StringUtil;
+import com.wb.excel.api.util.ValidationUtil;
+
+/**
+ * 数据类型枚举类。包含了目前DataTable支持验证的11种类型。
+ * DataTable会对指定的类型进行格式上的验证。
+ * Created on 2014/9/19/.
+ *
+ * @author
+ * @version v1.0.0.0
+ */
+public enum DataType {
+ @HeaderName("字符型")
+ @HeaderDescription("普通的字符串类型,例如:abc123.,!@#")
+ STRING,
+ @HeaderName("整数型")
+ @HeaderDescription("整数类型,小数点后的数字会被抹去(不是四舍五入),例如:11,200,4000")
+ NUMBER,
+ @HeaderName("数字类型")
+ @HeaderDescription("可以带小数点的数字类型,例如:1.00,1.01")
+ DECIMAL,
+ @HeaderName("网络地址型")
+ @HeaderDescription("网址,文件地址等。")
+ URL,
+ @HeaderName("邮箱型")
+ @HeaderDescription("邮箱地址,例如:test@xxx.com , test@xxx.com.cn")
+ EMAIL,
+ @HeaderName("手机号码型")
+ @HeaderDescription("手机号码。仅限用于大陆手机号中。如:13300010002")
+ PHONE,
+ @HeaderName("日期型")
+ @HeaderDescription("普通的日期类型,例如:2014-10-01")
+ DATE,
+ @HeaderName("时间日期型(秒)")
+ @HeaderDescription("时间精确到秒的日期类型,例如:2014-10-01 10:30:00")
+ DATETIME,
+ @HeaderName("时间日期型(分钟)")
+ @HeaderDescription("时间精确到分钟的日期类型,例如:2014-10-01 10:30")
+ DATEMINUTE,
+ @HeaderName("是否型")
+ @HeaderDescription("指定是或者否的类型,例如:是,否")
+ BOOLEAN,
+ @HeaderName("大数型")
+ @HeaderDescription("用于较大的数字类型,会忽略小数点以后的内容")
+ LONG;
+
+ /**
+ * 匹配格式.
+ *
+ * @param type 要判断的类型
+ * @param cell 需要判断类型的单元格(可能会有改变值的情况发生,所以需要传入此值)
+ * @param value 已被简单处理过的需要判断的值
+ * @return 匹配结果。true,符合;false,不符合
+ */
+ public static boolean check(DataType type, Cell cell, String value) {
+ boolean typeFlag = true;
+ if (value.length() > 0) {
+ switch (type) {
+ case EMAIL:
+ typeFlag = ValidationUtil.checkEmail(value);
+ break;
+ case PHONE:
+ typeFlag = ValidationUtil.checkPhone(value);
+ break;
+ case URL:
+ typeFlag = ValidationUtil.checkUrl(value);
+ break;
+ case DECIMAL:
+ typeFlag = ValidationUtil.checkDouble(value);
+ break;
+ case NUMBER:
+ typeFlag = ValidationUtil.checkInteger(value);
+ if (typeFlag) {
+ cell.setValue(StringUtil.transferInteger(value));
+ }
+ break;
+ case DATE:
+ typeFlag = ValidationUtil.checkDate(value);
+ if (typeFlag) {
+ cell.setValue(StringUtil.transferDate(value));
+ }
+ break;
+ case DATETIME:
+ typeFlag = ValidationUtil.checkDatetime(value);
+ if (typeFlag) {
+ cell.setValue(StringUtil.transferDatetime(value));
+ }
+ break;
+ case DATEMINUTE:
+ typeFlag = ValidationUtil.checkDatetime(value);
+ if (typeFlag) {
+ cell.setValue(StringUtil.transferDateminute(value));
+ }
+ break;
+ case BOOLEAN:
+ typeFlag = EnumUtil.check(YesNo.class, value);
+ if (typeFlag) {
+ cell.setValue(StringUtil.transferBoolean(value));
+ }
+ break;
+ case LONG:
+ typeFlag = ValidationUtil.checkLong(value);
+ if (typeFlag) {
+ cell.setValue(StringUtil.transferLong(value));
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ return typeFlag;
+ }
+}
diff --git a/src/main/java/com/wb/excel/api/enumeration/Gender.java b/src/main/java/com/wb/excel/api/enumeration/Gender.java
new file mode 100644
index 0000000..c70cab3
--- /dev/null
+++ b/src/main/java/com/wb/excel/api/enumeration/Gender.java
@@ -0,0 +1,18 @@
+package com.wb.excel.api.enumeration;
+
+import com.wb.excel.api.annotation.EnumValue;
+
+/**
+ * Created on 2014/9/26.
+ *
+ * @author
+ * @version 0.1.0
+ */
+public enum Gender {
+ @EnumValue({"男", "male", "m"})
+ M,
+ @EnumValue({"女", "female", "f"})
+ F,
+ @EnumValue({"未知", "其它", "其他", "u"})
+ U
+}
diff --git a/src/main/java/com/wb/excel/api/enumeration/Status.java b/src/main/java/com/wb/excel/api/enumeration/Status.java
new file mode 100644
index 0000000..9623c52
--- /dev/null
+++ b/src/main/java/com/wb/excel/api/enumeration/Status.java
@@ -0,0 +1,50 @@
+package com.wb.excel.api.enumeration;
+
+/**
+ * Created on 2014/9/23.
+ *
+ * @author
+ * @version v1.0.0.0
+ */
+public enum Status {
+ /**
+ * 数据库中已存在
+ */
+ EXIST,
+ /**
+ * 数据库中不存在
+ */
+ NOTEXIST,
+ /**
+ * 不符合的枚举值
+ */
+ ERROR_VALUE,
+ /**
+ * 验证通过
+ */
+ PASS,
+ /**
+ * 不允许重复的列发生了重复
+ */
+ REPEAT,
+ /**
+ * 格式不正确
+ */
+ FORMAT,
+ /**
+ * 长度不符合要求
+ */
+ LENGTH,
+ /**
+ * 不允许为空的列出现了空
+ */
+ EMPTY,
+ /**
+ * 数字类型的值过小
+ */
+ TOO_SMALL,
+ /**
+ * 数字类型的值过大
+ */
+ TOO_BIG
+}
diff --git a/src/main/java/com/wb/excel/api/enumeration/YesNo.java b/src/main/java/com/wb/excel/api/enumeration/YesNo.java
new file mode 100644
index 0000000..97ef556
--- /dev/null
+++ b/src/main/java/com/wb/excel/api/enumeration/YesNo.java
@@ -0,0 +1,18 @@
+package com.wb.excel.api.enumeration;
+
+import com.wb.excel.api.annotation.EnumValue;
+
+/**
+ * 用于判断Boolean型的值。仅供DataTable判断Boolean类型时使用。
+ * 不建议使用。
+ * Created on 2014/9/27.
+ *
+ * @author
+ * @version 0.1.0
+ */
+public enum YesNo {
+ @EnumValue({"是", "yes", "y", "true"})
+ Y,
+ @EnumValue({"否", "no", "n", "false"})
+ N
+}
diff --git a/src/main/java/com/wb/excel/api/exception/ColumnNameNotExistException.java b/src/main/java/com/wb/excel/api/exception/ColumnNameNotExistException.java
new file mode 100644
index 0000000..01c004f
--- /dev/null
+++ b/src/main/java/com/wb/excel/api/exception/ColumnNameNotExistException.java
@@ -0,0 +1,32 @@
+package com.wb.excel.api.exception;
+
+/**
+ * Created on 2014/10/12.
+ *
+ * @author
+ * @version 0.1.0
+ */
+public class ColumnNameNotExistException extends RuntimeException {
+ private static final long serialVersionUID = 234122996006212387L;
+
+ /**
+ * Constructs a new runtime exception with {@code null} as its
+ * detail message. The cause is not initialized, and may subsequently be
+ * initialized by a call to {@link #initCause}.
+ */
+ public ColumnNameNotExistException() {
+ super();
+ }
+
+ /**
+ * Constructs a new runtime exception with the specified detail message.
+ * The cause is not initialized, and may subsequently be initialized by a
+ * call to {@link #initCause}.
+ *
+ * @param message the detail message. The detail message is saved for
+ * later retrieval by the {@link #getMessage()} method.
+ */
+ public ColumnNameNotExistException(String message) {
+ super(message);
+ }
+}
diff --git a/src/main/java/com/wb/excel/api/exception/Error.java b/src/main/java/com/wb/excel/api/exception/Error.java
new file mode 100644
index 0000000..ee1dd24
--- /dev/null
+++ b/src/main/java/com/wb/excel/api/exception/Error.java
@@ -0,0 +1,52 @@
+package com.wb.excel.api.exception;
+
+import java.io.Serializable;
+
+public class Error implements Serializable {
+
+ private static final long serialVersionUID = 3L;
+
+ private String code;
+
+ private ErrorType type;
+
+ private String message;
+
+ public Error() {
+ }
+
+ public Error(String code, String message) {
+ this.code = code;
+ this.message = message;
+ }
+
+ public Error(ErrorType type, String message) {
+ this.type = type;
+ this.code = type.toString();
+ this.message = message;
+ }
+
+ public String getCode() {
+ return code;
+ }
+
+ public void setCode(String code) {
+ this.code = code;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+ public void setMessage(String message) {
+ this.message = message;
+ }
+
+ public ErrorType getType() {
+ return type;
+ }
+
+ public void setType(ErrorType type) {
+ this.type = type;
+ }
+}
diff --git a/src/main/java/com/wb/excel/api/exception/ErrorType.java b/src/main/java/com/wb/excel/api/exception/ErrorType.java
new file mode 100644
index 0000000..ca0cad6
--- /dev/null
+++ b/src/main/java/com/wb/excel/api/exception/ErrorType.java
@@ -0,0 +1,38 @@
+package com.wb.excel.api.exception;
+
+/**
+ * Created on 2014/10/15.
+ *
+ * @author
+ * @version 0.1.0
+ */
+public class ErrorType {
+ /**
+ * 唯一性错误,出现了不允许重复的内容
+ */
+ public static String UNIQUENESS_ERROR = "UNIQUENESS_ERROR";
+ /**
+ * 期待值为空 找不到想要的对象
+ */
+ public static String EXPECTATION_NULL = "EXPECTATION_NULL";
+ /**
+ * 业务错误 不符合业务逻辑的情况发生
+ */
+ public static String BUSINESS_ERROR = "BUSINESS_ERROR";
+ /**
+ * 系统错误 JDBC的错误等
+ */
+ public static String SYSTEM_ERROR = "SYSTEM_ERROR";
+ /**
+ * 非法的参数 无效,格式不对、非法值、越界等
+ */
+ public static String INVALID_PARAMETER = "INVALID_PARAMETER";
+ /**
+ * 其它未归类错误
+ */
+ public static String OTHER = "OTHER";
+ /**
+ * 异常信息Dump
+ */
+ public static String STACK_DUMP = "STACK_DUMP";
+}
diff --git a/src/main/java/com/wb/excel/api/exception/ExistedColumnNameException.java b/src/main/java/com/wb/excel/api/exception/ExistedColumnNameException.java
new file mode 100644
index 0000000..1c62a8c
--- /dev/null
+++ b/src/main/java/com/wb/excel/api/exception/ExistedColumnNameException.java
@@ -0,0 +1,32 @@
+package com.wb.excel.api.exception;
+
+/**
+ * Created on 2014/10/12.
+ *
+ * @author
+ * @version 0.1.0
+ */
+public class ExistedColumnNameException extends RuntimeException {
+ private static final long serialVersionUID = 234122996006212387L;
+
+ /**
+ * Constructs a new runtime exception with {@code null} as its
+ * detail message. The cause is not initialized, and may subsequently be
+ * initialized by a call to {@link #initCause}.
+ */
+ public ExistedColumnNameException() {
+ super();
+ }
+
+ /**
+ * Constructs a new runtime exception with the specified detail message.
+ * The cause is not initialized, and may subsequently be initialized by a
+ * call to {@link #initCause}.
+ *
+ * @param message the detail message. The detail message is saved for
+ * later retrieval by the {@link #getMessage()} method.
+ */
+ public ExistedColumnNameException(String message) {
+ super(message);
+ }
+}
diff --git a/src/main/java/com/wb/excel/api/exception/IllegalParameterException.java b/src/main/java/com/wb/excel/api/exception/IllegalParameterException.java
new file mode 100644
index 0000000..e9907b2
--- /dev/null
+++ b/src/main/java/com/wb/excel/api/exception/IllegalParameterException.java
@@ -0,0 +1,32 @@
+package com.wb.excel.api.exception;
+
+/**
+ * Created on 2014/10/12.
+ *
+ * @author
+ * @version 0.1.0
+ */
+public class IllegalParameterException extends RuntimeException {
+ private static final long serialVersionUID = 234122996006212387L;
+
+ /**
+ * Constructs a new runtime exception with {@code null} as its
+ * detail message. The cause is not initialized, and may subsequently be
+ * initialized by a call to {@link #initCause}.
+ */
+ public IllegalParameterException() {
+ super();
+ }
+
+ /**
+ * Constructs a new runtime exception with the specified detail message.
+ * The cause is not initialized, and may subsequently be initialized by a
+ * call to {@link #initCause}.
+ *
+ * @param message the detail message. The detail message is saved for
+ * later retrieval by the {@link #getMessage()} method.
+ */
+ public IllegalParameterException(String message) {
+ super(message);
+ }
+}
diff --git a/src/main/java/com/wb/excel/api/exception/TemplateNotMatchException.java b/src/main/java/com/wb/excel/api/exception/TemplateNotMatchException.java
new file mode 100644
index 0000000..969c4ee
--- /dev/null
+++ b/src/main/java/com/wb/excel/api/exception/TemplateNotMatchException.java
@@ -0,0 +1,29 @@
+package com.wb.excel.api.exception;
+
+/**
+ * Created on 2014/10/12.
+ *
+ * @author
+ * @version 0.1.0
+ */
+public class TemplateNotMatchException extends Exception {
+ /**
+ * Constructs a new exception with {@code null} as its detail message.
+ * The cause is not initialized, and may subsequently be initialized by a
+ * call to {@link #initCause}.
+ */
+ public TemplateNotMatchException() {
+ }
+
+ /**
+ * Constructs a new exception with the specified detail message. The
+ * cause is not initialized, and may subsequently be initialized by
+ * a call to {@link #initCause}.
+ *
+ * @param message the detail message. The detail message is saved for
+ * later retrieval by the {@link #getMessage()} method.
+ */
+ public TemplateNotMatchException(String message) {
+ super(message);
+ }
+}
diff --git a/src/main/java/com/wb/excel/api/interfaces/EnumSupport.java b/src/main/java/com/wb/excel/api/interfaces/EnumSupport.java
new file mode 100644
index 0000000..97421b0
--- /dev/null
+++ b/src/main/java/com/wb/excel/api/interfaces/EnumSupport.java
@@ -0,0 +1,38 @@
+package com.wb.excel.api.interfaces;
+
+/**
+ * 自定义枚举的基础类。
+ * Created on 2014/9/27.
+ *
+ * @author
+ * @version 0.1.0
+ */
+@Deprecated
+public interface EnumSupport {
+ /**
+ * 每个实现类自身都要实现检查方法。
+ * 用于判断输入的值是否属于枚举内容。
+ *
+ * @param str 要判断的值
+ * @return true || false / 符合||不符合
+ */
+ public Boolean check(String str);
+
+ /**
+ * 通过Value来获取Key。
+ * 例如性别: 输入男、Male、male都返回F(F为数据库中存储的值)
+ *
+ * @param value
+ * @return Key。最终存储至数据库中的值。
+ */
+ public Object getKey(String value);
+
+ /**
+ * 通过Key来获取Value
+ * 例如性别:输入F,返回男
+ *
+ * @param key
+ * @return Value。最终要展现给用户看的值。
+ */
+ public String getValue(Object key);
+}
diff --git a/src/main/java/com/wb/excel/api/interfaces/IExcelVerifyHandler.java b/src/main/java/com/wb/excel/api/interfaces/IExcelVerifyHandler.java
new file mode 100644
index 0000000..2cbf4ad
--- /dev/null
+++ b/src/main/java/com/wb/excel/api/interfaces/IExcelVerifyHandler.java
@@ -0,0 +1,34 @@
+package com.wb.excel.api.interfaces;
+
+import com.wb.excel.api.entity.DataVerifyResult;
+
+/**
+ * 导入校验接口
+ */
+public interface IExcelVerifyHandler {
+
+// /**
+// * 获取需要处理的字段,导入和导出统一处理了, 减少书写的字段
+// *
+// * @return
+// */
+// public String[] getNeedVerifyFields();
+//
+// /**
+// * 获取需要处理的字段,导入和导出统一处理了, 减少书写的字段
+// *
+// * @return
+// */
+// public void setNeedVerifyFields(String[] arr);
+
+ /**
+ * 数据校验
+ *
+ * @param obj 当前对象
+ * @param name 当前字段名称
+ * @param value 当前值
+ * @return
+ */
+ public DataVerifyResult verifyHandler(Object obj, String name, Object value);
+
+}
diff --git a/src/main/java/com/wb/excel/api/style/BaseCellStyle.java b/src/main/java/com/wb/excel/api/style/BaseCellStyle.java
new file mode 100644
index 0000000..b76f82b
--- /dev/null
+++ b/src/main/java/com/wb/excel/api/style/BaseCellStyle.java
@@ -0,0 +1,29 @@
+package com.wb.excel.api.style;
+
+import org.apache.poi.ss.usermodel.CellStyle;
+import org.apache.poi.ss.usermodel.Workbook;
+
+/**
+ * Created on 2015/1/29.
+ *
+ * @author
+ * @since 2.0.0
+ */
+public class BaseCellStyle {
+ /**
+ * 样式
+ */
+ protected CellStyle style;
+
+ public BaseCellStyle(Workbook workbook) {
+ style = workbook.createCellStyle();
+ }
+
+ public CellStyle getStyle() {
+ return style;
+ }
+
+ public void setStyle(CellStyle style) {
+ this.style = style;
+ }
+}
diff --git a/src/main/java/com/wb/excel/api/style/BaseFont.java b/src/main/java/com/wb/excel/api/style/BaseFont.java
new file mode 100644
index 0000000..430c4dc
--- /dev/null
+++ b/src/main/java/com/wb/excel/api/style/BaseFont.java
@@ -0,0 +1,29 @@
+package com.wb.excel.api.style;
+
+import org.apache.poi.ss.usermodel.Font;
+import org.apache.poi.ss.usermodel.Workbook;
+
+/**
+ * Created on 2015/1/29.
+ *
+ * @author
+ * @since 2.0.0
+ */
+public class BaseFont {
+ /**
+ * 字体
+ */
+ protected Font font;
+
+ public BaseFont(Workbook workbook) {
+ font = workbook.createFont();
+ }
+
+ public Font getFont() {
+ return font;
+ }
+
+ public void setFont(Font font) {
+ this.font = font;
+ }
+}
diff --git a/src/main/java/com/wb/excel/api/style/CheckFailureCellStyle.java b/src/main/java/com/wb/excel/api/style/CheckFailureCellStyle.java
new file mode 100644
index 0000000..b84b512
--- /dev/null
+++ b/src/main/java/com/wb/excel/api/style/CheckFailureCellStyle.java
@@ -0,0 +1,44 @@
+package com.wb.excel.api.style;
+
+import org.apache.poi.hssf.util.HSSFColor;
+import org.apache.poi.ss.usermodel.CellStyle;
+import org.apache.poi.ss.usermodel.Font;
+import org.apache.poi.ss.usermodel.IndexedColors;
+import org.apache.poi.ss.usermodel.Workbook;
+
+/**
+ * Created on 2015/1/29.
+ *
+ * @author
+ * @since 2.0.0
+ */
+public class CheckFailureCellStyle extends BaseCellStyle {
+ public CheckFailureCellStyle(Workbook workbook) {
+ super(workbook);
+ Font font = workbook.createFont(); // 单元格的字体
+ font.setColor(HSSFColor.WHITE.index); // 字体颜色-白色
+ CellStyle style = workbook.createCellStyle(); // 单元格的样式
+ style.setFillForegroundColor(HSSFColor.RED.index); // 背景颜色-红色
+ style.setFillPattern(CellStyle.SOLID_FOREGROUND); // 设置单元格填充样式
+ style.setAlignment(CellStyle.ALIGN_CENTER); // 居中
+ style.setFont(font);
+ style.setVerticalAlignment(CellStyle.VERTICAL_CENTER); //上下居中
+
+ //下边框
+ style.setBorderBottom(CellStyle.SOLID_FOREGROUND);
+ //下边框颜色
+ style.setBottomBorderColor(IndexedColors.BLACK.getIndex());
+ //左边框
+ style.setBorderLeft(CellStyle.SOLID_FOREGROUND);
+ //左边框颜色
+ style.setLeftBorderColor(IndexedColors.BLACK.getIndex());
+ //右边框
+ style.setBorderRight(CellStyle.SOLID_FOREGROUND);
+ //右边框颜色
+ style.setRightBorderColor(IndexedColors.BLACK.getIndex());
+ //上边框
+ style.setBorderTop(CellStyle.SOLID_FOREGROUND);
+ //上边框颜色
+ style.setTopBorderColor(IndexedColors.BLACK.getIndex());
+ }
+}
diff --git a/src/main/java/com/wb/excel/api/style/CheckMessageCellStyle.java b/src/main/java/com/wb/excel/api/style/CheckMessageCellStyle.java
new file mode 100644
index 0000000..3759662
--- /dev/null
+++ b/src/main/java/com/wb/excel/api/style/CheckMessageCellStyle.java
@@ -0,0 +1,24 @@
+package com.wb.excel.api.style;
+
+import org.apache.poi.hssf.util.HSSFColor;
+import org.apache.poi.ss.usermodel.CellStyle;
+import org.apache.poi.ss.usermodel.Font;
+import org.apache.poi.ss.usermodel.Workbook;
+
+/**
+ * Created on 2015/1/29.
+ *
+ * @author
+ * @since 2.0.0
+ */
+public class CheckMessageCellStyle extends BaseCellStyle {
+ public CheckMessageCellStyle(Workbook workbook) {
+ super(workbook);
+ Font font = workbook.createFont(); // 单元格的字体
+ font.setColor(HSSFColor.BLACK.index); // 字体颜色-黑色
+ CellStyle style = workbook.createCellStyle(); // 单元格的样式
+ style.setFillPattern(CellStyle.NO_FILL); // 设置单元格无填充
+ style.setFont(font);
+ style.setVerticalAlignment(CellStyle.VERTICAL_CENTER); //上下居中
+ }
+}
diff --git a/src/main/java/com/wb/excel/api/style/CheckSuccessCellStyle.java b/src/main/java/com/wb/excel/api/style/CheckSuccessCellStyle.java
new file mode 100644
index 0000000..a6a2e02
--- /dev/null
+++ b/src/main/java/com/wb/excel/api/style/CheckSuccessCellStyle.java
@@ -0,0 +1,40 @@
+package com.wb.excel.api.style;
+
+import org.apache.poi.hssf.util.HSSFColor;
+import org.apache.poi.ss.usermodel.CellStyle;
+import org.apache.poi.ss.usermodel.IndexedColors;
+import org.apache.poi.ss.usermodel.Workbook;
+
+/**
+ * Created on 2015/1/29.
+ *
+ * @author
+ * @since 2.0.0
+ */
+public class CheckSuccessCellStyle extends BaseCellStyle {
+ public CheckSuccessCellStyle(Workbook workbook) {
+ super(workbook);
+ style.setFillForegroundColor(HSSFColor.LIME.index); // 背景颜色-绿色
+ style.setFillPattern(CellStyle.SOLID_FOREGROUND); // 设置单元格填充样式
+ style.setAlignment(CellStyle.ALIGN_CENTER); // 居中
+ //style.setFont(font);
+ style.setVerticalAlignment(CellStyle.VERTICAL_CENTER); //上下居中
+
+ //下边框
+ style.setBorderBottom(CellStyle.SOLID_FOREGROUND);
+ //下边框颜色
+ style.setBottomBorderColor(IndexedColors.BLACK.getIndex());
+ //左边框
+ style.setBorderLeft(CellStyle.SOLID_FOREGROUND);
+ //左边框颜色
+ style.setLeftBorderColor(IndexedColors.BLACK.getIndex());
+ //右边框
+ style.setBorderRight(CellStyle.SOLID_FOREGROUND);
+ //右边框颜色
+ style.setRightBorderColor(IndexedColors.BLACK.getIndex());
+ //上边框
+ style.setBorderTop(CellStyle.SOLID_FOREGROUND);
+ //上边框颜色
+ style.setTopBorderColor(IndexedColors.BLACK.getIndex());
+ }
+}
diff --git a/src/main/java/com/wb/excel/api/style/ErrorCellStyle.java b/src/main/java/com/wb/excel/api/style/ErrorCellStyle.java
new file mode 100644
index 0000000..9eea4b1
--- /dev/null
+++ b/src/main/java/com/wb/excel/api/style/ErrorCellStyle.java
@@ -0,0 +1,39 @@
+package com.wb.excel.api.style;
+
+import org.apache.poi.hssf.util.HSSFColor;
+import org.apache.poi.ss.usermodel.CellStyle;
+import org.apache.poi.ss.usermodel.IndexedColors;
+import org.apache.poi.ss.usermodel.Workbook;
+
+/**
+ * Created on 2015/1/29.
+ *
+ * @author
+ * @since 2.0.0
+ */
+public class ErrorCellStyle extends BaseCellStyle {
+ public ErrorCellStyle(Workbook workbook) {
+ super(workbook);
+ style.setFillForegroundColor(HSSFColor.ORANGE.index); //背景颜色-紫罗兰色
+ style.setFillPattern(CellStyle.SOLID_FOREGROUND); //设置单元格填充样式
+ //style.setFont(font); //设置单元格字体
+ style.setVerticalAlignment(CellStyle.VERTICAL_CENTER);//上下居中
+
+ //下边框
+ style.setBorderBottom(CellStyle.SOLID_FOREGROUND);
+ //下边框颜色
+ style.setBottomBorderColor(IndexedColors.BLACK.getIndex());
+ //左边框
+ style.setBorderLeft(CellStyle.SOLID_FOREGROUND);
+ //左边框颜色
+ style.setLeftBorderColor(IndexedColors.BLACK.getIndex());
+ //右边框
+ style.setBorderRight(CellStyle.SOLID_FOREGROUND);
+ //右边框颜色
+ style.setRightBorderColor(IndexedColors.BLACK.getIndex());
+ //上边框
+ style.setBorderTop(CellStyle.SOLID_FOREGROUND);
+ //上边框颜色
+ style.setTopBorderColor(IndexedColors.BLACK.getIndex());
+ }
+}
diff --git a/src/main/java/com/wb/excel/api/style/ErrorNumberCellStyle.java b/src/main/java/com/wb/excel/api/style/ErrorNumberCellStyle.java
new file mode 100644
index 0000000..3d5ebb5
--- /dev/null
+++ b/src/main/java/com/wb/excel/api/style/ErrorNumberCellStyle.java
@@ -0,0 +1,17 @@
+package com.wb.excel.api.style;
+
+import org.apache.poi.ss.usermodel.CellStyle;
+import org.apache.poi.ss.usermodel.Workbook;
+
+/**
+ * Created on 2015/1/29.
+ *
+ * @author
+ * @since 2.0.0
+ */
+public class ErrorNumberCellStyle extends ErrorCellStyle {
+ public ErrorNumberCellStyle(Workbook workbook) {
+ super(workbook);
+ style.setAlignment(CellStyle.ALIGN_RIGHT);
+ }
+}
diff --git a/src/main/java/com/wb/excel/api/style/HeadCellStyle.java b/src/main/java/com/wb/excel/api/style/HeadCellStyle.java
new file mode 100644
index 0000000..2e668c9
--- /dev/null
+++ b/src/main/java/com/wb/excel/api/style/HeadCellStyle.java
@@ -0,0 +1,39 @@
+package com.wb.excel.api.style;
+
+import org.apache.poi.hssf.util.HSSFColor;
+import org.apache.poi.ss.usermodel.CellStyle;
+import org.apache.poi.ss.usermodel.IndexedColors;
+import org.apache.poi.ss.usermodel.Workbook;
+
+/**
+ * Created on 2015/1/29.
+ *
+ * @author
+ * @since 2.0.0
+ */
+public class HeadCellStyle extends BaseCellStyle {
+ public HeadCellStyle(Workbook workbook) {
+ super(workbook);
+ style.setFillForegroundColor(HSSFColor.GREY_25_PERCENT.index); //背景颜色-灰色
+ style.setFillPattern(CellStyle.SOLID_FOREGROUND); // 设置单元格填充样式
+ style.setAlignment(CellStyle.ALIGN_CENTER); // 居中
+ style.setVerticalAlignment(CellStyle.VERTICAL_CENTER);//上下居中
+
+ //下边框
+ style.setBorderBottom(CellStyle.SOLID_FOREGROUND);
+ //下边框颜色
+ style.setBottomBorderColor(IndexedColors.BLACK.getIndex());
+ //左边框
+ style.setBorderLeft(CellStyle.SOLID_FOREGROUND);
+ //左边框颜色
+ style.setLeftBorderColor(IndexedColors.BLACK.getIndex());
+ //右边框
+ style.setBorderRight(CellStyle.SOLID_FOREGROUND);
+ //右边框颜色
+ style.setRightBorderColor(IndexedColors.BLACK.getIndex());
+ //上边框
+ style.setBorderTop(CellStyle.SOLID_FOREGROUND);
+ //上边框颜色
+ style.setTopBorderColor(IndexedColors.BLACK.getIndex());
+ }
+}
diff --git a/src/main/java/com/wb/excel/api/style/NormalCellStyle.java b/src/main/java/com/wb/excel/api/style/NormalCellStyle.java
new file mode 100644
index 0000000..27e62c3
--- /dev/null
+++ b/src/main/java/com/wb/excel/api/style/NormalCellStyle.java
@@ -0,0 +1,28 @@
+package com.wb.excel.api.style;
+
+import org.apache.poi.ss.usermodel.CellStyle;
+import org.apache.poi.ss.usermodel.IndexedColors;
+import org.apache.poi.ss.usermodel.Workbook;
+
+/**
+ * Created on 2015/1/29.
+ *
+ * @author
+ * @since 2.0.0
+ */
+public class NormalCellStyle extends BaseCellStyle {
+ public NormalCellStyle(Workbook workbook) {
+ super(workbook);
+ style.setFillPattern(CellStyle.NO_FILL); //单元格不填充
+ //style.setFont(font); //设置单元格字体
+ style.setVerticalAlignment(CellStyle.VERTICAL_CENTER); //上下居中
+ style.setBorderBottom(CellStyle.SOLID_FOREGROUND); //下边框
+ style.setBottomBorderColor(IndexedColors.BLACK.getIndex()); //下边框颜色
+ style.setBorderLeft(CellStyle.SOLID_FOREGROUND); //左边框
+ style.setLeftBorderColor(IndexedColors.BLACK.getIndex()); //左边框颜色
+ style.setBorderRight(CellStyle.SOLID_FOREGROUND); //右边框
+ style.setRightBorderColor(IndexedColors.BLACK.getIndex()); //右边框颜色
+ style.setBorderTop(CellStyle.SOLID_FOREGROUND); //上边框
+ style.setTopBorderColor(IndexedColors.BLACK.getIndex()); //上边框颜色
+ }
+}
diff --git a/src/main/java/com/wb/excel/api/style/NormalFont.java b/src/main/java/com/wb/excel/api/style/NormalFont.java
new file mode 100644
index 0000000..f6cbb71
--- /dev/null
+++ b/src/main/java/com/wb/excel/api/style/NormalFont.java
@@ -0,0 +1,18 @@
+package com.wb.excel.api.style;
+
+import org.apache.poi.hssf.util.HSSFColor;
+import org.apache.poi.ss.usermodel.Workbook;
+
+/**
+ * 普通字体.颜色黑
+ * Created on 2015/1/29.
+ *
+ * @author
+ * @since 2.0.0
+ */
+public class NormalFont extends BaseFont {
+ public NormalFont(Workbook workbook) {
+ super(workbook);
+ font.setColor(HSSFColor.BLACK.index); //字体颜色-黑色
+ }
+}
diff --git a/src/main/java/com/wb/excel/api/style/NormalNumberCellStyle.java b/src/main/java/com/wb/excel/api/style/NormalNumberCellStyle.java
new file mode 100644
index 0000000..b2f6513
--- /dev/null
+++ b/src/main/java/com/wb/excel/api/style/NormalNumberCellStyle.java
@@ -0,0 +1,17 @@
+package com.wb.excel.api.style;
+
+import org.apache.poi.ss.usermodel.CellStyle;
+import org.apache.poi.ss.usermodel.Workbook;
+
+/**
+ * Created on 2015/1/29.
+ *
+ * @author
+ * @since 2.0.0
+ */
+public class NormalNumberCellStyle extends NormalCellStyle {
+ public NormalNumberCellStyle(Workbook workbook) {
+ super(workbook);
+ style.setAlignment(CellStyle.ALIGN_RIGHT);
+ }
+}
diff --git a/src/main/java/com/wb/excel/api/style/RedFont.java b/src/main/java/com/wb/excel/api/style/RedFont.java
new file mode 100644
index 0000000..2d2fdc6
--- /dev/null
+++ b/src/main/java/com/wb/excel/api/style/RedFont.java
@@ -0,0 +1,18 @@
+package com.wb.excel.api.style;
+
+import org.apache.poi.hssf.util.HSSFColor;
+import org.apache.poi.ss.usermodel.Workbook;
+
+/**
+ * 普通字体.颜色黑
+ * Created on 2015/1/29.
+ *
+ * @author
+ * @since 2.0.0
+ */
+public class RedFont extends BaseFont {
+ public RedFont(Workbook workbook) {
+ super(workbook);
+ font.setColor(HSSFColor.RED.index); //字体颜色-黑色
+ }
+}
diff --git a/src/main/java/com/wb/excel/api/util/BaseVerifyUtil.java b/src/main/java/com/wb/excel/api/util/BaseVerifyUtil.java
new file mode 100644
index 0000000..29685a3
--- /dev/null
+++ b/src/main/java/com/wb/excel/api/util/BaseVerifyUtil.java
@@ -0,0 +1,135 @@
+package com.wb.excel.api.util;
+
+
+import com.wb.excel.api.entity.DataVerifyResult;
+
+import java.util.regex.Pattern;
+
+/**
+ * ***************************************************************
+ *
+ *
+ * Copyright (c) 2014 –
+ * HeaderDescription:数据基础校验
+ * ***************************************************************
+ *
+ */
+public class BaseVerifyUtil {
+ private static String NOT_NULL = "不允许为空";
+ private static String IS_MOBILE = "不是手机号";
+ private static String IS_TEL = "不是电话号码";
+ private static String IS_EMAIL = "不是邮箱地址";
+ private static String MIN_LENGHT = "小于规定长度";
+ private static String MAX_LENGHT = "超过规定长度";
+
+ private static Pattern mobilePattern = Pattern.compile("^[1][3,4,5,8,7][0-9]{9}$");
+
+ private static Pattern telPattern = Pattern.compile("^([0][1-9]{2,3}-)?[0-9]{5,10}$");
+
+ private static Pattern emailPattern = Pattern
+ .compile("^([a-zA-Z0-9]+[_|\\_|\\.]?)*[a-zA-Z0-9]+@([a-zA-Z0-9]+[_|\\_|\\.]?)*[a-zA-Z0-9]+\\.[a-zA-Z]{2,3}$");
+
+
+ /**
+ * email校验
+ *
+ * @param name
+ * @param val
+ * @return
+ */
+ public static DataVerifyResult isEmail(String name, Object val) {
+ if (!emailPattern.matcher(String.valueOf(val)).matches()) {
+ return new DataVerifyResult(false, name + IS_EMAIL);
+ }
+ return new DataVerifyResult(true);
+ }
+
+ /**
+ * 手机校验
+ *
+ * @param name
+ * @param val
+ * @return
+ */
+ public static DataVerifyResult isMobile(String name, Object val) {
+ if (!mobilePattern.matcher(String.valueOf(val)).matches()) {
+ return new DataVerifyResult(false, name + IS_MOBILE);
+ }
+ return new DataVerifyResult(true);
+ }
+
+ /**
+ * 电话校验
+ *
+ * @param name
+ * @param val
+ * @return
+ */
+ public static DataVerifyResult isTel(String name, Object val) {
+ if (!telPattern.matcher(String.valueOf(val)).matches()) {
+ return new DataVerifyResult(false, name + IS_TEL);
+ }
+ return new DataVerifyResult(true);
+ }
+
+ /**
+ * 最大长度校验
+ *
+ * @param name
+ * @param val
+ * @return
+ */
+ public static DataVerifyResult maxLength(String name, Object val, int maxLength) {
+ if (notNull(name, val).isSuccess() && String.valueOf(val).length() > maxLength) {
+ return new DataVerifyResult(false, name + MAX_LENGHT);
+ }
+ return new DataVerifyResult(true);
+ }
+
+ /**
+ * 最小长度校验
+ *
+ * @param name
+ * @param val
+ * @param minLength
+ * @return
+ */
+ public static DataVerifyResult minLength(String name, Object val, int minLength) {
+ if (notNull(name, val).isSuccess() && String.valueOf(val).length() < minLength) {
+ return new DataVerifyResult(false, name + MIN_LENGHT);
+ }
+ return new DataVerifyResult(true);
+ }
+
+ /**
+ * 非空校验
+ *
+ * @param name
+ * @param val
+ * @return
+ */
+ public static DataVerifyResult notNull(String name, Object val) {
+ if (val == null || val.toString().equals("")) {
+ return new DataVerifyResult(false, name + NOT_NULL);
+ }
+ return new DataVerifyResult(true);
+ }
+
+ /**
+ * 正则表达式校验
+ *
+ * @param name
+ * @param val
+ * @param regex
+ * @param regexTip
+ * @return
+ */
+ public static DataVerifyResult regex(String name, Object val, String regex,
+ String regexTip) {
+ Pattern pattern = Pattern.compile(regex);
+ if (!pattern.matcher(String.valueOf(val)).matches()) {
+ return new DataVerifyResult(false, name + regexTip);
+ }
+ return new DataVerifyResult(true);
+ }
+}
diff --git a/src/main/java/com/wb/excel/api/util/ClassUtil.java b/src/main/java/com/wb/excel/api/util/ClassUtil.java
new file mode 100644
index 0000000..0db27a9
--- /dev/null
+++ b/src/main/java/com/wb/excel/api/util/ClassUtil.java
@@ -0,0 +1,195 @@
+package com.wb.excel.api.util;
+
+
+import com.wb.excel.api.annotation.ExcelCollection;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.util.*;
+
+/**
+ * Created on 2015/5/28.
+ *
+ * @author 金洋
+ * @version 2.1.0
+ */
+public class ClassUtil {
+
+ public static Field[] getFields(Class clazz, boolean parentFirst) {
+ List returnList = new ArrayList<>();
+ Set nameSet = new HashSet<>();
+
+ Field[] fields = clazz.getDeclaredFields();
+
+ for (Field field : fields) {
+ returnList.add(field);
+ nameSet.add(field.getName());
+ }
+ List parentList = getParentFields(clazz.getSuperclass(), nameSet, parentFirst);
+ if (parentFirst) {
+ parentList.addAll(returnList);
+ returnList = parentList;
+ } else {
+ returnList.addAll(parentList);
+ }
+
+ fields = new Field[returnList.size()];
+
+ int index = 0;
+ for (Field field : returnList) {
+ fields[index++] = field;
+ }
+ return fields;
+
+ }
+
+ /**
+ * 获取class的 包括父类的
+ *
+ * @param clazz
+ * @return
+ */
+ public static Field[] getClassFields(Class> clazz) {
+ List list = new ArrayList();
+ Field[] fields;
+ do {
+ fields = clazz.getDeclaredFields();
+ for (int i = 0; i < fields.length; i++) {
+ list.add(fields[i]);
+ }
+ clazz = clazz.getSuperclass();
+ } while (clazz != Object.class && clazz != null);
+ return list.toArray(fields);
+ }
+
+ /**
+ * 判断是不是集合的实现类
+ *
+ * @param clazz
+ * @return
+ */
+ public static boolean isCollection(Class> clazz) {
+ return Collection.class.isAssignableFrom(clazz);
+ }
+
+ /**
+ * 获取GET方法
+ *
+ * @param name
+ * @param pojoClass
+ * @return
+ * @throws Exception
+ */
+ public static Method getMethod(String name, Class> pojoClass) throws Exception {
+ StringBuffer getMethodName = new StringBuffer("get");
+ getMethodName.append(name.substring(0, 1).toUpperCase());
+ getMethodName.append(name.substring(1));
+ Method method = null;
+ try {
+ method = pojoClass.getMethod(getMethodName.toString(), new Class[]{});
+ } catch (Exception e) {
+ method = pojoClass.getMethod(
+ getMethodName.toString().replace("get", "is"),
+ new Class[]{});
+ }
+ return method;
+ }
+
+ /**
+ * 获取SET方法
+ *
+ * @param name
+ * @param pojoClass
+ * @param type
+ * @return
+ * @throws Exception
+ */
+ public static Method getMethod(String name, Class> pojoClass, Class> type) throws Exception {
+ StringBuffer getMethodName = new StringBuffer("set");
+ getMethodName.append(name.substring(0, 1).toUpperCase());
+ getMethodName.append(name.substring(1));
+ return pojoClass.getMethod(getMethodName.toString(), new Class[]{type});
+ }
+
+ /**
+ * 是不是java基础类
+ *
+ * @param field
+ * @return
+ */
+ public static boolean isJavaClass(Field field) {
+ Class> fieldType = field.getType();
+ boolean isBaseClass = false;
+ if (fieldType.isArray()) {
+ isBaseClass = false;
+ } else if (fieldType.isPrimitive() || fieldType.getPackage() == null
+ || fieldType.getPackage().getName().equals("java.lang")
+ || fieldType.getPackage().getName().equals("java.math")
+ || fieldType.getPackage().getName().equals("java.sql")
+ || fieldType.getPackage().getName().equals("java.util")) {
+ isBaseClass = true;
+ }
+ return isBaseClass;
+ }
+
+ /**
+ * 通过指定的类型获取所有的成员变量
+ *
+ * @param clazz
+ * @return
+ */
+ public static Field[] getFields(Class clazz) {
+ return getFields(clazz, false);
+ }
+
+ private static List getParentFields(Class parentClazz, Set nameSet, boolean parentFirst) {
+ List fieldList = new ArrayList<>();
+
+ if (parentClazz != null) {
+ Field[] parentList = parentClazz.getDeclaredFields();
+ int index = 0;
+ for (Field field : parentList) {
+ int beginSize = nameSet.size();
+ nameSet.add(field.getName());
+ int endSize = nameSet.size();
+
+ if (endSize > beginSize) {
+ if (parentFirst) {
+ fieldList.add(index++, field);
+ } else {
+ fieldList.add(field);
+ }
+ }
+ }
+ fieldList.addAll(getParentFields(parentClazz.getSuperclass(), nameSet, parentFirst));
+ }
+ return fieldList;
+ }
+
+ public static Object createObject(Class> clazz) {
+ Object obj = null;
+ Method setMethod;
+ try {
+ if (clazz.equals(Map.class)) {
+ return new HashMap();
+ }
+ obj = clazz.newInstance();
+ Field[] fields = getClassFields(clazz);
+ for (Field field : fields) {
+ if (isCollection(field.getType())) {
+ ExcelCollection collection = field.getAnnotation(ExcelCollection.class);
+ setMethod = getMethod(field.getName(), clazz, field.getType());
+ setMethod.invoke(obj, collection.type().newInstance());
+ } else if (!isJavaClass(field)) {
+ setMethod = getMethod(field.getName(), clazz, field.getType());
+ setMethod.invoke(obj, createObject(field.getType()));
+ }
+ }
+
+ } catch (Exception e) {
+ e.printStackTrace();
+ throw new RuntimeException("创建对象异常");
+ }
+ return obj;
+ }
+}
diff --git a/src/main/java/com/wb/excel/api/util/DataTableUtil.java b/src/main/java/com/wb/excel/api/util/DataTableUtil.java
new file mode 100644
index 0000000..d55891f
--- /dev/null
+++ b/src/main/java/com/wb/excel/api/util/DataTableUtil.java
@@ -0,0 +1,46 @@
+package com.wb.excel.api.util;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * Created on 2014/10/12.
+ *
+ * @author
+ * @version 0.1.0
+ */
+public class DataTableUtil {
+
+ /**
+ * 测试用方法。从本地文件读取字节数据。
+ *
+ * @param url 本地文件路径
+ * @return 读取文件的byte数组
+ * @throws java.io.IOException 读取文件中可能会抛出异常
+ */
+ public static byte[] readFile(String url) throws IOException {
+ File file = new File(url);
+ InputStream is = new FileInputStream(file);
+ Long length = file.length();
+ if (length > Integer.MAX_VALUE) {
+ throw new IOException("文件过大,无法读取");
+ }
+
+ byte[] bytes = new byte[length.intValue()];
+ int offset = 0;
+ int numRead;
+ while (offset < bytes.length
+ && (numRead = is.read(bytes, offset, bytes.length - offset)) >= 0) {
+ offset += numRead;
+ }
+
+ //如果得到的字节长度和file实际的长度不一致就可能出错了
+ if (offset < bytes.length) {
+ System.out.println("文件长度不一致");
+ }
+ is.close();
+ return bytes;
+ }
+}
diff --git a/src/main/java/com/wb/excel/api/util/EnumUtil.java b/src/main/java/com/wb/excel/api/util/EnumUtil.java
new file mode 100644
index 0000000..b8cb4dd
--- /dev/null
+++ b/src/main/java/com/wb/excel/api/util/EnumUtil.java
@@ -0,0 +1,127 @@
+package com.wb.excel.api.util;
+
+
+import com.wb.excel.api.annotation.EnumValue;
+
+import java.lang.reflect.Field;
+
+/**
+ * Created on 2014/10/10.
+ *
+ * @author
+ * @version 0.1.0
+ */
+public class EnumUtil {
+ /**
+ * 用于判断输入的值是否属于枚举内容。
+ *
+ * @param clazz
+ * @param value 要判断的值
+ * @return true || false / 符合||不符合
+ */
+ public static Boolean check(Class clazz, String value) {
+ if (clazz.isEnum() && value.length() > 0) {
+ value = value.toLowerCase();
+ Field[] fields = clazz.getFields();
+ for (Field field : fields) {
+ if (!field.isAnnotationPresent(EnumValue.class)) {
+ continue;
+ }
+ EnumValue enumValue = field.getAnnotation(EnumValue.class);
+ String[] enumValues = enumValue.value();
+ for (String temp : enumValues) {
+ if (temp.equals(value)) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * 通过指定的枚举类和value值,返回key值(未找到key时返回空字符串)
+ *
+ * @param clazz
+ * @param value
+ * @return
+ */
+ public static String getKey(Class clazz, String value) {
+ if (clazz.isEnum()) {
+ value = value.toLowerCase();
+ Field[] fields = clazz.getFields();
+ for (Field field : fields) {
+ if (!field.isAnnotationPresent(EnumValue.class)) {
+ continue;
+ }
+ EnumValue enumValue = field.getAnnotation(EnumValue.class);
+ String[] enumValues = enumValue.value();
+ for (String temp : enumValues) {
+ if (temp.equals(value)) {
+ return field.getName();
+ }
+ }
+ }
+ }
+ return "";
+ }
+
+ /**
+ * 通过指定的枚举类和key值,返回第一个value值(未指定value时会返回key的值)
+ *
+ * @param clazz 要获取值的枚举类
+ * @param key 枚举的key
+ * @return 对应的value
+ */
+ public static String getValue(Class clazz, String key) {
+ if (clazz.isEnum()) {
+ Field[] fields = clazz.getFields();
+ for (Field field : fields) {
+ if (!field.isAnnotationPresent(EnumValue.class)) {
+ continue;
+ }
+ EnumValue enumValue = field.getAnnotation(EnumValue.class);
+ String[] enumValues = enumValue.value();
+
+ /* 如果找到了key */
+ if (field.getName().equals(key)) {
+ /* 如果没有注明枚举的内容,直接返回key */
+ if (enumValues.length == 1 && enumValues[0].equals("")) {
+ enumValues[0] = key;
+ }
+ /* 返回 */
+ return enumValues[0];
+ }
+ }
+ }
+ return "";
+ }
+
+ /**
+ * 根据索引获取
+ *
+ * @param
+ * @param clazz
+ * @param ordinal
+ * @return
+ */
+ public static > T valueOf(Class clazz, int ordinal) {
+ return clazz.getEnumConstants()[ordinal];
+ }
+
+ /**
+ * 根据name获取
+ *
+ * @param
+ * @param enumType
+ * @param name
+ * @return
+ */
+ public static > T valueOf(Class enumType, String name) {
+ if (name != null && !"".equals(name)) {
+ return Enum.valueOf(enumType, name);
+ }
+ return null;
+ }
+}
diff --git a/src/main/java/com/wb/excel/api/util/ExcelUtil.java b/src/main/java/com/wb/excel/api/util/ExcelUtil.java
new file mode 100644
index 0000000..22625e7
--- /dev/null
+++ b/src/main/java/com/wb/excel/api/util/ExcelUtil.java
@@ -0,0 +1,32 @@
+package com.wb.excel.api.util;
+
+import org.apache.poi.ss.usermodel.Cell;
+
+/**
+ * Excel工具类.
+ * Created on 2014/9/1.
+ *
+ * @author
+ * @since 0.1.0
+ */
+public class ExcelUtil {
+
+ /**
+ * 获取单元格的值
+ *
+ * @param cell 要获取值的单元格
+ * @return 单元格的值
+ */
+ public static String getValue(Cell cell) {
+ if (cell.getCellType() == Cell.CELL_TYPE_BOOLEAN) {
+ // 返回布尔类型的值
+ return String.valueOf(cell.getBooleanCellValue());
+ } else if (cell.getCellType() == Cell.CELL_TYPE_NUMERIC) {
+ // 返回数值类型的值
+ return String.valueOf(cell.getNumericCellValue());
+ } else {
+ // 返回字符串类型的值
+ return String.valueOf(cell.getStringCellValue());
+ }
+ }
+}
diff --git a/src/main/java/com/wb/excel/api/util/StringUtil.java b/src/main/java/com/wb/excel/api/util/StringUtil.java
new file mode 100644
index 0000000..9634cb9
--- /dev/null
+++ b/src/main/java/com/wb/excel/api/util/StringUtil.java
@@ -0,0 +1,206 @@
+package com.wb.excel.api.util;
+
+import com.wb.excel.api.enumeration.YesNo;
+import org.apache.poi.hssf.usermodel.HSSFDateUtil;
+
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+
+/**
+ * Created by DEV001 on 2014/9/1.
+ */
+public class StringUtil {
+
+ public static int getByteLength(String str) {
+ int length = str.replaceAll("[^\\x00-\\xff]", "**").length();
+ return length;
+ }
+
+ public static String upperFirstWord(String str) {
+ String temp = str.substring(0, 1);
+ return temp.toUpperCase() + str.substring(1);
+ }
+
+ /**
+ * TODO
+ *
+ * @param str
+ * @param reg
+ * @param index
+ * @return
+ */
+ public static String split(String str, String reg, int index) {
+ if (reg.length() == 0) {
+ return str;
+ }
+ String[] strings = str.split(reg);
+ if (index < 0) {
+ index = 0;
+ }
+ if (index >= strings.length) {
+ index = strings.length - 1;
+ }
+ return strings[index];
+ }
+
+ public static String substring(String str, int start, int end) {
+ if (0 >= start || start >= str.length()) {
+ end = str.length() - 1;
+ }
+ if (0 >= end || end >= str.length()) {
+ end = str.length() - 1;
+ }
+ return str.substring(start, end);
+ }
+
+ public static String transferDate(String value) {
+ Double d = TransferUtil.transferDouble(value);
+ Date date = null;
+ SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
+ if (d == null) {
+ try {
+ date = sdf.parse(value);
+ } catch (ParseException e) {
+ e.printStackTrace();
+ }
+ } else {
+ date = HSSFDateUtil.getJavaDate(d);
+ }
+ return sdf.format(date);
+ }
+
+ public static String transferDatetime(String value) {
+ Double d = TransferUtil.transferDouble(value);
+ Date date = null;
+
+ List sdfList = new ArrayList<>();
+ sdfList.add("yyyy-MM-dd HH:mm:ss");
+ sdfList.add("yyyy-MM-dd hh:mm:ss");
+ sdfList.add("yyyy/MM/dd HH:mm:ss");
+ sdfList.add("yyyy/MM/dd hh:mm:ss");
+
+ SimpleDateFormat stdFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+
+ if (d == null) {
+ for (String sdfValue : sdfList) {
+ SimpleDateFormat sdf = new SimpleDateFormat(sdfValue);
+ try {
+ date = sdf.parse(value);
+ break;
+ } catch (ParseException ignored) {
+ }
+ }
+ } else {
+ date = HSSFDateUtil.getJavaDate(d);
+ }
+ return stdFormat.format(date);
+ }
+
+ public static String transferDateminute(String value) {
+ Double d = TransferUtil.transferDouble(value);
+ Date date = null;
+
+ List sdfList = new ArrayList<>();
+ sdfList.add("yyyy-MM-dd HH:mm:ss");
+ sdfList.add("yyyy-MM-dd hh:mm:ss");
+ sdfList.add("yyyy/MM/dd HH:mm:ss");
+ sdfList.add("yyyy/MM/dd hh:mm:ss");
+
+ SimpleDateFormat stdFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm");
+
+ if (d == null) {
+ for (String sdfValue : sdfList) {
+ SimpleDateFormat sdf = new SimpleDateFormat(sdfValue);
+ try {
+ date = sdf.parse(value);
+ break;
+ } catch (ParseException ignored) {
+ }
+ }
+ } else {
+ date = HSSFDateUtil.getJavaDate(d);
+ }
+ return stdFormat.format(date);
+ }
+
+ public static String transferInteger(String value) {
+ try {
+ Double d = Double.parseDouble(value);
+ int i = d.intValue();
+ if (d != i) {
+ return null;
+ } else {
+ return "" + i;
+ }
+ } catch (Exception e) {
+ return null;
+ }
+ }
+
+ public static String transferBoolean(String value) {
+ String key = EnumUtil.getKey(YesNo.class, value);
+ if (key.equals("Y")) {
+ return "是";
+ } else if (key.equals("N")) {
+ return "否";
+ }
+ return "";
+ }
+
+ public static String transferLong(String value) {
+ try {
+ Double d = Double.parseDouble(value);
+ long i = d.longValue();
+ if (d != i) {
+ return null;
+ } else {
+ return "" + i;
+ }
+ } catch (Exception e) {
+ return null;
+ }
+ }
+
+ /**
+ * 将字符串加密处理,例:sample@passionnetwork.com → samp***********.com
+ *
+ * @param input 想要加密的字符串
+ * @param startLength 加密开始位置
+ * @param endLength 加密结束位置
+ * @param isAbsolute 是否保持原来长度
+ * @return 加密后的字符串
+ */
+ public static String encryptString(String input, int startLength, int endLength, boolean isAbsolute) {
+ int length = input.length();
+ int endIndex = length - endLength;
+ if (startLength > length || endLength > length) {
+ return input;
+ }
+
+ String start = input.substring(0, startLength);
+ String end = input.substring(endIndex);
+ String out = start;
+
+ if (isAbsolute) {
+ for (int i = startLength; i < endIndex; i++) {
+ out += "*";
+ }
+ } else {
+ out += "****";
+ }
+ out += end;
+
+ return out;
+ }
+
+ public static String fixNumberLength(int number, int length) {
+ String fixedNumber = "" + String.valueOf(number);
+ while (fixedNumber.length() < length) {
+ fixedNumber = "0" + fixedNumber;
+ }
+ return fixedNumber;
+ }
+}
diff --git a/src/main/java/com/wb/excel/api/util/StringUtils.java b/src/main/java/com/wb/excel/api/util/StringUtils.java
new file mode 100644
index 0000000..d76add6
--- /dev/null
+++ b/src/main/java/com/wb/excel/api/util/StringUtils.java
@@ -0,0 +1,146 @@
+package com.wb.excel.api.util;
+
+import org.apache.poi.hpsf.Constants;
+
+/**
+ * ***************************************************************
+ *
+ *
+ * Copyright (c) 2014 –
+ * HeaderDescription:
+ * ***************************************************************
+ *
+ */
+public class StringUtils {
+ private StringUtils() {
+ }
+
+ /**
+ * 检查指定的字符串是否为空。
+ *
+ * - SysUtils.isEmpty(null) = true
+ * - SysUtils.isEmpty("") = true
+ * - SysUtils.isEmpty(" ") = true
+ * - SysUtils.isEmpty("abc") = false
+ *
+ *
+ * @param value 待检查的字符串
+ * @return true/false
+ */
+ public static boolean isEmpty(String value) {
+ int strLen;
+ if(value == null || (strLen = value.length()) == 0) {
+ return true;
+ }
+ for(int i = 0; i < strLen; i++) {
+ if((Character.isWhitespace(value.charAt(i)) == false)) {
+ return false;
+ }
+ }
+ return true;
+ }
+ public static boolean isNotEmpty(String value) {
+ int strLen;
+ if(value == null || (strLen = value.length()) == 0) {
+ return false;
+ }
+ for(int i = 0; i < strLen; i++) {
+ if((Character.isWhitespace(value.charAt(i)) == false)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * 检查对象是否为数字型字符串,包含负数开头的。
+ */
+ public static boolean isNumeric(Object obj) {
+ if(obj == null) {
+ return false;
+ }
+ char[] chars = obj.toString().toCharArray();
+ int length = chars.length;
+ if(length < 1)
+ return false;
+
+ int i = 0;
+ if(length > 1 && chars[0] == '-')
+ i = 1;
+
+ for(; i < length; i++) {
+ if(!Character.isDigit(chars[i])) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * 检查指定的字符串列表是否不为空。
+ */
+ public static boolean areNotEmpty(String... values) {
+ boolean result = true;
+ if(values == null || values.length == 0) {
+ result = false;
+ } else {
+ for(String value : values) {
+ result &= !isEmpty(value);
+ }
+ }
+ return result;
+ }
+
+ /**
+ * 把通用字符编码的字符串转化为汉字编码。
+ */
+ public static String unicodeToChinese(String unicode) {
+ StringBuilder out = new StringBuilder();
+ if(!isEmpty(unicode)) {
+ for(int i = 0; i < unicode.length(); i++) {
+ out.append(unicode.charAt(i));
+ }
+ }
+ return out.toString();
+ }
+
+ public static String toUnderlineStyle(String name) {
+ StringBuilder newName = new StringBuilder();
+ for(int i = 0; i < name.length(); i++) {
+ char c = name.charAt(i);
+ if(Character.isUpperCase(c)) {
+ if(i > 0) {
+ newName.append("_");
+ }
+ newName.append(Character.toLowerCase(c));
+ } else {
+ newName.append(c);
+ }
+ }
+ return newName.toString();
+ }
+//
+// public static String convertString(byte[] data, int offset, int length) {
+// if(data == null) {
+// return null;
+// } else {
+// try {
+// return new String(data, offset, length, Constants.CHARSET_UTF8);
+// } catch(Exception e) {
+// throw new RuntimeException(e);
+// }
+// }
+// }
+//
+// public static byte[] convertBytes(String data) {
+// if(data == null) {
+// return null;
+// } else {
+// try {
+// return data.getBytes(Constants.CHARSET_UTF8);
+// } catch(Exception e) {
+// throw new RuntimeException(e);
+// }
+// }
+// }
+}
diff --git a/src/main/java/com/wb/excel/api/util/TransferUtil.java b/src/main/java/com/wb/excel/api/util/TransferUtil.java
new file mode 100644
index 0000000..021c7f6
--- /dev/null
+++ b/src/main/java/com/wb/excel/api/util/TransferUtil.java
@@ -0,0 +1,101 @@
+package com.wb.excel.api.util;
+
+
+import com.wb.excel.api.enumeration.YesNo;
+
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+/**
+ * Created on 2014/9/27.
+ *
+ * @author
+ * @version 0.1.0
+ */
+public class TransferUtil {
+ public static Date transferDate(String value) {
+ Date date = null;
+ try {
+ if (value.length() == 10) {
+ SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
+ date = sdf.parse(value);
+ } else if (value.length() > 10) {
+ SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+ date = sdf.parse(value);
+ }
+ } catch (ParseException e) {
+ e.printStackTrace();
+ }
+ return date;
+ }
+
+ public static Date transferDatetime(String value) {
+ SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+ Date date = null;
+ try {
+ date = sdf.parse(value);
+ } catch (ParseException e) {
+ e.printStackTrace();
+ }
+ return date;
+ }
+
+ public static Date transferDateminute(String value) {
+ SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm");
+ Date date = null;
+ try {
+ date = sdf.parse(value);
+ } catch (ParseException e) {
+ e.printStackTrace();
+ }
+ return date;
+ }
+
+ public static Integer transferInteger(String value) {
+ try {
+ Double d = Double.parseDouble(value);
+ int i = d.intValue();
+ if (d != i) {
+ return null;
+ } else {
+ return i;
+ }
+ } catch (Exception e) {
+ return null;
+ }
+ }
+
+ public static Double transferDouble(String value) {
+ try {
+ return Double.parseDouble(value);
+ } catch (Exception e) {
+ return null;
+ }
+ }
+
+ public static Boolean transferBoolean(String value) {
+ String key = EnumUtil.getKey(YesNo.class, value);
+ if (key.equals("Y")) {
+ return true;
+ } else if (key.equals("N")) {
+ return false;
+ } else {
+ return null;
+ }
+ }
+
+ public static Long transferLong(String value) {
+ try {
+ Double d = Double.parseDouble(value);
+ long i = d.longValue();
+ if (d != i) {
+ return null;
+ } else {
+ return i;
+ }
+ } catch (Exception e) {
+ return null;
+ }
+ }
+}
diff --git a/src/main/java/com/wb/excel/api/util/ValidationUtil.java b/src/main/java/com/wb/excel/api/util/ValidationUtil.java
new file mode 100644
index 0000000..e54c0b7
--- /dev/null
+++ b/src/main/java/com/wb/excel/api/util/ValidationUtil.java
@@ -0,0 +1,241 @@
+package com.wb.excel.api.util;
+
+
+import javax.validation.ConstraintViolation;
+import javax.validation.Validation;
+import javax.validation.Validator;
+import javax.validation.ValidatorFactory;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Set;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * 验证工具类。提供一些通用简单的数据验证功能。
+ * Created by DEV001 on 2014/8/1.
+ */
+public class ValidationUtil {
+
+ private static Validator validator;
+
+ /**
+ * 检查ID是否合法
+ *
+ * @param id 要检查的ID
+ * @return true, ID合法
+ */
+ public static Boolean checkId(Long id) {
+ return !(null == id || id < 1);
+ }
+
+ public static Boolean checkDate(String value) {
+ try {
+ Double.valueOf(value);
+ } catch (Exception e) {
+ SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
+ try {
+ sdf.parse(value);
+ return true;
+ } catch (ParseException e1) {
+ e1.printStackTrace();
+ }
+ return false;
+ }
+ return true;
+ }
+
+ public static Boolean checkDatetime(String value) {
+ try {
+ Double.valueOf(value);
+ } catch (Exception e) {
+ List sdfList = new ArrayList<>();
+ sdfList.add("yyyy-MM-dd HH:mm:ss");
+ sdfList.add("yyyy-MM-dd hh:mm:ss");
+ sdfList.add("yyyy/MM/dd HH:mm:ss");
+ sdfList.add("yyyy/MM/dd hh:mm:ss");
+
+ for (int i = 0; i < sdfList.size(); i++) {
+ String sdfValue = sdfList.get(i);
+ SimpleDateFormat sdf = new SimpleDateFormat(sdfValue);
+ try {
+ sdf.parse(value);
+ return true;
+ } catch (ParseException ignored) {
+ }
+ }
+ return false;
+ }
+ return true;
+ }
+
+ public static Boolean checkDouble(String value) {
+ try {
+ Double.parseDouble(value);
+ } catch (Exception e) {
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * 检查一个字符串是否可以转为整数。
+ *
+ * @param value 要检查的字符串
+ * @return true || false
+ */
+ public static Boolean checkInteger(String value) {
+ try {
+ Double d = Double.parseDouble(value);
+ int i = d.intValue();
+ return d == i;
+ } catch (Exception e) {
+ return false;
+ }
+ }
+
+ /**
+ * 检查一个字符串是否可以转为长整数。
+ *
+ * @param value 要检查的字符串
+ * @return true || false
+ */
+ public static boolean checkLong(String value) {
+ try {
+ Double d = Double.parseDouble(value);
+ long l = d.longValue();
+ return d == l;
+ } catch (Exception e) {
+ return false;
+ }
+ }
+
+ /**
+ * 检查用户ID的列表是否合法
+ *
+ * @param ids 要检查的ID列表
+ * @return true, 输入的ID列表合法
+ */
+ public static Boolean checkIdList(List ids) {
+ return !(null == ids || ids.size() == 0);
+ }
+
+ /**
+ * 检查字符串。不为空返回true;为空返回false。
+ * 内容为空也认为是空
+ *
+ * @param str 要检查的字符串
+ * @return 检查的结果。true,检查通过;false,检查不通过。
+ */
+ public static Boolean checkString(String str) {
+ return !(null == str || 0 == str.trim().length());
+ }
+
+ /**
+ * 检查字符串的长度是否符合要求。 该方法不会删除字符串前后的空格
+ *
+ * @param str 要进行判断的字符串
+ * @param minLength 字符串限制的最小长度(包含)
+ * @param maxLength 字符串限制的最大长度(包含)
+ * @return 例如:限制长度 2,50。字符串为"aa"返回true,字符串为"a"返回false
+ */
+ public static Boolean checkStringLength(String str, int minLength, int maxLength) {
+ if (null == str) {
+ return false;
+ } else {
+ if (str.length() >= minLength && str.length() <= maxLength) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * 检查邮箱格式是否正确
+ *
+ * @param email 要检查的邮箱地址
+ * @return true, 格式正确;false,格式不正确
+ * 例如:
+ * 0123-abcd_ABCD@0123-abcd_ABCD.00aaBB--__.cc true
+ * a@a.a true
+ * tony@sina@qq.com false
+ */
+ public static Boolean checkEmail(String email) {
+ //验证邮箱地址的正则表达式
+ Pattern p;
+ p = Pattern.compile(
+ "^([a-zA-Z0-9]+[_|_|-|-|.]?)*[a-zA-Z0-9]+@([a-zA-Z0-9]+[_|_|-|-|.]?)*[a-zA-Z0-9]+.[a-zA-Z]{2,3}$");
+ Matcher m = p.matcher(email);
+ return m.matches();
+ }
+
+
+ /**
+ * 检查文件路径格式是否正确
+ *
+ * @param filePath 要检查的文件路径
+ * @return true, 格式正确;false,格式不正确
+ * 例如:
+ * C:\b.txt true
+ * C:\abc\a.txt true
+ * C:\windows\sys<\mfc.dll false
+ */
+ public static Boolean checkFilePath(String filePath) {
+ //验证文件路径格式的正则表达式
+ Pattern p = Pattern.compile("^(?(?:[a-zA-Z]:)?\\\\(?:[^\\\\\\?\\/\\*\\|<>:\"]+\\\\)+)(?(?[^\\\\\\?\\/\\*\\|<>:\"]+?)\\.(?[^.\\\\\\?\\/\\*\\|<>:\"]+))$");
+ Matcher m = p.matcher(filePath);
+ return m.matches();
+ }
+
+ /**
+ * 检查电话号码格式是否正确。
+ *
+ * @param phone 要检查的电话号码
+ * @return true, 格式正确;false,格式不正确
+ * 例如:
+ * 13345661234 true
+ * 16812341234 false
+ * 0512-123456 false
+ * 0512-2345678 true
+ * 12345678 false
+ * 22345678 true
+ */
+ public static Boolean checkPhone(String phone) {
+ List list = new LinkedList<>();
+ list.add(Pattern.compile("^[1][3,4,5,8][0-9]{9}$")); //验证手机号
+ list.add(Pattern.compile("^[0][1-9]{1,2}[0-9]-[2-9][0-9]{6,7}$")); //验证带区号固定电话,区号后加“-”
+ list.add(Pattern.compile("^[2-9][0-9]{6,7}$")); //验证不带区号的固定电话
+ list.add(Pattern.compile("([0][1-9]{1,2}[0-9])[2-9][0-9]{6,7}$"));
+
+ Matcher matcher;
+ Boolean result = false;
+ for (Pattern pattern : list) {
+ matcher = pattern.matcher(phone); //遍历匹配
+ result |= matcher.matches(); //对所有的匹配结果做或运算。
+ }
+ return result;
+ }
+
+ /**
+ * 检查URL是否正确
+ *
+ * @param url
+ * @return
+ */
+ public static Boolean checkUrl(String url) {
+ List list = new LinkedList<>();
+ list.add(Pattern.compile("^(http|www|ftp|)?(://)?(\\w+(-\\w+)*)(\\.(\\w+(-\\w+)*))*((:\\d+)?)(/(\\w+(-\\w+)*))*(\\.?(\\w)*)(\\?)?(((\\w*%)*(\\w*\\?)*(\\w*:)*(\\w*\\+)*(\\w*\\.)*(\\w*&)*(\\w*-)*(\\w*=)*(\\w*%)*(\\w*\\?)*(\\w*:)*(\\w*\\+)*(\\w*\\.)*(\\w*&)*(\\w*-)*(\\w*=)*)*(\\w*)*)$"));
+
+ Matcher matcher;
+ Boolean result = false;
+ for (Pattern pattern : list) {
+ matcher = pattern.matcher(url); //遍历匹配
+ result |= matcher.matches(); //对所有的匹配结果做或运算。
+ }
+ return result;
+ }
+
+}
diff --git a/src/main/java/com/wb/excel/api/util/VerifyDataUtil.java b/src/main/java/com/wb/excel/api/util/VerifyDataUtil.java
new file mode 100644
index 0000000..3107441
--- /dev/null
+++ b/src/main/java/com/wb/excel/api/util/VerifyDataUtil.java
@@ -0,0 +1,64 @@
+package com.wb.excel.api.util;
+
+import com.wb.excel.api.entity.DataVerifyResult;
+import com.wb.excel.api.entity.ExcelVerifyEntity;
+import com.wb.excel.api.interfaces.IExcelVerifyHandler;
+
+/**
+ * ***************************************************************
+ *
+ *
+ * Copyright (c) 2014 –
+ * HeaderDescription:
+ * ***************************************************************
+ *
+ */
+public class VerifyDataUtil {
+ private final static DataVerifyResult DEFAULT_RESULT = new DataVerifyResult(
+ true);
+
+ private void addVerifyResult(DataVerifyResult hanlderResult,
+ DataVerifyResult result) {
+ if (!hanlderResult.isSuccess()) {
+ result.setSuccess(false);
+ result.setMsg((StringUtils.isEmpty(result.getMsg()) ? "" : result.getMsg() + " , ")
+ + hanlderResult.getMsg());
+ }
+ }
+
+ public DataVerifyResult verifyData(Object object, Object value, String name, String showName,
+ ExcelVerifyEntity verify, IExcelVerifyHandler excelVerifyHandler) {
+ if (verify == null) {
+ return DEFAULT_RESULT;
+ }
+ DataVerifyResult result = new DataVerifyResult(true, "");
+ if (verify.isNotNull()) {
+ addVerifyResult(BaseVerifyUtil.notNull(showName, value), result);
+ }
+ if (verify.isEmail()) {
+ addVerifyResult(BaseVerifyUtil.isEmail(showName, value), result);
+ }
+ if (verify.isMobile()) {
+ addVerifyResult(BaseVerifyUtil.isMobile(showName, value), result);
+ }
+ if (verify.isTel()) {
+ addVerifyResult(BaseVerifyUtil.isTel(showName, value), result);
+ }
+ if (verify.getMaxLength() != -1) {
+ addVerifyResult(BaseVerifyUtil.maxLength(showName, value, verify.getMaxLength()), result);
+ }
+ if (verify.getMinLength() != -1) {
+ addVerifyResult(BaseVerifyUtil.minLength(showName, value, verify.getMinLength()), result);
+ }
+ if (StringUtils.isNotEmpty(verify.getRegex())) {
+ addVerifyResult(
+ BaseVerifyUtil.regex(showName, value, verify.getRegex(), verify.getRegexTip()),
+ result);
+ }
+ if (verify.isInterHandler()) {
+ addVerifyResult(excelVerifyHandler.verifyHandler(object, name, value), result);
+ }
+ return result;
+
+ }
+}
diff --git a/src/test/java/ExampleTest.java b/src/test/java/ExampleTest.java
new file mode 100644
index 0000000..a2e86e7
--- /dev/null
+++ b/src/test/java/ExampleTest.java
@@ -0,0 +1,109 @@
+import com.wb.excel.api.Excel;
+import com.wb.excel.api.datatable.DataTable;
+import com.wb.excel.api.enumeration.YesNo;
+import com.wb.excel.api.exception.TemplateNotMatchException;
+
+import java.io.*;
+import java.lang.reflect.InvocationTargetException;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * 实例
+ */
+public class ExampleTest {
+
+ public static void main(String[] args) throws IOException, NoSuchMethodException, IllegalAccessException, InvocationTargetException {
+ testExport();
+ testImport();
+ }
+
+ public static void testExport() {
+
+ try {
+ //第一步,准备数据模型及数据,模型需要打上注解
+ List pos = new ArrayList();
+
+ User user = new User("张三", "zs123", "123123");
+ user.setSex(YesNo.Y);
+ pos.add(user);
+ pos.add(user);
+
+ //第二步,初始化数据
+ DataTable dataTable = new DataTable(pos);
+
+ //第三步,初始化Excel
+ Excel excel = new Excel(dataTable);
+
+ //第四步,导出xlsx文件
+ output("user.xlsx", excel.getBytes());
+ } catch (NoSuchMethodException e) {
+ e.printStackTrace();
+ } catch (IOException e) {
+ e.printStackTrace();
+ } catch (IllegalAccessException e) {
+ e.printStackTrace();
+ } catch (InvocationTargetException e) {
+ e.printStackTrace();
+ }
+
+ }
+
+ public static void testImport() {
+ try {
+ File file = new File("user.xlsx");
+ FileInputStream stream = new FileInputStream(file);
+
+ byte[] bytes = new byte[stream.available()];
+ stream.read(bytes);
+
+ DataTable dataTable = new DataTable(bytes, User.class);
+
+ if (dataTable.hasError()) {
+ Excel excel = new Excel(true, dataTable);
+ output("user_err.xlsx", excel.getBytes());
+ } else {
+ List list = dataTable.transferList(User.class);
+ System.out.println("本次读取数据" + list.size() + "条!");
+ }
+
+ } catch (FileNotFoundException e) {
+ e.printStackTrace();
+ } catch (IllegalAccessException e) {
+ e.printStackTrace();
+ } catch (InvocationTargetException e) {
+ e.printStackTrace();
+ } catch (IOException e) {
+ e.printStackTrace();
+ } catch (InstantiationException e) {
+ e.printStackTrace();
+ } catch (TemplateNotMatchException e) {
+ e.printStackTrace();
+ } catch (NoSuchMethodException e) {
+ e.printStackTrace();
+ }
+ }
+
+ public static void output(String path, byte[] bytes) {
+ try {
+ File file = new File(path);
+ file.createNewFile();
+
+ FileOutputStream fileOutputStream = null;
+ try {
+ fileOutputStream = new FileOutputStream(file);
+ fileOutputStream.write(bytes);
+ } finally {
+ try {
+ fileOutputStream.flush();
+ fileOutputStream.close();
+ } catch (Exception e) {
+
+ }
+ }
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+
+ }
+}
diff --git a/src/test/java/User.java b/src/test/java/User.java
new file mode 100644
index 0000000..1e361b9
--- /dev/null
+++ b/src/test/java/User.java
@@ -0,0 +1,55 @@
+import com.wb.excel.api.annotation.Enum;
+import com.wb.excel.api.annotation.EnumValue;
+import com.wb.excel.api.enumeration.YesNo;
+
+
+public class User {
+
+ private String name;
+ private String password;
+ private String qq;
+
+ @Enum(target = YesNo.class)
+ private YesNo sex;
+
+ public User() {
+ }
+
+ public User(String name, String password, String qq) {
+ this.name = name;
+ this.password = password;
+ this.qq = qq;
+ }
+
+ public YesNo getSex() {
+ return sex;
+ }
+
+ public void setSex(YesNo sex) {
+ this.sex = sex;
+ }
+
+ public String getQq() {
+ return qq;
+ }
+
+ public void setQq(String qq) {
+ this.qq = qq;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getPassword() {
+ return password;
+ }
+
+ public void setPassword(String password) {
+ this.password = password;
+ }
+}
| |