diff --git a/src/main/java/com/wb/excel/api/datatable/WCell.java b/src/main/java/com/wb/excel/api/WCell.java similarity index 96% rename from src/main/java/com/wb/excel/api/datatable/WCell.java rename to src/main/java/com/wb/excel/api/WCell.java index 946cd46..db5b1ad 100644 --- a/src/main/java/com/wb/excel/api/datatable/WCell.java +++ b/src/main/java/com/wb/excel/api/WCell.java @@ -1,4 +1,4 @@ -package com.wb.excel.api.datatable; +package com.wb.excel.api; import com.wb.excel.api.enumeration.Status; diff --git a/src/main/java/com/wb/excel/api/datatable/WColumn.java b/src/main/java/com/wb/excel/api/WColumn.java similarity index 86% rename from src/main/java/com/wb/excel/api/datatable/WColumn.java rename to src/main/java/com/wb/excel/api/WColumn.java index e4b1424..427f66b 100644 --- a/src/main/java/com/wb/excel/api/datatable/WColumn.java +++ b/src/main/java/com/wb/excel/api/WColumn.java @@ -1,7 +1,7 @@ -package com.wb.excel.api.datatable; +package com.wb.excel.api; -import com.wb.excel.api.enumeration.DataType; +import com.wb.excel.api.converter.Converter; import com.wb.excel.api.util.StringUtil; import java.io.Serializable; @@ -34,9 +34,9 @@ public class WColumn implements Serializable { */ private String description; /** - * 该列的数据类型 + * 列转换器 */ - private DataType dataType; + private Converter converter; private Field field; @@ -46,7 +46,6 @@ public class WColumn implements Serializable { this.isHidden = false; this.isRequired = false; this.description = ""; - this.dataType = DataType.STRING; } public WColumn(String name) { @@ -55,7 +54,6 @@ public class WColumn implements Serializable { this.isHidden = false; this.isRequired = false; this.description = ""; - this.dataType = DataType.STRING; } //----------- getter & setter -------------- @@ -110,11 +108,11 @@ public class WColumn implements Serializable { this.description = description; } - public DataType getDataType() { - return dataType; + public Converter getConverter() { + return converter; } - public void setDataType(DataType dataType) { - this.dataType = dataType; + public void setConverter(Converter converter) { + this.converter = converter; } } diff --git a/src/main/java/com/wb/excel/api/WExcel.java b/src/main/java/com/wb/excel/api/WExcel.java deleted file mode 100644 index e86c56a..0000000 --- a/src/main/java/com/wb/excel/api/WExcel.java +++ /dev/null @@ -1,317 +0,0 @@ -package com.wb.excel.api; - -import com.wb.excel.api.annotation.ColumnDescription; -import com.wb.excel.api.datatable.WCell; -import com.wb.excel.api.datatable.WColumn; -import com.wb.excel.api.datatable.WSheet; -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 WExcel { - /** - * 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 WExcel() { - init(); - } - - /** - * 将一个DataTable转换为Excel对象,不显示检查结果和错误消息栏.
- * 通常用于导出报表. - * {@link WExcel#WExcel(boolean flag, WSheet... dataTable)} - * - * @param tables 要导出的DataTable集合 - */ - public WExcel(WSheet... tables) { - workbook = this.initExcel(false, tables); - } - - /** - * 将若干DataTable转换为Excel对象. - * - * @param flag 是否需要添加检查结果和错误消息栏(true,会添加;false,不会添加) - * @param tables DataTable列表 - */ - public WExcel(boolean flag, WSheet... tables) { - workbook = this.initExcel(flag, tables); - } - - public XSSFWorkbook initExcel(boolean flag, WSheet... tables) { - init(); - Set nameSet = new HashSet<>(tables.length); - for (WSheet 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 = WSheet.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++) { - WColumn WColumn = table.getWColumns()[j]; - if (WColumn.isHidden()) { - hiddenNumber++; - continue; - } - int k = j - hiddenNumber; - if (flag) { - k++; - } - org.apache.poi.ss.usermodel.Cell firstCell = firstRow.createCell(k); - String columnName = WColumn.getName(); - XSSFRichTextString textString; - if (WColumn.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(WColumn.getDescription()).append("\n"); - if (WColumn.getDataType() != DataType.STRING) { - // 如果数据类型不是字符串类型,添加特殊数据类型的说明信息。 - Field[] fields = DataType.class.getDeclaredFields(); - for (Field field : fields) { - if (field.getName().equals(WColumn.getDataType().name())) { - if (field.isAnnotationPresent(ColumnDescription.class)) { - - // 获取声明字段上的Description信息。 - ColumnDescription columnDescription = field.getAnnotation(ColumnDescription.class); - if (columnDescription.value() != null) { - sb.append(columnDescription.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 + WColumn.getCellWidth()) * 256); - } - - // 错误消息栏 - if (flag) { - org.apache.poi.ss.usermodel.Cell firstCell = firstRow.createCell(table.getColumnIndex() + 1 - hiddenNumber); - String columnName = WSheet.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++) { - WColumn WColumn = table.getWColumns()[j]; - if (WColumn.isHidden()) { - hiddenNumber++; - continue; - } - int k = j - hiddenNumber; - if (flag) { - k++; - } - - org.apache.poi.ss.usermodel.Cell xssfCell = row.createCell(k); - WCell WCell = table.getCell(i, j); - if (null == WCell) { - continue; - } - String value = WCell.getValue(); - xssfCell.setCellValue(value); - - // 如果该列是数字类型,则靠右 - if (table.getWColumns()[j].getDataType() == DataType.DECIMAL - || table.getWColumns()[j].getDataType() == DataType.NUMBER) { - if (flag && !WCell.getStatus().equals(Status.PASS)) { - xssfCell.setCellStyle(errorNumberCellStyle); - } else { - xssfCell.setCellStyle(normalNumberCellStyle); - } - } else { - if (flag && !WCell.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; - } - - /** - * 得到已生成好的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/datatable/WRow.java b/src/main/java/com/wb/excel/api/WRow.java similarity index 86% rename from src/main/java/com/wb/excel/api/datatable/WRow.java rename to src/main/java/com/wb/excel/api/WRow.java index 6930e55..70909e3 100644 --- a/src/main/java/com/wb/excel/api/datatable/WRow.java +++ b/src/main/java/com/wb/excel/api/WRow.java @@ -1,4 +1,4 @@ -package com.wb.excel.api.datatable; +package com.wb.excel.api; import java.io.Serializable; import java.util.HashMap; diff --git a/src/main/java/com/wb/excel/api/WSheet.java b/src/main/java/com/wb/excel/api/WSheet.java new file mode 100644 index 0000000..d668631 --- /dev/null +++ b/src/main/java/com/wb/excel/api/WSheet.java @@ -0,0 +1,636 @@ +package com.wb.excel.api; + +import com.wb.excel.api.annotation.*; +import com.wb.excel.api.converter.*; +import com.wb.excel.api.converter.Converter; +import com.wb.excel.api.enumeration.Status; +import com.wb.excel.api.exception.IllegalParameterException; +import com.wb.excel.api.exception.TemplateNotMatchException; +import com.wb.excel.api.style.*; +import com.wb.excel.api.util.ClassUtil; +import com.wb.excel.api.util.ExcelUtil; +import com.wb.excel.api.util.StringUtil; +import org.apache.poi.hssf.usermodel.HSSFWorkbook; +import org.apache.poi.ss.usermodel.*; +import org.apache.poi.xssf.usermodel.*; + +import javax.validation.constraints.NotNull; +import java.io.*; +import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.*; + +/** + * 数据表的定义。
+ * Created on 2014/09/19. + * + * @author 沈振家 + * @since 0.1.0 + */ +public class WSheet implements Serializable, Cloneable { + + /** + * 表名 + */ + private String name; + + /** + * 表头的集合 + */ + private List columnList = new ArrayList<>(); + + /** + * 单元格里存放的对象 + */ + private List rowList = new ArrayList<>(); + + /** + * 根据输入的模板类打印下载模板。 + */ + public WSheet(Class tClass) { + initColumns(tClass); + } + + /** + * 根据模板类对DataTable添加相应的列。 + * + * @return 包含@Name标记的字段Set + */ + private List initColumns(Class clazz) { + //获取工作簿名称,没有则以类名为默认工作簿名称 + SheetName sheetName = clazz.getAnnotation(SheetName.class); + if (sheetName != null) { + this.setName(sheetName.value()); + } else { + this.setName(clazz.getName()); + } + + //是否关注父类属性 + boolean parentFirst = clazz.isAnnotationPresent(ParentFirst.class) && clazz.getAnnotation(ParentFirst.class).value(); + Field[] fields = ClassUtil.getFields(clazz, parentFirst); + for (Field field : fields) { + WColumn WColumn = new WColumn(); + WColumn.setField(field); + if (field.isAnnotationPresent(Ignore.class) && field.getAnnotation(Ignore.class).value()) { + WColumn.setHidden(true); + } + + //获取列名称 + if (!field.isAnnotationPresent(ColumnName.class)) { + WColumn.setName(field.getName()); + } else { + ColumnName columnColumnName = field.getAnnotation(ColumnName.class); + WColumn.setName(columnColumnName.value()); + } + //获取列填写说明或描述 + if (field.isAnnotationPresent(ColumnDescription.class)) { + WColumn.setDescription(field.getAnnotation(ColumnDescription.class).value()); + } + + //列填写标志(是否必填) + if (field.isAnnotationPresent(NotNull.class)) { + WColumn.setRequired(true); + } + + //获取列类型 + if (field.isAnnotationPresent(com.wb.excel.api.annotation.Converter.class)) { + com.wb.excel.api.annotation.Converter converter = field.getAnnotation(com.wb.excel.api.annotation.Converter.class); + Class target = converter.target(); + try { + WColumn.setConverter((Converter) target.newInstance()); + } catch (InstantiationException e) { + e.printStackTrace(); + } catch (IllegalAccessException e) { + e.printStackTrace(); + } + } else { + if (field.getType() == boolean.class || field.getType() == Boolean.class) { + WColumn.setConverter(new BooleanConverter()); + } else if (field.getType() == byte.class || field.getType() == Byte.class) { + WColumn.setConverter(new ByteConverter()); + } else if (field.getType() == char.class || field.getType() == Character.class) { + WColumn.setConverter(new CharacterConverter()); + } else if (field.getType() == short.class || field.getType() == Short.class) { + WColumn.setConverter(new ShortConverter()); + } else if (field.getType() == int.class || field.getType() == Integer.class) { + WColumn.setConverter(new IntegerConverter()); + } else if (field.getType() == long.class || field.getType() == Long.class) { + WColumn.setConverter(new LongConverter()); + } else if (field.getType() == float.class || field.getType() == Float.class) { + WColumn.setConverter(new FloatConverter()); + } else if (field.getType() == double.class || field.getType() == Double.class) { + WColumn.setConverter(new DoubleConverter()); + } else if (field.getType() == Date.class) { + WColumn.setConverter(new DateConverter()); + } else if (field.getType() == String.class) { + WColumn.setConverter(new StringConverter()); + } else { + throw new RuntimeException("Can not find Converter"); + } + } + + columnList.add(WColumn); + } + return columnList; + } + + /** + * 此构造方法仅用于转换对象列表。
+ * 并不会对数据的格式和合法性进行检验。 + * + * @param list 需要导出的对象列表 + * @throws NoSuchMethodException + * @throws InvocationTargetException + * @throws IllegalAccessException + */ + public WSheet(List list) throws InvocationTargetException, IllegalAccessException, NoSuchMethodException { + if (list == null || list.size() == 0) { + throw new IllegalParameterException("不允许传入空的列表"); + } + if (list.size() > 0) { + List wColumns = initColumns(list.get(0).getClass()); + + for (T t : list) { + WRow row = new WRow(); + for (WColumn column : wColumns) { + if (column == null) { + continue; + } + Field field = column.getField(); + String att = StringUtil.upperFirstWord(field.getName()); + Method method = null; + try { + // 尝试获取get方法 + method = t.getClass().getMethod("get" + att); + } catch (NoSuchMethodException e) { + // 尝试获取is方法,工具生成布尔值可能是is而不是get + method = t.getClass().getMethod("is" + att); + } + Object value = method.invoke(t); + if (null == value) { + row.put(column.getName(), new WCell()); + } else { + row.put(column.getName(), new WCell(column.getConverter().string(value))); + } + } + this.rowList.add(row); + } + } + } + + /** + * 以Excel文件的字节数组为数据源,为自己赋值的同时,与指定的模板类进行数据校验。
+ * 如果匹配过程中发现了不符合的数据,会在对应的单元中添加错误信息。
+ * + * @param bytes Excel文件的字节数组 + * @param clazz 类型 + * @throws IOException
1:输入流无法转为Excel文件 - 请检查输入的 bytes 是否正确;
+ * 2:输入流关闭出错;
+ * @throws TemplateNotMatchException
1:Excel文件的列数与对象类型不匹配 - 请检查Excel表与模板类是否一致;
+ * 2:获取枚举类型出错 - 你在模板类中标注了一个变量的值为枚举类型,但程序寻找枚举类时出错;
+ */ + public WSheet(byte[] bytes, Class clazz) throws IOException, TemplateNotMatchException { + 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 sheet = workbook.getSheetAt(0); + //获取Sheet名称 + SheetName sheetName = clazz.getAnnotation(SheetName.class); + if (sheetName != null) {//如果模板存在注解则使用注解名称 + this.setName(sheetName.value()); + } else {//将类名设为表名,如果类名不存在,将Excel表名设为表名 + this.setName(sheet.getSheetName()); + } + + //读取表头 + Row headRow = sheet.getRow(0); + //获取Excel列的总数 + int columnSum = headRow.getPhysicalNumberOfCells(); + //匹配列的数量。用于判断Excel是否包含所有必须列。 + int columnMatchNumber = 0; + + //检查列数量 + List list = initColumns(clazz); + if (list.size() != columnSum) { + throw new TemplateNotMatchException("与模板列数量不同。"); + } else { + for (int i = 0; i < list.size(); i++) { + WColumn wColumn = list.get(i); + Cell cell = headRow.getCell(i); + String headValue = ExcelUtil.getValue(cell); + headValue = headValue.replace("*", ""); + headValue = headValue.replace(" ", ""); + + if (!wColumn.getName().equals(headValue)) { + throw new TemplateNotMatchException("第" + (i + 1) + "项,不匹配的列名," + wColumn.getName() + "和" + headValue); + } + } + } + + int maxRowNumber = sheet.getLastRowNum(); //Excel文件的总行数 + /* 逐行读取导入文件的数据 */ + for (int i = 0; i < maxRowNumber; i++) { + Row inputRow = sheet.getRow(i + 1); //Excel中的一行数据,第0行为表头,所以要加1 + WRow row = new WRow(); + rowList.add(row); + + if (null != inputRow) { + for (int j = 0; j < columnList.size(); j++) { + WColumn wcolumn = columnList.get(j); + + /* 取得当前格子的值 */ + Cell excelCell = inputRow.getCell(j); + WCell WCell = new WCell(); + row.put(wcolumn.getName(), WCell); + + String value = ""; + if (null != excelCell) { + value = ExcelUtil.getValue(excelCell); + } + value = value.trim(); + + WCell.setValue(value); + + // 检查是否必须项 + if (wcolumn.isRequired()) { + if (value.length() == 0) { + WCell.setStatus(Status.EMPTY); + } + } + + // 检查长度是否合法 +// if (wcolumn) { +// if (value.length() > lengths[j].max() || value.length() < lengths[j].min()) { +// this.setStatus(i, j, Status.LENGTH); +// cellFlag = false; +// } +// } + + // 检查字符是否符合正则表达式 +// if (cellFlag && null != columnTypes[j] && !columnTypes[j].value().equals(DataType.STRING)) { +// if (!DataType.check(columnTypes[j].value(), WCell, value)) { +// this.setStatus(i, j, Status.FORMAT); +// cellFlag = false; +// } +// } + } + } + } + } + +// /** +// * 能过列名取得列下标。 +// * +// * @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.columnList.get(i).getName().equals(columnName)) { +// columnIndex = i; +// break; +// } +// } +// if (columnIndex == -1) { +// throw new ColumnNameNotExistException("不存在的列名:" + columnName); +// } +// return columnIndex; +// } + + /** + * 转换某行为一个对象 + * + * @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 = ClassUtil.getFields(clazz, parentFirst); + Set set = new HashSet<>(); + for (Field field : fields) { + set.add(field); + } + + for (int j = 0; j < this.columnList.size(); j++) { + WColumn wColumn = this.columnList.get(0); + if (wColumn.isHidden()) { + continue; + } + + String key = this.columnList.get(j).getName(); + + for (WColumn column : columnList) { + Field field = column.getField(); + ColumnName fieldColumnName = field.getAnnotation(ColumnName.class); + + if (key.equals(fieldColumnName.value())) { + + String att = StringUtil.upperFirstWord(field.getName()); + + WCell WCell = this.rowList.get(rowIndex).get(column.getName()); + if (null != WCell) { + String value = WCell.getValue(); + Method method = clazz.getMethod("set" + att, field.getType()); + //获取转换器 + Converter converter = column.getConverter(); + method.invoke(object, converter.convert(value)); + } + break; + } + } + } + return object; + } + + /** + * 将DataTable转为T型的List

+ * 如果你试图这么做,请确保在每个字段上都加上了@Name注解
+ * 并确保该注解的值与DataTable中列的名字一致。
+ * 注解的值在这里作为唯一的标识。 + * + * @return T型列表 + * @see WColumn 列名称 + */ + public List transferList(Class clazz) throws IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException { + List list = new ArrayList<>(); + + for (int i = 0; i < this.rowList.size(); 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; + } + +// +// public final String toCSV() { +// StringBuilder sb = new StringBuilder(); +// +// for (WColumn WColumn : this.getWColumns()) { +// if (WColumn != null) { +// sb.append(WColumn.getName()).append(","); +// } +// } +// sb.append("\n"); +// +// for (int i = 0; i < this.getRowIndex(); i++) { +// for (int j = 0; j < this.getColumnIndex(); j++) { +// WCell WCell = this.getCell(i, j); +// if (this.columnList.get(j).getDataType().equals(DataType.STRING) +// || this.columnList.get(j).getDataType().equals(DataType.DATE) +// || this.columnList.get(j).getDataType().equals(DataType.DATETIME)) { +// sb.append("\"\t").append(WCell.getValue()).append("\","); +// } else { +// sb.append(WCell.getValue()).append(","); +// } +// } +// sb.append("\n"); +// } +// +// return sb.toString(); +// } + + /** + * 判断DataTable是否包含错误信息 + * + * @return 是否包含错误. + */ + public final boolean hasError() { + for (WRow wRow : rowList) { + Iterator iterator = wRow.values().iterator(); + + while (iterator.hasNext()) { + WCell next = iterator.next(); + + if (next.getStatus().name() != Status.PASS.name()) { + return true; + } + } + + } + return false; + } + + /** + * 得到已生成好的Excel文件的字节流信息 + * + * @return 字节流信息 + * @throws IOException + */ + public byte[] getBytes() throws IOException { + XSSFWorkbook workbook = getExcel(false); + if (workbook != null) { + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + workbook.write(outputStream); + return outputStream.toByteArray(); + } + return null; + } + + public XSSFWorkbook getExcel(boolean flag) { + XSSFWorkbook workbook = new XSSFWorkbook(); + + //---------- 创建样式 ------------------ + CellStyle headCellStyle = new HeadCellStyle(workbook).getStyle(); + CellStyle errorCellStyle = new ErrorCellStyle(workbook).getStyle(); + CellStyle errorNumberCellStyle = new ErrorNumberCellStyle(workbook).getStyle(); + CellStyle normalCellStyle = new NormalCellStyle(workbook).getStyle(); + CellStyle normalNumberCellStyle = new NormalNumberCellStyle(workbook).getStyle(); + CellStyle checkMessageCellStyle = new CheckMessageCellStyle(workbook).getStyle(); + CellStyle checkFailureCellStyle = new CheckFailureCellStyle(workbook).getStyle(); + CellStyle checkSuccessCellStyle = new CheckSuccessCellStyle(workbook).getStyle(); + + //----------- 创建字体 ---------------- + Font normalFont = new NormalFont(workbook).getFont(); + Font redFont = new RedFont(workbook).getFont(); + + //创建一个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 = WSheet.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 < this.columnList.size(); j++) { + WColumn column = this.columnList.get(j); + Field field = column.getField(); + + 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 (field.isAnnotationPresent(ColumnDescription.class)) { + // 获取声明字段上的Description信息。 + ColumnDescription columnDescription = field.getAnnotation(ColumnDescription.class); + sb.append(columnDescription.value()); + sb.append("\n"); + } + + // 如果填写了注释信息 + 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 = WSheet.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 < this.rowList.size(); 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 < this.columnList.size(); j++) { + WColumn column = this.columnList.get(j); + if (column.isHidden()) { + hiddenNumber++; + continue; + } + int k = j - hiddenNumber; + if (flag) { + k++; + } + + org.apache.poi.ss.usermodel.Cell xssfCell = row.createCell(k); + WCell WCell = this.rowList.get(i).get(column.getName()); + if (null == WCell) { + continue; + } + String value = WCell.getValue(); + xssfCell.setCellValue(value); + + // 如果该列是数字类型,则靠右 +// if (table.getWColumns()[j].getDataType() == DataType.DECIMAL +// || table.getWColumns()[j].getDataType() == DataType.NUMBER) { +// if (flag && !WCell.getStatus().equals(Status.PASS)) { +// xssfCell.setCellStyle(errorNumberCellStyle); +// } else { +// xssfCell.setCellStyle(normalNumberCellStyle); +// } +// } else { +// if (flag && !WCell.getStatus().equals(Status.PASS)) { +// xssfCell.setCellStyle(errorCellStyle); +// } else { +// xssfCell.setCellStyle(normalCellStyle); +// } +// } + } + +// if (flag && !rowFlag) { +// Cell xssfCell = row.createCell(j + 1 - hiddenNumber); +// xssfCell.setCellValue(table.getRowError(i)); +// xssfCell.setCellStyle(checkMessageCellStyle); +// } + } + return workbook; + } +} diff --git a/src/main/java/com/wb/excel/api/annotation/ColumnType.java b/src/main/java/com/wb/excel/api/annotation/ColumnType.java deleted file mode 100644 index 5c41e79..0000000 --- a/src/main/java/com/wb/excel/api/annotation/ColumnType.java +++ /dev/null @@ -1,19 +0,0 @@ -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 ColumnType { - public DataType value() default DataType.STRING; -} diff --git a/src/main/java/com/wb/excel/api/annotation/NoRepeat.java b/src/main/java/com/wb/excel/api/annotation/Converter.java similarity index 55% rename from src/main/java/com/wb/excel/api/annotation/NoRepeat.java rename to src/main/java/com/wb/excel/api/annotation/Converter.java index 4a62af4..85b1816 100644 --- a/src/main/java/com/wb/excel/api/annotation/NoRepeat.java +++ b/src/main/java/com/wb/excel/api/annotation/Converter.java @@ -3,15 +3,14 @@ package com.wb.excel.api.annotation; import java.lang.annotation.*; /** - * Created on 2014/9/24. + * 优先通过target来获取转换器 * - * @author - * @version v1.0.0.0 + * @author 王兵 + * @version v0.0.1 */ @Target(ElementType.FIELD) @Retention(RetentionPolicy.RUNTIME) @Documented -public @interface NoRepeat { - String value() default ""; - +public @interface Converter { + Class target(); } diff --git a/src/main/java/com/wb/excel/api/annotation/Enum.java b/src/main/java/com/wb/excel/api/annotation/Enum.java deleted file mode 100644 index 76fe5b3..0000000 --- a/src/main/java/com/wb/excel/api/annotation/Enum.java +++ /dev/null @@ -1,17 +0,0 @@ -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 deleted file mode 100644 index 6acc43b..0000000 --- a/src/main/java/com/wb/excel/api/annotation/EnumValue.java +++ /dev/null @@ -1,26 +0,0 @@ -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/ExcelVerify.java b/src/main/java/com/wb/excel/api/annotation/ExcelVerify.java deleted file mode 100644 index c625916..0000000 --- a/src/main/java/com/wb/excel/api/annotation/ExcelVerify.java +++ /dev/null @@ -1,94 +0,0 @@ -/** - * 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; - -/** - * WExcel 导入校验 - * - * @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/IsDuplicated.java b/src/main/java/com/wb/excel/api/annotation/IsDuplicated.java deleted file mode 100644 index 3131370..0000000 --- a/src/main/java/com/wb/excel/api/annotation/IsDuplicated.java +++ /dev/null @@ -1,17 +0,0 @@ -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/Split.java b/src/main/java/com/wb/excel/api/annotation/Split.java deleted file mode 100644 index 5ce2f12..0000000 --- a/src/main/java/com/wb/excel/api/annotation/Split.java +++ /dev/null @@ -1,28 +0,0 @@ -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 deleted file mode 100644 index 155c6c0..0000000 --- a/src/main/java/com/wb/excel/api/annotation/Substring.java +++ /dev/null @@ -1,18 +0,0 @@ -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/converter/BooleanConverter.java b/src/main/java/com/wb/excel/api/converter/BooleanConverter.java new file mode 100644 index 0000000..10551ff --- /dev/null +++ b/src/main/java/com/wb/excel/api/converter/BooleanConverter.java @@ -0,0 +1,21 @@ +package com.wb.excel.api.converter; + +public class BooleanConverter implements Converter { + + @Override + public Boolean convert(String var) { + try { + return Boolean.parseBoolean(var); + } catch (Exception e) { + return false; + } + } + + @Override + public String string(Boolean var) { + if (var == null) { + return ""; + } + return String.valueOf(var); + } +} diff --git a/src/main/java/com/wb/excel/api/converter/ByteConverter.java b/src/main/java/com/wb/excel/api/converter/ByteConverter.java new file mode 100644 index 0000000..528dd56 --- /dev/null +++ b/src/main/java/com/wb/excel/api/converter/ByteConverter.java @@ -0,0 +1,21 @@ +package com.wb.excel.api.converter; + +public class ByteConverter implements Converter { + + @Override + public Byte convert(String var) { + try { + return Byte.parseByte(var); + } catch (Exception e) { + return 0; + } + } + + @Override + public String string(Byte var) { + if (var == null) { + return ""; + } + return String.valueOf(var); + } +} diff --git a/src/main/java/com/wb/excel/api/converter/CharacterConverter.java b/src/main/java/com/wb/excel/api/converter/CharacterConverter.java new file mode 100644 index 0000000..455c998 --- /dev/null +++ b/src/main/java/com/wb/excel/api/converter/CharacterConverter.java @@ -0,0 +1,21 @@ +package com.wb.excel.api.converter; + +public class CharacterConverter implements Converter { + + @Override + public Character convert(String var) { + if (var == null || var.equals("")) { + return '0'; + } else { + return var.charAt(0); + } + } + + @Override + public String string(Character var) { + if (var == null) { + return ""; + } + return String.valueOf(var).trim(); + } +} diff --git a/src/main/java/com/wb/excel/api/converter/Converter.java b/src/main/java/com/wb/excel/api/converter/Converter.java new file mode 100644 index 0000000..6b8e33b --- /dev/null +++ b/src/main/java/com/wb/excel/api/converter/Converter.java @@ -0,0 +1,9 @@ +package com.wb.excel.api.converter; + + +public interface Converter { + + T convert(String var); + + String string(T var); +} diff --git a/src/main/java/com/wb/excel/api/converter/DateConverter.java b/src/main/java/com/wb/excel/api/converter/DateConverter.java new file mode 100644 index 0000000..ab4243c --- /dev/null +++ b/src/main/java/com/wb/excel/api/converter/DateConverter.java @@ -0,0 +1,44 @@ +package com.wb.excel.api.converter; + +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Date; + +public class DateConverter implements Converter { + + @Override + public Date convert(String var) { + if (var == null) { + return null; + } + Date date = null; + try { + var = var.trim(); + if (var.matches("[0-9]{4}-[0-9]{1,2}-[0-9]{1,2}")) { + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); + return sdf.parse(var); + } else if (var.matches("[0-9]{4}/[0-9]{1,2}/[0-9]{1,2} [0-9]{1,2}:[0-9]{1,2}:[0-9]{1,2}")) { + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); + return sdf.parse(var); + } else if (var.matches("[0-9]{4}-[0-9]{1,2}-[0-9]{1,2} [0-9]{1,2}:[0-9]{1,2}:[0-9]{1,2}")) { + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + date = sdf.parse(var); + } else if (var.matches("[0-9]{4}年[0-9]{1,2}月[0-9]{1,2}日 [0-9]{1,2}:[0-9]{1,2}:[0-9]{1,2}")) { + SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss"); + date = sdf.parse(var); + } + + } catch (ParseException e) { + e.printStackTrace(); + } + return date; + } + + @Override + public String string(Date var) { + if (var == null) { + return ""; + } + return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(var); + } +} diff --git a/src/main/java/com/wb/excel/api/converter/DoubleConverter.java b/src/main/java/com/wb/excel/api/converter/DoubleConverter.java new file mode 100644 index 0000000..30b3771 --- /dev/null +++ b/src/main/java/com/wb/excel/api/converter/DoubleConverter.java @@ -0,0 +1,21 @@ +package com.wb.excel.api.converter; + +public class DoubleConverter implements Converter { + + @Override + public Double convert(String var) { + try { + return Double.parseDouble(var); + } catch (Exception e) { + return 0d; + } + } + + @Override + public String string(Double var) { + if (var == null) { + return ""; + } + return String.valueOf(var); + } +} diff --git a/src/main/java/com/wb/excel/api/converter/FloatConverter.java b/src/main/java/com/wb/excel/api/converter/FloatConverter.java new file mode 100644 index 0000000..1e6af31 --- /dev/null +++ b/src/main/java/com/wb/excel/api/converter/FloatConverter.java @@ -0,0 +1,21 @@ +package com.wb.excel.api.converter; + +public class FloatConverter implements Converter { + + @Override + public Float convert(String var) { + try { + return Float.parseFloat(var); + } catch (Exception e) { + return 0f; + } + } + + @Override + public String string(Float var) { + if (var == null) { + return ""; + } + return String.valueOf(var); + } +} diff --git a/src/main/java/com/wb/excel/api/converter/IntegerConverter.java b/src/main/java/com/wb/excel/api/converter/IntegerConverter.java new file mode 100644 index 0000000..4c98825 --- /dev/null +++ b/src/main/java/com/wb/excel/api/converter/IntegerConverter.java @@ -0,0 +1,21 @@ +package com.wb.excel.api.converter; + +public class IntegerConverter implements Converter { + + @Override + public Integer convert(String var) { + try { + return Integer.parseInt(var); + } catch (Exception e) { + return 0; + } + } + + @Override + public String string(Integer var) { + if (var == null) { + return ""; + } + return String.valueOf(var); + } +} diff --git a/src/main/java/com/wb/excel/api/converter/LongConverter.java b/src/main/java/com/wb/excel/api/converter/LongConverter.java new file mode 100644 index 0000000..7cb422e --- /dev/null +++ b/src/main/java/com/wb/excel/api/converter/LongConverter.java @@ -0,0 +1,21 @@ +package com.wb.excel.api.converter; + +public class LongConverter implements Converter { + + @Override + public Long convert(String var) { + try { + return Long.parseLong(var); + } catch (Exception e) { + return 0L; + } + } + + @Override + public String string(Long var) { + if (var == null) { + return ""; + } + return String.valueOf(var); + } +} diff --git a/src/main/java/com/wb/excel/api/converter/ShortConverter.java b/src/main/java/com/wb/excel/api/converter/ShortConverter.java new file mode 100644 index 0000000..563e361 --- /dev/null +++ b/src/main/java/com/wb/excel/api/converter/ShortConverter.java @@ -0,0 +1,21 @@ +package com.wb.excel.api.converter; + +public class ShortConverter implements Converter { + + @Override + public Short convert(String var) { + try { + return Short.parseShort(var); + } catch (Exception e) { + return 0; + } + } + + @Override + public String string(Short var) { + if (var == null) { + return ""; + } + return String.valueOf(var); + } +} diff --git a/src/main/java/com/wb/excel/api/converter/StringConverter.java b/src/main/java/com/wb/excel/api/converter/StringConverter.java new file mode 100644 index 0000000..7ecbaf0 --- /dev/null +++ b/src/main/java/com/wb/excel/api/converter/StringConverter.java @@ -0,0 +1,17 @@ +package com.wb.excel.api.converter; + +public class StringConverter implements Converter { + + @Override + public String convert(String var) { + return var; + } + + @Override + public String string(String var) { + if (var == null) { + return ""; + } + return String.valueOf(var); + } +} diff --git a/src/main/java/com/wb/excel/api/datatable/WSheet.java b/src/main/java/com/wb/excel/api/datatable/WSheet.java deleted file mode 100644 index 9bd903a..0000000 --- a/src/main/java/com/wb/excel/api/datatable/WSheet.java +++ /dev/null @@ -1,1098 +0,0 @@ -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.Cell; -import org.apache.poi.ss.usermodel.Row; -import org.apache.poi.ss.usermodel.Sheet; -import org.apache.poi.ss.usermodel.Workbook; -import org.apache.poi.xssf.usermodel.XSSFWorkbook; -import 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.*; -import java.util.Date; - -/** - * 数据表的定义。
- * Created on 2014/09/19. - * - * @author 沈振家 - * @since 0.1.0 - */ -public class WSheet 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 WColumn[] WColumns; - - /** - * 当前的行数 - */ - private int rowIndex; - private int columnIndex; - - /** - * 单元格里存放的对象 - */ - private WCell[][] data; - - /** - * 整个Table的错误列表 - */ - private List errorList; - - /** - * 每一行的错误情况。 - */ - private List> errorLists; - - /** - * 初始化准备工作。在构造方法前调用。 - */ - public void init() { - rowIndex = 0; - columnIndex = 0; - - WColumns = new WColumn[MAX_COLUMN_NUMBER]; - data = new WCell[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 WSheet() { - init(); - } - - /** - * 根据输入的模板类打印下载模板。 - * - * @param clazz 模板类 - */ - public WSheet(Class clazz) { - init(); - initColumns(clazz); - } - - /** - * 根据模板类对DataTable添加相应的列。 - * - * @param clazz 模板类 - * @return 包含@Name标记的字段Set - */ - private List initColumns(Class clazz) { - List result = new ArrayList(); - //获取工作簿名称,没有则以类名为默认工作簿名称 - SheetName sheetName = clazz.getAnnotation(SheetName.class); - if (sheetName != null) { - this.setName(sheetName.value()); - } else { - this.setName(clazz.getName()); - } - - //是否关注父类属性 - boolean parentFirst = clazz.isAnnotationPresent(ParentFirst.class) && clazz.getAnnotation(ParentFirst.class).value(); - Field[] fields = ClassUtil.getFields(clazz, parentFirst); - for (Field field : fields) { - WColumn WColumn = new WColumn(); - WColumn.setField(field); - if (field.isAnnotationPresent(Ignore.class) && field.getAnnotation(Ignore.class).value()) { - WColumn.setHidden(true); - } - - //获取列名称 - if (!field.isAnnotationPresent(ColumnName.class)) { - WColumn.setName(field.getName()); - } else { - ColumnName columnColumnName = field.getAnnotation(ColumnName.class); - WColumn.setName(columnColumnName.value()); - } - //获取列填写说明或描述 - if (field.isAnnotationPresent(ColumnDescription.class)) { - WColumn.setDescription(field.getAnnotation(ColumnDescription.class).value()); - } - - //列填写标志(是否必填) - if (field.isAnnotationPresent(NotNull.class)) { - WColumn.setRequired(true); - } - - //获取列类型 - if (field.isAnnotationPresent(ColumnType.class)) { - ColumnType columnType = field.getAnnotation(ColumnType.class); - WColumn.setDataType(columnType.value()); - } else { - WColumn.setDataType(DataType.STRING); - } - - this.addColumn(WColumn); - result.add(WColumn); - } - return result; - } - - /** - * 此构造方法仅用于转换对象列表。
- * 并不会对数据的格式和合法性进行检验。 - * - * @param list 需要导出的对象列表 - * @throws NoSuchMethodException - * @throws InvocationTargetException - * @throws IllegalAccessException - */ - public WSheet(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); - List wColumns = initColumns(tClass.getClass()); - - for (T t : list) { - WRow row = new WRow(); - for (WColumn WColumn : wColumns) { - if (WColumn == null) { - continue; - } - Field field = WColumn.getField(); - String att = StringUtil.upperFirstWord(field.getName()); - Method method = t.getClass().getMethod("get" + att); - Object value = method.invoke(t); - if (null == value) { - row.put(WColumn.getName(), new WCell()); - } else { - if (field.getType() == Date.class) { - Date date = (Date) value; - SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); - value = sdf.format(date); - } else if (field.getType() == java.sql.Date.class) { - Date date = (Date) value; - SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); - value = sdf.format(date); - } else if (field.getType() == Boolean.class) { - value = StringUtil.transferBoolean(value.toString()); - } else if (field.getType() == Boolean.class) { - value = StringUtil.transferBoolean(value.toString()); - } else if (field.isAnnotationPresent(Enum.class)) { - Enum e = field.getAnnotation(Enum.class); - value = EnumUtil.getValue(e.target(), value.toString()); - } - row.put(WColumn.getName(), new WCell(value.toString())); - } - } - this.addRow(row); - } - } - } - - /** - * 构造方法。传入Excel流,不需要指定类型。同时,也不会对数据进行检查。 - * - * @param bytes Excel的字节数组。 - * @throws IOException 可能会出现的错误。通常为以下错误:
- * 1.流不能转换为Workbook - */ - @Deprecated - public WSheet(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); - WColumn WColumn = new WColumn(); - WColumn.setName(ExcelUtil.getValue(cell)); - this.addColumn(WColumn); - } - - /* 逐行读取导入文件的数据,从1开始是因为第0行为表头 */ - int rowNumber = sheet.getLastRowNum(); - for (int i = 1; i <= rowNumber; i++) { - Row inputRow = sheet.getRow(i); - WRow row = new WRow(); - 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.getWColumns()[j].getName(), new WCell(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 WSheet(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 sheet = workbook.getSheetAt(0); - //获取Sheet名称 - SheetName sheetName = clazz.getAnnotation(SheetName.class); - if (sheetName != null) {//如果模板存在注解则使用注解名称 - this.setName(sheetName.value()); - } else {//将类名设为表名,如果类名不存在,将Excel表名设为表名 - this.setName(sheet.getSheetName()); - } - - //读取表头 - Row headRow = sheet.getRow(0); - //获取Excel列的总数 - int columnSum = headRow.getPhysicalNumberOfCells(); - //匹配列的数量。用于判断Excel是否包含所有必须列。 - int columnMatchNumber = 0; - - //检查列数量 - List list = initColumns(clazz); - if (list.size() != columnSum) { - throw new TemplateNotMatchException("与模板列数量不同。"); - } else { - for (int i = 0; i < list.size(); i++) { - WColumn wColumn = list.get(i); - Cell cell = headRow.getCell(i); - String headValue = ExcelUtil.getValue(cell); - headValue = headValue.replace("*", ""); - headValue = headValue.replace(" ", ""); - - if (!wColumn.getName().equals(headValue)) { - throw new TemplateNotMatchException("第" + (i + 1) + "项,不匹配的列名," + wColumn.getName() + "和" + headValue); - } - } - } - - /* 为Excel表中的每一列分配空间 */ - List> sets = new ArrayList<>(); - ColumnType[] columnTypes = new ColumnType[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]; - ColumnDescription[] columnDescriptions = new ColumnDescription[columnSum]; - IsDuplicated[] isDuplicateds = new IsDuplicated[columnSum]; - - int maxRowNumber = sheet.getLastRowNum(); //Excel文件的总行数 - /* 逐行读取导入文件的数据 */ - for (int i = 0; i < maxRowNumber; i++) { - Row inputRow = sheet.getRow(i + 1); //Excel中的一行数据,第0行为表头,所以要加1 - WRow row = new WRow(); //DataTable中的一行 - this.addRow(row); - - if (null != inputRow) { - for (int j = 0; j < columnSum; j++) { //逐格扫描 - - /* 取得当前格子的值 */ - Cell excelCell = inputRow.getCell(j); - WCell WCell = new WCell(); - this.setCell(i, WColumns[j].getName(), WCell); - - 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()); - } - - WCell.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 != columnTypes[j] && !columnTypes[j].value().equals(DataType.STRING)) { - if (!DataType.check(columnTypes[j].value(), WCell, 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 WColumn[] getWColumns() { - return this.WColumns; - } - - /** - * 通过坐标取得单元格 - * - * @param rowNumber 行坐标 - * @param columnName 列名 - * @return 对应坐标的单元格 - * @throws IndexOutOfBoundsException 下标越界 - * @throws ColumnNameNotExistException 列名不存在 - */ - public WCell getCell(int rowNumber, String columnName) - throws IndexOutOfBoundsException, ColumnNameNotExistException { - int columnNumber = getColumnIndex(columnName); - return getCell(rowNumber, columnNumber); - } - - /** - * 通过坐标取得单元格 - * - * @param rowNumber 行坐标 - * @param columnNumber 列坐标 - * @throws IndexOutOfBoundsException 下标越界 - */ - public final WCell 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 WCell 单元格 - * @throws IndexOutOfBoundsException 坐标不存在的情况下,会报出异常,提示坐标不存在。 - */ - public void setCell(int rowNumber, int columnNumber, WCell WCell) 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] = WCell; - this.setStatus(rowNumber, columnNumber, WCell.getStatus()); - } - - /** - * 设置某个单元格的值。注意:传入的是值 - * - * @param rowIndex 行坐标 - * @param columnName 列坐标 - * @param WCell 单元格 - * @throws IndexOutOfBoundsException 下标越界 - * @throws ColumnNameNotExistException 列名不存在 - */ - public void setCell(int rowIndex, String columnName, WCell WCell) - throws IndexOutOfBoundsException, ColumnNameNotExistException { - int columnNumber = getColumnIndex(columnName); - this.setCell(rowIndex, columnNumber, WCell); - } - - /** - * 设置某个单元格的状态值 。注意:传入的是值 - * - * @param rowNumber 行坐标 - * @param columnNumber 列坐标 - * @param status 状态值。 - * @throws IndexOutOfBoundsException 下标越界 - */ - public void setStatus(int rowNumber, int columnNumber, Status status) throws IndexOutOfBoundsException { - if (!status.equals(Status.PASS)) { - WCell WCell = this.getCell(rowNumber, columnNumber); - if (null == WCell) { - WCell = new WCell(); - this.setCell(rowNumber, columnNumber, WCell); - } - WCell.setStatus(status); - - StringBuilder message = new StringBuilder(this.getWColumns()[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.getWColumns()[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 WRow[] getDataRows() { - WRow[] wRows = new WRow[this.rowIndex]; - for (int i = 0; i < this.rowIndex; i++) { - WRow row = new WRow(); - for (int j = 0; j < this.columnIndex; j++) { - row.put(this.WColumns[j].getName(), this.data[i][j]); - } - wRows[i] = row; - } - return wRows; - } - - /** - * 按列获取所有的单元格 - * - * @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.WColumns[i].getName(), list); - } - return columns; - } - - /** - * 添加一行单元格。当数据量超过定义大小的一半时,会扩大容量至之前的1.5倍。 - * - * @param row 一行记录 - */ - public void addRow(WRow row) { - /* 如果占用了一半以上,进行扩容 */ - if (this.rowIndex >= MAX_ROW_NUMBER / 2) { - expandRow(); - } - for (int i = 0; i < this.columnIndex; i++) { - WCell WCell = row.get(this.WColumns[i].getName()); - if (null != WCell) { - this.setCell(this.rowIndex, i, WCell); - int width = StringUtil.getByteLength(WCell.getValue()); - if (width > this.getWColumns()[i].getCellWidth()) { - if (width > 100) { - width = 100; - } - this.getWColumns()[i].setCellWidth(width); - } - } - } - this.rowIndex++; - } - - /** - * 添加一列表头信息,会进行查重。当列数超过定义大小的一半时,会扩大容量至之前的1.5倍。 - * - * @param WColumn 要加入的表头信息 - */ - public void addColumn(WColumn WColumn) { - /* 如果占用了一半以上,进行扩容 */ - if (this.columnIndex >= MAX_COLUMN_NUMBER / 2) { - expandColumn(); - } - boolean exist = false; - WColumn.setName(WColumn.getName().replace("*", "")); //删除标题中的星号 - WColumn.setName(WColumn.getName().replace(" ", "")); //删除标题中的空格 - for (int i = 0; i < this.columnIndex; i++) { - if (WColumn.getName().equals(this.getWColumns()[i].getName())) { - exist = true; - } - } - if (!exist) { - this.WColumns[this.columnIndex++] = WColumn; - } else { - throw new ExistedColumnNameException("已存在名称为" + WColumn.getName() + "的列"); - } - } - - /** - * 当表空间列数不足时,扩大表和表头的列数。 - */ - protected void expandColumn() { - MAX_COLUMN_NUMBER *= (3 / 2) + 1; - /* 扩展表头 */ - WColumn[] temp = new WColumn[MAX_COLUMN_NUMBER]; - System.arraycopy(WColumns, 0, temp, 0, WColumns.length); - WColumns = 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() { - WCell[][] temp = new WCell[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 = ClassUtil.getFields(clazz, parentFirst); - Set set = new HashSet<>(); - for (Field field : fields) { - set.add(field); - } - - for (int j = 0; j < this.getColumnIndex(); j++) { - if (this.getWColumns()[j].isHidden()) { - continue; - } - - String key = this.getWColumns()[j].getName(); - if (key.equals(CHECK_STATUS_NAME) || key.equals(CHECK_STATUS_RESULT)) { - continue; - } - - for (Field field : set) { - ColumnName fieldColumnName = field.getAnnotation(ColumnName.class); - - if (key.equals(fieldColumnName.value())) { - - String att = StringUtil.upperFirstWord(field.getName()); - String value; - WCell WCell = this.getCell(rowIndex, j); - if (null != WCell) { - value = WCell.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.getType() == Date.class) { - Date date = TransferUtil.transferDate(value); - method.invoke(object, date); - } else if (field.getType() == Double.class || field.getType() == double.class - || field.getType() == Float.class || field.getType() == float.class) { - Double d = TransferUtil.transferDouble(value); - method.invoke(object, d); - } else if (field.getType() == Integer.class || field.getType() == int.class - || field.getType() == Long.class || field.getType() == long.class - || field.getType() == Short.class || field.getType() == short.class - || field.getType() == Byte.class || field.getType() == byte.class) { - Integer integer = TransferUtil.transferInteger(value); - method.invoke(object, integer); - } else if (field.getType() == Boolean.class || field.getType() == boolean.class) { - Boolean b = TransferUtil.transferBoolean(value); - method.invoke(object, b); - } else { - method.invoke(object, value); - } - } - break; - } - } - } - return object; - } - - /** - * 将DataTable转为T型的List

- * 如果你试图这么做,请确保在每个字段上都加上了@Name注解
- * 并确保该注解的值与DataTable中列的名字一致。
- * 注解的值在这里作为唯一的标识。 - * - * @return T型列表 - * @see WColumn 列名称 - */ - 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 (WColumn WColumn : this.getWColumns()) { - if (WColumn != null) { - sb.append(WColumn.getName()).append(","); - } - } - sb.append("\n"); - - for (int i = 0; i < this.getRowIndex(); i++) { - for (int j = 0; j < this.getColumnIndex(); j++) { - WCell WCell = this.getCell(i, j); - if (this.getWColumns()[j].getDataType().equals(DataType.STRING) - || this.getWColumns()[j].getDataType().equals(DataType.DATE) - || this.getWColumns()[j].getDataType().equals(DataType.DATETIME)) { - sb.append("\"\t").append(WCell.getValue()).append("\","); - } else { - sb.append(WCell.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 (WColumns[i].getCellWidth() < length) { - if (length > 100) { - length = 100; - } - WColumns[i].setCellWidth(length); - } - } - } - StringBuilder sb = new StringBuilder(""); - int sumWidth = 0; - - /* 打印表头 */ - - for (int i = 0; i < this.getColumnIndex(); i++) { - WColumn WColumn = this.getWColumns()[i]; - int width = WColumn.getCellWidth() - StringUtil.getByteLength(WColumn.getName()) + 4; - int left = width / 2; - int right = width - left; - - for (int j = 0; j < left; j++) { - sb.append(" "); - } - sb.append(WColumn.getName()); - for (int j = 0; j < right; j++) { - sb.append(" "); - } - sumWidth += WColumn.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.getWColumns()[j].getCellWidth(); - WCell WCell = null; - try { - WCell = this.getCell(i, j); - } catch (Exception e) { - e.printStackTrace(); - } - if (null != WCell) { - Object obj = WCell.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 != WCell.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/enumeration/DataType.java b/src/main/java/com/wb/excel/api/enumeration/DataType.java deleted file mode 100644 index 697c70a..0000000 --- a/src/main/java/com/wb/excel/api/enumeration/DataType.java +++ /dev/null @@ -1,83 +0,0 @@ -package com.wb.excel.api.enumeration; - -import com.wb.excel.api.annotation.ColumnDescription; -import com.wb.excel.api.annotation.ColumnName; -import com.wb.excel.api.datatable.WCell; -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 { - @ColumnName("字符型") - @ColumnDescription("普通的字符串类型,例如:abc123.,!@#") - STRING, - @ColumnName("整数型") - @ColumnDescription("整数类型,小数点后的数字会被抹去(不是四舍五入),例如:11,200,4000") - NUMBER, - @ColumnName("数字类型") - @ColumnDescription("可以带小数点的数字类型,例如:1.00,1.01") - DECIMAL, - @ColumnName("日期型") - @ColumnDescription("普通的日期类型,例如:2014-10-01") - DATE, - @ColumnName("时间日期型(秒)") - @ColumnDescription("时间精确到秒的日期类型,例如:2014-10-01 10:30:00") - DATETIME, - @ColumnName("是否型") - @ColumnDescription("指定是或者否的类型,例如:是,否") - BOOLEAN; - - /** - * 匹配格式. - * - * @param type 要判断的类型 - * @param WCell 需要判断类型的单元格(可能会有改变值的情况发生,所以需要传入此值) - * @param value 已被简单处理过的需要判断的值 - * @return 匹配结果。true,符合;false,不符合 - */ - public static boolean check(DataType type, WCell WCell, String value) { - boolean typeFlag = true; - if (value.length() > 0) { - switch (type) { - case DECIMAL: - typeFlag = ValidationUtil.checkDouble(value); - break; - case NUMBER: - typeFlag = ValidationUtil.checkInteger(value); - if (typeFlag) { - WCell.setValue(StringUtil.transferInteger(value)); - } - break; - case DATE: - typeFlag = ValidationUtil.checkDate(value); - if (typeFlag) { - WCell.setValue(StringUtil.transferDate(value)); - } - break; - case DATETIME: - typeFlag = ValidationUtil.checkDatetime(value); - if (typeFlag) { - WCell.setValue(StringUtil.transferDatetime(value)); - } - break; - case BOOLEAN: - typeFlag = EnumUtil.check(YesNo.class, value); - if (typeFlag) { - WCell.setValue(StringUtil.transferBoolean(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 deleted file mode 100644 index c70cab3..0000000 --- a/src/main/java/com/wb/excel/api/enumeration/Gender.java +++ /dev/null @@ -1,18 +0,0 @@ -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/YesNo.java b/src/main/java/com/wb/excel/api/enumeration/YesNo.java deleted file mode 100644 index 97ef556..0000000 --- a/src/main/java/com/wb/excel/api/enumeration/YesNo.java +++ /dev/null @@ -1,18 +0,0 @@ -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/util/ClassUtil.java b/src/main/java/com/wb/excel/api/util/ClassUtil.java index 5c13325..61b9e51 100644 --- a/src/main/java/com/wb/excel/api/util/ClassUtil.java +++ b/src/main/java/com/wb/excel/api/util/ClassUtil.java @@ -18,7 +18,7 @@ public class ClassUtil { /** * 获取模板类所有字段 * - * @param clazz 模板对象 + * @param clazz 模板对象 * @param parentFirst 是否关注父类的字段 * @return */ diff --git a/src/main/java/com/wb/excel/api/util/EnumUtil.java b/src/main/java/com/wb/excel/api/util/EnumUtil.java deleted file mode 100644 index b8cb4dd..0000000 --- a/src/main/java/com/wb/excel/api/util/EnumUtil.java +++ /dev/null @@ -1,127 +0,0 @@ -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/StringUtil.java b/src/main/java/com/wb/excel/api/util/StringUtil.java index 9634cb9..674440c 100644 --- a/src/main/java/com/wb/excel/api/util/StringUtil.java +++ b/src/main/java/com/wb/excel/api/util/StringUtil.java @@ -1,6 +1,5 @@ package com.wb.excel.api.util; -import com.wb.excel.api.enumeration.YesNo; import org.apache.poi.hssf.usermodel.HSSFDateUtil; import java.text.ParseException; @@ -9,9 +8,6 @@ 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) { @@ -99,108 +95,4 @@ public class StringUtil { 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 index efe7e74..2e91556 100644 --- a/src/main/java/com/wb/excel/api/util/StringUtils.java +++ b/src/main/java/com/wb/excel/api/util/StringUtils.java @@ -1,7 +1,5 @@ package com.wb.excel.api.util; -import org.apache.poi.hpsf.Constants; - /** * *************************************************************** *

@@ -29,23 +27,24 @@ public class StringUtils { */ public static boolean isEmpty(String value) { int strLen; - if(value == null || (strLen = value.length()) == 0) { + if (value == null || (strLen = value.length()) == 0) { return true; } - for(int i = 0; i < strLen; i++) { - if((Character.isWhitespace(value.charAt(i)) == false)) { + 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) { + if (value == null || (strLen = value.length()) == 0) { return false; } - for(int i = 0; i < strLen; i++) { - if((Character.isWhitespace(value.charAt(i)) == false)) { + for (int i = 0; i < strLen; i++) { + if ((Character.isWhitespace(value.charAt(i)) == false)) { return true; } } @@ -56,20 +55,20 @@ public class StringUtils { * 检查对象是否为数字型字符串,包含负数开头的。 */ public static boolean isNumeric(Object obj) { - if(obj == null) { + if (obj == null) { return false; } char[] chars = obj.toString().toCharArray(); int length = chars.length; - if(length < 1) + if (length < 1) return false; int i = 0; - if(length > 1 && chars[0] == '-') + if (length > 1 && chars[0] == '-') i = 1; - for(; i < length; i++) { - if(!Character.isDigit(chars[i])) { + for (; i < length; i++) { + if (!Character.isDigit(chars[i])) { return false; } } @@ -81,10 +80,10 @@ public class StringUtils { */ public static boolean areNotEmpty(String... values) { boolean result = true; - if(values == null || values.length == 0) { + if (values == null || values.length == 0) { result = false; } else { - for(String value : values) { + for (String value : values) { result &= !isEmpty(value); } } @@ -96,8 +95,8 @@ public class StringUtils { */ public static String unicodeToChinese(String unicode) { StringBuilder out = new StringBuilder(); - if(!isEmpty(unicode)) { - for(int i = 0; i < unicode.length(); i++) { + if (!isEmpty(unicode)) { + for (int i = 0; i < unicode.length(); i++) { out.append(unicode.charAt(i)); } } @@ -106,10 +105,10 @@ public class StringUtils { public static String toUnderlineStyle(String name) { StringBuilder newName = new StringBuilder(); - for(int i = 0; i < name.length(); i++) { + for (int i = 0; i < name.length(); i++) { char c = name.charAt(i); - if(Character.isUpperCase(c)) { - if(i > 0) { + if (Character.isUpperCase(c)) { + if (i > 0) { newName.append("_"); } newName.append(Character.toLowerCase(c)); diff --git a/src/main/java/com/wb/excel/api/util/TransferUtil.java b/src/main/java/com/wb/excel/api/util/TransferUtil.java index 672d1f5..f5b0ec0 100644 --- a/src/main/java/com/wb/excel/api/util/TransferUtil.java +++ b/src/main/java/com/wb/excel/api/util/TransferUtil.java @@ -1,8 +1,5 @@ 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; @@ -63,17 +60,6 @@ public class TransferUtil { } } - 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); diff --git a/src/main/java/com/wb/excel/api/util/ValidationUtil.java b/src/main/java/com/wb/excel/api/util/ValidationUtil.java index e54c0b7..a06ef20 100644 --- a/src/main/java/com/wb/excel/api/util/ValidationUtil.java +++ b/src/main/java/com/wb/excel/api/util/ValidationUtil.java @@ -1,16 +1,12 @@ 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; diff --git a/src/test/java/ExampleTest.java b/src/test/java/ExampleTest.java index 213e43f..1b6a4be 100644 --- a/src/test/java/ExampleTest.java +++ b/src/test/java/ExampleTest.java @@ -1,8 +1,5 @@ -import com.wb.excel.api.WExcel; -import com.wb.excel.api.datatable.WSheet; -import com.wb.excel.api.enumeration.YesNo; +import com.wb.excel.api.WSheet; import com.wb.excel.api.exception.TemplateNotMatchException; -import jdk.nashorn.internal.parser.JSONParser; import java.io.*; import java.lang.reflect.InvocationTargetException; @@ -16,10 +13,20 @@ import java.util.List; public class ExampleTest { public static void main(String[] args) throws IOException, NoSuchMethodException, IllegalAccessException, InvocationTargetException { -// testExport(); + testTemplate(); + testExport(); testImport(); } + public static void testTemplate() { + try { + WSheet WSheet = new WSheet<>(User.class); + output("user_template.xlsx", WSheet.getBytes()); + } catch (IOException e) { + e.printStackTrace(); + } + } + public static void testExport() { try { @@ -27,21 +34,24 @@ public class ExampleTest { List pos = new ArrayList(); User user = new User(); - user.setName("张三"); + user.setWz("张三"); user.setDate(new Date()); - user.setAge(20); - user.setSex(YesNo.Y); + user.setBr(true); + user.setBt((byte) 1); + user.setZf('A'); + user.setDzs((short) 1); + user.setZs(1); + user.setCzs((long) 1); + user.setFd(1.0f); + user.setSjd(1.0); pos.add(user); pos.add(user); //第二步,初始化数据 - WSheet WSheet = new WSheet(pos); - - //第三步,初始化Excel - WExcel WExcel = new WExcel(false, WSheet); + WSheet WSheet = new WSheet<>(pos); //第四步,导出xlsx文件 - output("user.xlsx", WExcel.getBytes()); + output("user.xlsx", WSheet.getBytes()); } catch (NoSuchMethodException e) { e.printStackTrace(); } catch (IOException e) { @@ -64,8 +74,8 @@ public class ExampleTest { WSheet WSheet = new WSheet(bytes, User.class); if (WSheet.hasError()) { - WExcel WExcel = new WExcel(true, WSheet); - output("user_err.xlsx", WExcel.getBytes()); +// WExcel WExcel = new WExcel(true, WSheet); +// output("user_err.xlsx", WExcel.getBytes()); } else { List list = WSheet.transferList(User.class); System.out.println("本次读取数据" + list.size() + "条!"); @@ -113,4 +123,5 @@ public class ExampleTest { } } + } diff --git a/src/test/java/User.java b/src/test/java/User.java index b6020ff..9546803 100644 --- a/src/test/java/User.java +++ b/src/test/java/User.java @@ -1,32 +1,38 @@ import com.wb.excel.api.annotation.ColumnName; -import com.wb.excel.api.annotation.Enum; import com.wb.excel.api.annotation.SheetName; -import com.wb.excel.api.enumeration.YesNo; -import javax.validation.constraints.NotNull; -import java.text.SimpleDateFormat; import java.util.Date; @SheetName("用户") public class User { - @NotNull - @ColumnName("姓名") - private String name; - @ColumnName("出生日期时间") + @ColumnName("文字") + private String wz; + @ColumnName("日期时间") private Date date; - @ColumnName("年纪") - private int age; - @Enum(target = YesNo.class) - @ColumnName("性别") - private YesNo sex; + @ColumnName("布尔") + private boolean br; + @ColumnName("比特") + private byte bt; + @ColumnName("字符") + private char zf; + @ColumnName("短整数") + private short dzs; + @ColumnName("整数") + private int zs; + @ColumnName("长整数") + private long czs; + @ColumnName("浮点") + private float fd; + @ColumnName("双精度") + private double sjd; - public String getName() { - return name; + public String getWz() { + return wz; } - public void setName(String name) { - this.name = name; + public void setWz(String wz) { + this.wz = wz; } public Date getDate() { @@ -37,24 +43,72 @@ public class User { this.date = date; } - public int getAge() { - return age; + public boolean isBr() { + return br; } - public void setAge(int age) { - this.age = age; + public void setBr(boolean br) { + this.br = br; } - public YesNo getSex() { - return sex; + public byte getBt() { + return bt; } - public void setSex(YesNo sex) { - this.sex = sex; + public void setBt(byte bt) { + this.bt = bt; + } + + public char getZf() { + return zf; + } + + public void setZf(char zf) { + this.zf = zf; + } + + public short getDzs() { + return dzs; + } + + public void setDzs(short dzs) { + this.dzs = dzs; + } + + public int getZs() { + return zs; + } + + public void setZs(int zs) { + this.zs = zs; + } + + public long getCzs() { + return czs; + } + + public void setCzs(long czs) { + this.czs = czs; + } + + public float getFd() { + return fd; + } + + public void setFd(float fd) { + this.fd = fd; + } + + public double getSjd() { + return sjd; + } + + public void setSjd(double sjd) { + this.sjd = sjd; } @Override public String toString() { - return "" + name + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(date) + age + sex; + return String.valueOf(this.zf); } }