From a4b8fc39a900b315977828097da324e34383fbe8 Mon Sep 17 00:00:00 2001 From: wangbing <1919101440@qq.com> Date: Fri, 15 Nov 2019 00:08:01 +0800 Subject: [PATCH] =?UTF-8?q?1=E3=80=81Excel?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../manger/callable/SpringBootCallable.java | 52 +- .../SpringBoot/java/frame/excel/WCell.java | 33 + .../SpringBoot/java/frame/excel/WColumn.java | 128 ++++ .../SpringBoot/java/frame/excel/WRow.java | 30 + .../SpringBoot/java/frame/excel/WSheet.java | 598 ++++++++++++++++++ .../excel/annotation/ColumnDescription.java | 17 + .../frame/excel/annotation/ColumnName.java | 31 + .../frame/excel/annotation/Converter.java | 16 + .../java/frame/excel/annotation/Ignore.java | 16 + .../frame/excel/annotation/ParentFirst.java | 16 + .../frame/excel/annotation/SheetName.java | 19 + .../excel/converter/BooleanConverter.java | 21 + .../frame/excel/converter/ByteConverter.java | 21 + .../excel/converter/CharacterConverter.java | 21 + .../java/frame/excel/converter/Converter.java | 8 + .../frame/excel/converter/DateConverter.java | 44 ++ .../excel/converter/DoubleConverter.java | 21 + .../frame/excel/converter/FloatConverter.java | 26 + .../excel/converter/IntegerConverter.java | 21 + .../frame/excel/converter/LongConverter.java | 34 + .../frame/excel/converter/ShortConverter.java | 21 + .../excel/converter/StringConverter.java | 17 + .../java/frame/excel/style/BaseCellStyle.java | 57 ++ .../java/frame/excel/style/BaseFont.java | 29 + .../java/frame/excel/style/DataCellStyle.java | 29 + .../frame/excel/style/ErrorCellStyle.java | 22 + .../java/frame/excel/style/HeadCellStyle.java | 15 + .../java/frame/excel/style/NormalFont.java | 18 + .../java/frame/excel/style/RedFont.java | 18 + .../java/frame/utils/ClassUtil.java | 173 +++++ .../java/frame/utils/StringUtil.java | 87 +++ .../java/frame/utils/ValidationUtil.java | 28 +- src/main/resources/modules/SpringBoot/pom.ftl | 11 + .../resources/templates/screen/module/mgr.ftl | 19 +- .../templates/screen/module/system/dict.ftl | 23 +- .../screen/module/system/dictItem.ftl | 19 +- 36 files changed, 1733 insertions(+), 26 deletions(-) create mode 100644 src/main/resources/modules/SpringBoot/java/frame/excel/WCell.java create mode 100644 src/main/resources/modules/SpringBoot/java/frame/excel/WColumn.java create mode 100644 src/main/resources/modules/SpringBoot/java/frame/excel/WRow.java create mode 100644 src/main/resources/modules/SpringBoot/java/frame/excel/WSheet.java create mode 100644 src/main/resources/modules/SpringBoot/java/frame/excel/annotation/ColumnDescription.java create mode 100644 src/main/resources/modules/SpringBoot/java/frame/excel/annotation/ColumnName.java create mode 100644 src/main/resources/modules/SpringBoot/java/frame/excel/annotation/Converter.java create mode 100644 src/main/resources/modules/SpringBoot/java/frame/excel/annotation/Ignore.java create mode 100644 src/main/resources/modules/SpringBoot/java/frame/excel/annotation/ParentFirst.java create mode 100644 src/main/resources/modules/SpringBoot/java/frame/excel/annotation/SheetName.java create mode 100644 src/main/resources/modules/SpringBoot/java/frame/excel/converter/BooleanConverter.java create mode 100644 src/main/resources/modules/SpringBoot/java/frame/excel/converter/ByteConverter.java create mode 100644 src/main/resources/modules/SpringBoot/java/frame/excel/converter/CharacterConverter.java create mode 100644 src/main/resources/modules/SpringBoot/java/frame/excel/converter/Converter.java create mode 100644 src/main/resources/modules/SpringBoot/java/frame/excel/converter/DateConverter.java create mode 100644 src/main/resources/modules/SpringBoot/java/frame/excel/converter/DoubleConverter.java create mode 100644 src/main/resources/modules/SpringBoot/java/frame/excel/converter/FloatConverter.java create mode 100644 src/main/resources/modules/SpringBoot/java/frame/excel/converter/IntegerConverter.java create mode 100644 src/main/resources/modules/SpringBoot/java/frame/excel/converter/LongConverter.java create mode 100644 src/main/resources/modules/SpringBoot/java/frame/excel/converter/ShortConverter.java create mode 100644 src/main/resources/modules/SpringBoot/java/frame/excel/converter/StringConverter.java create mode 100644 src/main/resources/modules/SpringBoot/java/frame/excel/style/BaseCellStyle.java create mode 100644 src/main/resources/modules/SpringBoot/java/frame/excel/style/BaseFont.java create mode 100644 src/main/resources/modules/SpringBoot/java/frame/excel/style/DataCellStyle.java create mode 100644 src/main/resources/modules/SpringBoot/java/frame/excel/style/ErrorCellStyle.java create mode 100644 src/main/resources/modules/SpringBoot/java/frame/excel/style/HeadCellStyle.java create mode 100644 src/main/resources/modules/SpringBoot/java/frame/excel/style/NormalFont.java create mode 100644 src/main/resources/modules/SpringBoot/java/frame/excel/style/RedFont.java create mode 100644 src/main/resources/modules/SpringBoot/java/frame/utils/ClassUtil.java create mode 100644 src/main/resources/modules/SpringBoot/java/frame/utils/StringUtil.java diff --git a/src/main/java/xyz/wbsite/dbtool/javafx/manger/callable/SpringBootCallable.java b/src/main/java/xyz/wbsite/dbtool/javafx/manger/callable/SpringBootCallable.java index 66459178..5734452d 100644 --- a/src/main/java/xyz/wbsite/dbtool/javafx/manger/callable/SpringBootCallable.java +++ b/src/main/java/xyz/wbsite/dbtool/javafx/manger/callable/SpringBootCallable.java @@ -556,12 +556,18 @@ public class SpringBootCallable implements Callable { ctx.put("moduleName", project.getProjectName()); ctx.put("timestamp", new Date().getTime()); - File base = new File(root.getAbsolutePath(), "base"); - base.mkdirs(); File auth = new File(root.getAbsolutePath(), "auth"); auth.mkdirs(); -// File freemarker = new File(root.getAbsolutePath(), "freemarker"); -// freemarker.mkdirs(); + File base = new File(root.getAbsolutePath(), "base"); + base.mkdirs(); + File excel = new File(root.getAbsolutePath(), "excel"); + excel.mkdirs(); + File excelannotation = new File(excel.getAbsolutePath(), "annotation"); + excelannotation.mkdirs(); + File excelconverter = new File(excel.getAbsolutePath(), "converter"); + excelconverter.mkdirs(); + File excelstyle = new File(excel.getAbsolutePath(), "style"); + excelstyle.mkdirs(); File utils = new File(root.getAbsolutePath(), "utils"); utils.mkdirs(); File validation = new File(root.getAbsolutePath(), "validation"); @@ -588,14 +594,43 @@ public class SpringBootCallable implements Callable { freeMarkerManager.outputTemp(new File(base.getAbsolutePath(), "SortType.java"), option + "/java/frame/base/SortType.java", ctx); freeMarkerManager.outputTemp(new File(base.getAbsolutePath(), "Token.java"), option + "/java/frame/base/Token.java", ctx); - //freemarker -// freeMarkerManager.outputTemp(new File(freemarker.getAbsolutePath(), "ViewNameTranslator.java"), option + "/java/frame/freemarker/ViewNameTranslator.java", ctx); -// freeMarkerManager.outputTemp(new File(freemarker.getAbsolutePath(), "Layout.java"), option + "/java/frame/freemarker/Layout.java", ctx); -// freeMarkerManager.outputTemp(new File(freemarker.getAbsolutePath(), "Uri.java"), option + "/java/frame/freemarker/Uri.java", ctx); + //excel + freeMarkerManager.outputTemp(new File(excel.getAbsolutePath(), "WCell.java"), option + "/java/frame/excel/WCell.java", ctx); + freeMarkerManager.outputTemp(new File(excel.getAbsolutePath(), "WColumn.java"), option + "/java/frame/excel/WColumn.java", ctx); + freeMarkerManager.outputTemp(new File(excel.getAbsolutePath(), "WRow.java"), option + "/java/frame/excel/WRow.java", ctx); + freeMarkerManager.outputTemp(new File(excel.getAbsolutePath(), "WSheet.java"), option + "/java/frame/excel/WSheet.java", ctx); + + freeMarkerManager.outputTemp(new File(excelannotation.getAbsolutePath(), "ColumnDescription.java"), option + "/java/frame/excel/annotation/ColumnDescription.java", ctx); + freeMarkerManager.outputTemp(new File(excelannotation.getAbsolutePath(), "ColumnName.java"), option + "/java/frame/excel/annotation/ColumnName.java", ctx); + freeMarkerManager.outputTemp(new File(excelannotation.getAbsolutePath(), "Converter.java"), option + "/java/frame/excel/annotation/Converter.java", ctx); + freeMarkerManager.outputTemp(new File(excelannotation.getAbsolutePath(), "Ignore.java"), option + "/java/frame/excel/annotation/Ignore.java", ctx); + freeMarkerManager.outputTemp(new File(excelannotation.getAbsolutePath(), "ParentFirst.java"), option + "/java/frame/excel/annotation/ParentFirst.java", ctx); + freeMarkerManager.outputTemp(new File(excelannotation.getAbsolutePath(), "SheetName.java"), option + "/java/frame/excel/annotation/SheetName.java", ctx); + + freeMarkerManager.outputTemp(new File(excelconverter.getAbsolutePath(), "BooleanConverter.java"), option + "/java/frame/excel/converter/BooleanConverter.java", ctx); + freeMarkerManager.outputTemp(new File(excelconverter.getAbsolutePath(), "ByteConverter.java"), option + "/java/frame/excel/converter/ByteConverter.java", ctx); + freeMarkerManager.outputTemp(new File(excelconverter.getAbsolutePath(), "CharacterConverter.java"), option + "/java/frame/excel/converter/CharacterConverter.java", ctx); + freeMarkerManager.outputTemp(new File(excelconverter.getAbsolutePath(), "Converter.java"), option + "/java/frame/excel/converter/Converter.java", ctx); + freeMarkerManager.outputTemp(new File(excelconverter.getAbsolutePath(), "DateConverter.java"), option + "/java/frame/excel/converter/DateConverter.java", ctx); + freeMarkerManager.outputTemp(new File(excelconverter.getAbsolutePath(), "DoubleConverter.java"), option + "/java/frame/excel/converter/DoubleConverter.java", ctx); + freeMarkerManager.outputTemp(new File(excelconverter.getAbsolutePath(), "FloatConverter.java"), option + "/java/frame/excel/converter/FloatConverter.java", ctx); + freeMarkerManager.outputTemp(new File(excelconverter.getAbsolutePath(), "IntegerConverter.java"), option + "/java/frame/excel/converter/IntegerConverter.java", ctx); + freeMarkerManager.outputTemp(new File(excelconverter.getAbsolutePath(), "LongConverter.java"), option + "/java/frame/excel/converter/LongConverter.java", ctx); + freeMarkerManager.outputTemp(new File(excelconverter.getAbsolutePath(), "ShortConverter.java"), option + "/java/frame/excel/converter/ShortConverter.java", ctx); + freeMarkerManager.outputTemp(new File(excelconverter.getAbsolutePath(), "StringConverter.java"), option + "/java/frame/excel/converter/StringConverter.java", ctx); + + freeMarkerManager.outputTemp(new File(excelstyle.getAbsolutePath(), "BaseCellStyle.java"), option + "/java/frame/excel/style/BaseCellStyle.java", ctx); + freeMarkerManager.outputTemp(new File(excelstyle.getAbsolutePath(), "BaseFont.java"), option + "/java/frame/excel/style/BaseFont.java", ctx); + freeMarkerManager.outputTemp(new File(excelstyle.getAbsolutePath(), "DataCellStyle.java"), option + "/java/frame/excel/style/DataCellStyle.java", ctx); + freeMarkerManager.outputTemp(new File(excelstyle.getAbsolutePath(), "ErrorCellStyle.java"), option + "/java/frame/excel/style/ErrorCellStyle.java", ctx); + freeMarkerManager.outputTemp(new File(excelstyle.getAbsolutePath(), "HeadCellStyle.java"), option + "/java/frame/excel/style/HeadCellStyle.java", ctx); + freeMarkerManager.outputTemp(new File(excelstyle.getAbsolutePath(), "NormalFont.java"), option + "/java/frame/excel/style/NormalFont.java", ctx); + freeMarkerManager.outputTemp(new File(excelstyle.getAbsolutePath(), "RedFont.java"), option + "/java/frame/excel/style/RedFont.java", ctx); //uitls freeMarkerManager.outputTemp(new File(utils.getAbsolutePath(), "Base64Util.java"), option + "/java/frame/utils/Base64Util.java", ctx); freeMarkerManager.outputTemp(new File(utils.getAbsolutePath(), "AESUtil.java"), option + "/java/frame/utils/AESUtil.java", ctx); + freeMarkerManager.outputTemp(new File(utils.getAbsolutePath(), "ClassUtil.java"), option + "/java/frame/utils/ClassUtil.java", ctx); freeMarkerManager.outputTemp(new File(utils.getAbsolutePath(), "CookieUtil.java"), option + "/java/frame/utils/CookieUtil.java", ctx); freeMarkerManager.outputTemp(new File(utils.getAbsolutePath(), "FileUtil.java"), option + "/java/frame/utils/FileUtil.java", ctx); freeMarkerManager.outputTemp(new File(utils.getAbsolutePath(), "LogUtil.java"), option + "/java/frame/utils/LogUtil.java", ctx); @@ -603,6 +638,7 @@ public class SpringBootCallable implements Callable { freeMarkerManager.outputTemp(new File(utils.getAbsolutePath(), "MD5Util.java"), option + "/java/frame/utils/MD5Util.java", ctx); freeMarkerManager.outputTemp(new File(utils.getAbsolutePath(), "ProcessUtil.java"), option + "/java/frame/utils/ProcessUtil.java", ctx); freeMarkerManager.outputTemp(new File(utils.getAbsolutePath(), "RSAUtil.java"), option + "/java/frame/utils/RSAUtil.java", ctx); + freeMarkerManager.outputTemp(new File(utils.getAbsolutePath(), "StringUtil.java"), option + "/java/frame/utils/StringUtil.java", ctx); freeMarkerManager.outputTemp(new File(utils.getAbsolutePath(), "ValidationUtil.java"), option + "/java/frame/utils/ValidationUtil.java", ctx); freeMarkerManager.outputTemp(new File(utils.getAbsolutePath(), "WebUtils.java"), option + "/java/frame/utils/WebUtils.java", ctx); freeMarkerManager.outputTemp(new File(utils.getAbsolutePath(), "IDgenerator.java"), option + "/java/frame/utils/IDgenerator.java", ctx); diff --git a/src/main/resources/modules/SpringBoot/java/frame/excel/WCell.java b/src/main/resources/modules/SpringBoot/java/frame/excel/WCell.java new file mode 100644 index 00000000..5b1791bf --- /dev/null +++ b/src/main/resources/modules/SpringBoot/java/frame/excel/WCell.java @@ -0,0 +1,33 @@ +package ${basePackage}.frame.excel; + + +import java.io.Serializable; + +public class WCell implements Serializable { + + private String value; + + /** + * 默认无参构造方法.会将单元格的状态设为通过. + */ + public WCell() { + this.value = ""; + } + + /** + * 传入默认单元格值的构造方法. + * + * @param value 单元格的值. + */ + public WCell(String value) { + this.value = value; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } +} diff --git a/src/main/resources/modules/SpringBoot/java/frame/excel/WColumn.java b/src/main/resources/modules/SpringBoot/java/frame/excel/WColumn.java new file mode 100644 index 00000000..3d3d5223 --- /dev/null +++ b/src/main/resources/modules/SpringBoot/java/frame/excel/WColumn.java @@ -0,0 +1,128 @@ +package ${basePackage}.frame.excel; + + +import xyz.wbsite.frame.excel.converter.Converter; +import xyz.wbsite.frame.utils.StringUtil; + +import java.io.Serializable; +import java.lang.reflect.Field; + +/** + * DataTable中的表头,包含本列的一些限制条件。
+ * 现有:列名、是否必须、是否允许重复、说明字段以及数据类型 + * Created by edward on 9/19/14. + */ +public class WColumn implements Serializable { + /** + * 列名 + */ + private String name; + /** + * 该列的最大宽度 + */ + private int cellWidth; + /** + * 是否为隐藏列,如果为隐藏列,在导出Excel文件时会被忽略 + */ + private boolean isHidden; + /** + * 是否是必输列 + */ + private boolean isRequired; + /** + * 该列的描述字段 + */ + private String description; + /** + * 列转换器 + */ + private Converter converter; + + private Field field; + + private int cellType = 1; + + public WColumn() { + this.name = ""; + this.cellWidth = 1; + this.isHidden = false; + this.isRequired = false; + this.description = ""; + } + + public WColumn(String name) { + this.name = name; + this.cellWidth = 1; + this.isHidden = false; + this.isRequired = false; + this.description = ""; + } + + //----------- 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 Field getField() { + return field; + } + + public void setField(Field field) { + this.field = field; + } + + 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 Converter getConverter() { + return converter; + } + + public void setConverter(Converter converter) { + this.converter = converter; + } + + public int getCellType() { + return cellType; + } + + public void setCellType(int cellType) { + this.cellType = cellType; + } +} diff --git a/src/main/resources/modules/SpringBoot/java/frame/excel/WRow.java b/src/main/resources/modules/SpringBoot/java/frame/excel/WRow.java new file mode 100644 index 00000000..76aea009 --- /dev/null +++ b/src/main/resources/modules/SpringBoot/java/frame/excel/WRow.java @@ -0,0 +1,30 @@ +package ${basePackage}.frame.excel; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; + +/** + * DataTable中的行对象. + * Created on 2014/09/19. + * + * @author + * @since 0.1.0 + */ +public class WRow extends HashMap implements Serializable { + + private List errorList = new ArrayList<>(); + + public final boolean hasError() { + return errorList.size() > 0; + } + + public final void addError(String errorMsg) { + errorList.add(errorMsg); + } + + public List getErrorList() { + return errorList; + } +} diff --git a/src/main/resources/modules/SpringBoot/java/frame/excel/WSheet.java b/src/main/resources/modules/SpringBoot/java/frame/excel/WSheet.java new file mode 100644 index 00000000..c97ec712 --- /dev/null +++ b/src/main/resources/modules/SpringBoot/java/frame/excel/WSheet.java @@ -0,0 +1,598 @@ +package ${basePackage}.frame.excel; + +import xyz.wbsite.frame.excel.style.DataCellStyle; +import xyz.wbsite.frame.excel.style.ErrorCellStyle; +import xyz.wbsite.frame.excel.style.HeadCellStyle; +import xyz.wbsite.frame.excel.style.RedFont; +import xyz.wbsite.frame.utils.ClassUtil; +import xyz.wbsite.frame.utils.StringUtil; +import xyz.wbsite.frame.utils.ValidationUtil; +import xyz.wbsite.frame.excel.annotation.*; +import xyz.wbsite.frame.excel.converter.*; +import org.apache.poi.hssf.usermodel.HSSFDateUtil; +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.text.SimpleDateFormat; +import java.util.*; + +/** + * 数据表的定义。
+ * Created on 2014/09/19. + * + * @author 沈振家 + * @since 0.1.0 + */ +public class WSheet implements Serializable, Cloneable { + + /** + * 表名 + */ + private String name; + + /** + * 表名 + */ + private boolean freezeFirst; + + /** + * 表头的集合 + */ + 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) { + //获取工作簿名称,没有则以类名为默认工作簿名称 + if (clazz.isAnnotationPresent(SheetName.class)) { + SheetName sheetName = clazz.getAnnotation(SheetName.class); + this.setName(sheetName.value()); + this.setFreezeFirst(sheetName.freezeFirst()); + } 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()); + WColumn.setCellWidth(columnColumnName.width()); + } + //获取列填写说明或描述 + if (field.isAnnotationPresent(ColumnDescription.class)) { + WColumn.setDescription(field.getAnnotation(ColumnDescription.class).value()); + } + + //列填写标志(是否必填) + if (field.isAnnotationPresent(NotNull.class)) { + WColumn.setRequired(true); + } + + //获取列类型 + if (field.isAnnotationPresent(xyz.wbsite.frame.excel.annotation.Converter.class)) { + xyz.wbsite.frame.excel.annotation.Converter converter = field.getAnnotation(xyz.wbsite.frame.excel.annotation.Converter.class); + Class target = converter.target(); + try { + WColumn.setConverter((xyz.wbsite.frame.excel.converter.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()); + WColumn.setCellType(Cell.CELL_TYPE_BOOLEAN); + } else if (field.getType() == byte.class || field.getType() == Byte.class) { + WColumn.setConverter(new ByteConverter()); + WColumn.setCellType(Cell.CELL_TYPE_NUMERIC); + } else if (field.getType() == char.class || field.getType() == Character.class) { + WColumn.setConverter(new CharacterConverter()); + WColumn.setCellType(Cell.CELL_TYPE_STRING); + } else if (field.getType() == short.class || field.getType() == Short.class) { + WColumn.setConverter(new ShortConverter()); + WColumn.setCellType(Cell.CELL_TYPE_NUMERIC); + } else if (field.getType() == int.class || field.getType() == Integer.class) { + WColumn.setConverter(new IntegerConverter()); + WColumn.setCellType(Cell.CELL_TYPE_NUMERIC); + } else if (field.getType() == long.class || field.getType() == Long.class) { + WColumn.setConverter(new LongConverter()); + WColumn.setCellType(Cell.CELL_TYPE_NUMERIC); + } else if (field.getType() == float.class || field.getType() == Float.class) { + WColumn.setConverter(new FloatConverter()); + WColumn.setCellType(Cell.CELL_TYPE_NUMERIC); + } else if (field.getType() == double.class || field.getType() == Double.class) { + WColumn.setConverter(new DoubleConverter()); + WColumn.setCellType(Cell.CELL_TYPE_NUMERIC); + } else if (field.getType() == Date.class) { + WColumn.setConverter(new DateConverter()); + WColumn.setCellType(Cell.CELL_TYPE_NUMERIC); + } else if (field.getType() == String.class) { + WColumn.setConverter(new StringConverter()); + WColumn.setCellType(Cell.CELL_TYPE_STRING); + } 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 RuntimeException("不允许传入空的列表"); + } + 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 { + String string = column.getConverter().string(value); + row.put(column.getName(), new WCell(string)); + } + } + this.rowList.add(row); + } + } + } + + /** + * 以Excel文件的字节数组为数据源,为自己赋值的同时,与指定的模板类进行数据校验。
+ * 如果匹配过程中发现了不符合的数据,会在对应的单元中添加错误信息。
+ * + * @param bytes Excel文件的字节数组 + * @param clazz 类型 + * @throws IOException
1:输入流无法转为Excel文件 - 请检查输入的 bytes 是否正确;
+ * 2:输入流关闭出错;
+ */ + public WSheet(byte[] bytes, Class clazz) throws IOException { + 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 RuntimeException("不支持的文件类型"); + } + //第一张Sheet表 + Sheet sheet = workbook.getSheetAt(0); + //获取Sheet名称 + if (clazz.isAnnotationPresent(SheetName.class)) {//如果模板存在注解则使用注解名称 + SheetName sheetName = clazz.getAnnotation(SheetName.class); + this.setName(sheetName.value()); + } else {//将类名设为表名,如果类名不存在,将Excel表名设为表名 + this.setName(sheet.getSheetName()); + } + + //读取表头 + Row headRow = sheet.getRow(0); + //获取Excel列的总数 + int columnSum = headRow.getPhysicalNumberOfCells(); + + //检查列数量 + List list = initColumns(clazz); + if (list.size() != columnSum) { + throw new RuntimeException("与模板列数量不同。"); + } else { + for (int i = 0; i < list.size(); i++) { + WColumn wColumn = list.get(i); + Cell cell = headRow.getCell(i); + String headValue = getValue(cell); + headValue = headValue.replace("*", ""); + headValue = headValue.replace(" ", ""); + + if (!wColumn.getName().equals(headValue)) { + throw new RuntimeException("第" + (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 = getValue(excelCell); + } + value = value.trim(); + + WCell.setValue(value); + } + } + + try { + T t = transferOneObject(clazz, i); + List validate = ValidationUtil.validate(t); + if (validate.size() > 0) { + for (String s : validate) { + row.addError(s); + } + } + } catch (Exception e) { + e.printStackTrace(); + row.addError("数据检查错误"); + } + } + } + + /** + * 转换某行为一个对象 + * + * @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()); + //获取转换器 + xyz.wbsite.frame.excel.converter.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 boolean getFreezeFirst() { + return freezeFirst; + } + + public void setFreezeFirst(boolean freezeFirst) { + this.freezeFirst = freezeFirst; + } + +// +// 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).getExcelType().equals(ExcelType.STRING) +// || this.columnList.get(j).getExcelType().equals(ExcelType.DATE) +// || this.columnList.get(j).getExcelType().equals(ExcelType.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) { + if (wRow.hasError()) { + 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 byte[] getBytes(boolean checkResult) throws IOException { + XSSFWorkbook workbook = getExcel(checkResult); + if (workbook != null) { + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + workbook.write(outputStream); + return outputStream.toByteArray(); + } + return null; + } + + public XSSFWorkbook getExcel(boolean checkResult) { + XSSFWorkbook workbook = new XSSFWorkbook(); + //创建一个Sheet表 + XSSFSheet sheet = workbook.createSheet(name); + sheet.setDefaultRowHeightInPoints(18); + Row firstRow = sheet.createRow(0); // 下标为0的行开始 + XSSFDrawing drawing = sheet.createDrawingPatriarch(); + + int offset = 0; + // 添加错误说明列 + if (checkResult && hasError()) { + offset++; + Cell firstCell = firstRow.createCell(0); + firstCell.setCellStyle(new ErrorCellStyle(workbook).getStyle()); + firstCell.setCellValue(new XSSFRichTextString("检查结果说明")); + sheet.setColumnWidth(0, 18 * 256); + } + + for (int j = 0; j < this.columnList.size(); j++) { + WColumn column = this.columnList.get(j); + Field field = column.getField(); + Cell firstCell = firstRow.createCell(j + offset); + String columnName = column.getName(); + XSSFRichTextString textString; + if (column.isRequired()) { + textString = new XSSFRichTextString("*" + columnName); + textString.applyFont(0, 1, new RedFont(workbook).getFont()); + textString.applyFont(1, textString.length(), workbook.createFont()); + } else { + textString = new XSSFRichTextString(columnName); + textString.applyFont(workbook.createFont()); + } + 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(new HeadCellStyle(workbook).getStyle()); + sheet.setColumnWidth(j + offset, (4 + column.getCellWidth()) * 256); + } + + // 冻结第一行 + if (freezeFirst) { + sheet.createFreezePane(255, 1); + } + + // 填充数据 + for (int i = 0; i < this.rowList.size(); i++) { + boolean flag = this.rowList.get(i).hasError(); + WRow wRow = this.rowList.get(i); + Row row = sheet.createRow(i + 1); + + if (flag) { + List errorList = wRow.getErrorList(); + Cell xssfCell = row.createCell(0); + xssfCell.setCellStyle(new ErrorCellStyle(workbook).getStyle()); + String join = String.join(";", errorList); + xssfCell.setCellValue(new XSSFRichTextString(join)); + } + + for (int j = 0; j < this.columnList.size(); j++) { + WColumn column = this.columnList.get(j); + + Cell xssfCell = row.createCell(j + offset); + WCell WCell = this.rowList.get(i).get(column.getName()); + if (null == WCell) { + continue; + } + String value = WCell.getValue(); + xssfCell.setCellType(column.getCellType()); + if (column.getCellType() == Cell.CELL_TYPE_NUMERIC || column.getCellType() == Cell.CELL_TYPE_BOOLEAN) { + xssfCell.setCellStyle(new DataCellStyle(workbook, CellStyle.ALIGN_RIGHT, wRow.hasError()).getStyle()); + } else { + xssfCell.setCellStyle(new DataCellStyle(workbook, CellStyle.ALIGN_LEFT, wRow.hasError()).getStyle()); + } + + xssfCell.setCellValue(value); + } + } + return workbook; + } + + /** + * 获取单元格的值 + * + * @param cell 要获取值的单元格 + * @return 单元格的值 + */ + public static String getValue(Cell cell) { + if (cell == null) { + return ""; + } + switch (cell.getCellType()) { + case Cell.CELL_TYPE_STRING: + return cell.getStringCellValue(); + case Cell.CELL_TYPE_BOOLEAN: + return String.valueOf(cell.getBooleanCellValue()); + case Cell.CELL_TYPE_NUMERIC: + if (HSSFDateUtil.isCellDateFormatted(cell)) { + Date value = cell.getDateCellValue(); + return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(value); + } else { + double numericCellValue = cell.getNumericCellValue(); + String s = String.valueOf(numericCellValue); + return s.replaceAll("\\.0$", ""); + } + default: + return cell.getStringCellValue(); + } + } +} diff --git a/src/main/resources/modules/SpringBoot/java/frame/excel/annotation/ColumnDescription.java b/src/main/resources/modules/SpringBoot/java/frame/excel/annotation/ColumnDescription.java new file mode 100644 index 00000000..882f7140 --- /dev/null +++ b/src/main/resources/modules/SpringBoot/java/frame/excel/annotation/ColumnDescription.java @@ -0,0 +1,17 @@ +package ${basePackage}.frame.excel.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 ColumnDescription { + String value() default ""; + +} diff --git a/src/main/resources/modules/SpringBoot/java/frame/excel/annotation/ColumnName.java b/src/main/resources/modules/SpringBoot/java/frame/excel/annotation/ColumnName.java new file mode 100644 index 00000000..c702d9e7 --- /dev/null +++ b/src/main/resources/modules/SpringBoot/java/frame/excel/annotation/ColumnName.java @@ -0,0 +1,31 @@ +package ${basePackage}.frame.excel.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 ColumnName { + String value(); + + /** + * 排序 + * + * @return + */ + int width() default 8; + + /** + * 日期格式化 + * + * @return + */ + String dateFormat() default "yyyy-MM-dd"; +} diff --git a/src/main/resources/modules/SpringBoot/java/frame/excel/annotation/Converter.java b/src/main/resources/modules/SpringBoot/java/frame/excel/annotation/Converter.java new file mode 100644 index 00000000..7b178ecf --- /dev/null +++ b/src/main/resources/modules/SpringBoot/java/frame/excel/annotation/Converter.java @@ -0,0 +1,16 @@ +package ${basePackage}.frame.excel.annotation; + +import java.lang.annotation.*; + +/** + * 优先通过target来获取转换器 + * + * @author 王兵 + * @version v0.0.1 + */ +@Target(ElementType.FIELD) +@Retention(RetentionPolicy.RUNTIME) +@Documented +public @interface Converter { + Class target(); +} diff --git a/src/main/resources/modules/SpringBoot/java/frame/excel/annotation/Ignore.java b/src/main/resources/modules/SpringBoot/java/frame/excel/annotation/Ignore.java new file mode 100644 index 00000000..b3ec0436 --- /dev/null +++ b/src/main/resources/modules/SpringBoot/java/frame/excel/annotation/Ignore.java @@ -0,0 +1,16 @@ +package ${basePackage}.frame.excel.annotation; + +import java.lang.annotation.*; + +/** + * 是否忽略表字段 + * + * @author 金洋 + * @since 2.1.0 + */ +@Target(ElementType.FIELD) +@Retention(RetentionPolicy.RUNTIME) +@Documented +public @interface Ignore { + boolean value() default true; +} diff --git a/src/main/resources/modules/SpringBoot/java/frame/excel/annotation/ParentFirst.java b/src/main/resources/modules/SpringBoot/java/frame/excel/annotation/ParentFirst.java new file mode 100644 index 00000000..d79cbc1f --- /dev/null +++ b/src/main/resources/modules/SpringBoot/java/frame/excel/annotation/ParentFirst.java @@ -0,0 +1,16 @@ +package ${basePackage}.frame.excel.annotation; + +import java.lang.annotation.*; + +/** + * 是否关注父类的字段 + * + * @author 金洋 + * @since 2.1.0 + */ +@Target(ElementType.TYPE) +@Retention(RetentionPolicy.RUNTIME) +@Documented +public @interface ParentFirst { + boolean value() default true; +} diff --git a/src/main/resources/modules/SpringBoot/java/frame/excel/annotation/SheetName.java b/src/main/resources/modules/SpringBoot/java/frame/excel/annotation/SheetName.java new file mode 100644 index 00000000..5e3c7cd3 --- /dev/null +++ b/src/main/resources/modules/SpringBoot/java/frame/excel/annotation/SheetName.java @@ -0,0 +1,19 @@ +package ${basePackage}.frame.excel.annotation; + +import java.lang.annotation.*; + +/** + * 为字段、方法或类注解名称。
+ * Created on 2014/9/24. + * + * @author + * @version v1.0.0.0 + */ +@Target({ElementType.TYPE}) +@Retention(RetentionPolicy.RUNTIME) +@Documented +public @interface SheetName { + String value(); + + boolean freezeFirst() default false; +} diff --git a/src/main/resources/modules/SpringBoot/java/frame/excel/converter/BooleanConverter.java b/src/main/resources/modules/SpringBoot/java/frame/excel/converter/BooleanConverter.java new file mode 100644 index 00000000..40f39163 --- /dev/null +++ b/src/main/resources/modules/SpringBoot/java/frame/excel/converter/BooleanConverter.java @@ -0,0 +1,21 @@ +package ${basePackage}.frame.excel.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/resources/modules/SpringBoot/java/frame/excel/converter/ByteConverter.java b/src/main/resources/modules/SpringBoot/java/frame/excel/converter/ByteConverter.java new file mode 100644 index 00000000..6ab92a74 --- /dev/null +++ b/src/main/resources/modules/SpringBoot/java/frame/excel/converter/ByteConverter.java @@ -0,0 +1,21 @@ +package ${basePackage}.frame.excel.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/resources/modules/SpringBoot/java/frame/excel/converter/CharacterConverter.java b/src/main/resources/modules/SpringBoot/java/frame/excel/converter/CharacterConverter.java new file mode 100644 index 00000000..55ff31e1 --- /dev/null +++ b/src/main/resources/modules/SpringBoot/java/frame/excel/converter/CharacterConverter.java @@ -0,0 +1,21 @@ +package ${basePackage}.frame.excel.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/resources/modules/SpringBoot/java/frame/excel/converter/Converter.java b/src/main/resources/modules/SpringBoot/java/frame/excel/converter/Converter.java new file mode 100644 index 00000000..ebf412b2 --- /dev/null +++ b/src/main/resources/modules/SpringBoot/java/frame/excel/converter/Converter.java @@ -0,0 +1,8 @@ +package ${basePackage}.frame.excel.converter; + +public interface Converter { + + T convert(String var); + + String string(T var); +} diff --git a/src/main/resources/modules/SpringBoot/java/frame/excel/converter/DateConverter.java b/src/main/resources/modules/SpringBoot/java/frame/excel/converter/DateConverter.java new file mode 100644 index 00000000..d2b2bf34 --- /dev/null +++ b/src/main/resources/modules/SpringBoot/java/frame/excel/converter/DateConverter.java @@ -0,0 +1,44 @@ +package ${basePackage}.frame.excel.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/resources/modules/SpringBoot/java/frame/excel/converter/DoubleConverter.java b/src/main/resources/modules/SpringBoot/java/frame/excel/converter/DoubleConverter.java new file mode 100644 index 00000000..5ddd0388 --- /dev/null +++ b/src/main/resources/modules/SpringBoot/java/frame/excel/converter/DoubleConverter.java @@ -0,0 +1,21 @@ +package ${basePackage}.frame.excel.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/resources/modules/SpringBoot/java/frame/excel/converter/FloatConverter.java b/src/main/resources/modules/SpringBoot/java/frame/excel/converter/FloatConverter.java new file mode 100644 index 00000000..43b2f89f --- /dev/null +++ b/src/main/resources/modules/SpringBoot/java/frame/excel/converter/FloatConverter.java @@ -0,0 +1,26 @@ +package ${basePackage}.frame.excel.converter; + +public class FloatConverter implements Converter { + + @Override + public Float convert(String var) { + try { + //增加对1.0一类的的优化显示 + if (var.matches("(\\d+)\\.0")) { + var = var.replaceAll("\\.0$", ""); + } + + 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/resources/modules/SpringBoot/java/frame/excel/converter/IntegerConverter.java b/src/main/resources/modules/SpringBoot/java/frame/excel/converter/IntegerConverter.java new file mode 100644 index 00000000..669c4b56 --- /dev/null +++ b/src/main/resources/modules/SpringBoot/java/frame/excel/converter/IntegerConverter.java @@ -0,0 +1,21 @@ +package ${basePackage}.frame.excel.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/resources/modules/SpringBoot/java/frame/excel/converter/LongConverter.java b/src/main/resources/modules/SpringBoot/java/frame/excel/converter/LongConverter.java new file mode 100644 index 00000000..d8ff31a3 --- /dev/null +++ b/src/main/resources/modules/SpringBoot/java/frame/excel/converter/LongConverter.java @@ -0,0 +1,34 @@ +package ${basePackage}.frame.excel.converter; + + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class LongConverter implements Converter { + + @Override + public Long convert(String var) { + try { + //增加对1.0一类的的兼容性 + if (var.matches("(\\d+)\\.(\\d*)")) { + Pattern compile = Pattern.compile("(\\d+)\\.(\\d*)"); + Matcher matcher = compile.matcher(var); + if (matcher.find()) { + var = matcher.group(1); + } + } + + 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/resources/modules/SpringBoot/java/frame/excel/converter/ShortConverter.java b/src/main/resources/modules/SpringBoot/java/frame/excel/converter/ShortConverter.java new file mode 100644 index 00000000..82589b1d --- /dev/null +++ b/src/main/resources/modules/SpringBoot/java/frame/excel/converter/ShortConverter.java @@ -0,0 +1,21 @@ +package ${basePackage}.frame.excel.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/resources/modules/SpringBoot/java/frame/excel/converter/StringConverter.java b/src/main/resources/modules/SpringBoot/java/frame/excel/converter/StringConverter.java new file mode 100644 index 00000000..fc349c8d --- /dev/null +++ b/src/main/resources/modules/SpringBoot/java/frame/excel/converter/StringConverter.java @@ -0,0 +1,17 @@ +package ${basePackage}.frame.excel.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/resources/modules/SpringBoot/java/frame/excel/style/BaseCellStyle.java b/src/main/resources/modules/SpringBoot/java/frame/excel/style/BaseCellStyle.java new file mode 100644 index 00000000..a8622c32 --- /dev/null +++ b/src/main/resources/modules/SpringBoot/java/frame/excel/style/BaseCellStyle.java @@ -0,0 +1,57 @@ +package ${basePackage}.frame.excel.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 BaseCellStyle { + /** + * 样式 + */ + protected CellStyle style; + + public BaseCellStyle(Workbook workbook) { + style = workbook.createCellStyle(); + style.setFillPattern(CellStyle.NO_FILL); + //下边框 + 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()); + + 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()); //上边框颜色 + } + + public CellStyle getStyle() { + return style; + } + + public void setStyle(CellStyle style) { + this.style = style; + } +} diff --git a/src/main/resources/modules/SpringBoot/java/frame/excel/style/BaseFont.java b/src/main/resources/modules/SpringBoot/java/frame/excel/style/BaseFont.java new file mode 100644 index 00000000..b8088906 --- /dev/null +++ b/src/main/resources/modules/SpringBoot/java/frame/excel/style/BaseFont.java @@ -0,0 +1,29 @@ +package ${basePackage}.frame.excel.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/resources/modules/SpringBoot/java/frame/excel/style/DataCellStyle.java b/src/main/resources/modules/SpringBoot/java/frame/excel/style/DataCellStyle.java new file mode 100644 index 00000000..0c4b5a04 --- /dev/null +++ b/src/main/resources/modules/SpringBoot/java/frame/excel/style/DataCellStyle.java @@ -0,0 +1,29 @@ +package ${basePackage}.frame.excel.style; + +import org.apache.poi.hssf.util.HSSFColor; +import org.apache.poi.ss.usermodel.CellStyle; +import org.apache.poi.ss.usermodel.Workbook; + +public class DataCellStyle extends BaseCellStyle { + + public DataCellStyle(Workbook workbook, short align, boolean error) { + super(workbook); + style.setAlignment(align); + if (error) { + style.setFillForegroundColor(HSSFColor.RED.index); //背景颜色红色 + style.setFillPattern(CellStyle.SOLID_FOREGROUND); //设置单元格填充样式 + } + } + + public DataCellStyle(Workbook workbook, short align) { + this(workbook, align, false); + } + + public DataCellStyle(Workbook workbook, boolean error) { + this(workbook, CellStyle.ALIGN_LEFT, error); + } + + public DataCellStyle(Workbook workbook) { + this(workbook, CellStyle.ALIGN_LEFT, false); + } +} diff --git a/src/main/resources/modules/SpringBoot/java/frame/excel/style/ErrorCellStyle.java b/src/main/resources/modules/SpringBoot/java/frame/excel/style/ErrorCellStyle.java new file mode 100644 index 00000000..2adbb695 --- /dev/null +++ b/src/main/resources/modules/SpringBoot/java/frame/excel/style/ErrorCellStyle.java @@ -0,0 +1,22 @@ +package ${basePackage}.frame.excel.style; + +import org.apache.poi.hssf.util.HSSFColor; +import org.apache.poi.ss.usermodel.CellStyle; +import org.apache.poi.ss.usermodel.Workbook; + +public class ErrorCellStyle extends BaseCellStyle { + + public ErrorCellStyle(Workbook workbook) { + super(workbook); + style.setFillForegroundColor(HSSFColor.RED.index); //背景颜色红色 + style.setFillPattern(CellStyle.SOLID_FOREGROUND); //设置单元格填充样式 + } + + public CellStyle getStyle() { + return style; + } + + public void setStyle(CellStyle style) { + this.style = style; + } +} diff --git a/src/main/resources/modules/SpringBoot/java/frame/excel/style/HeadCellStyle.java b/src/main/resources/modules/SpringBoot/java/frame/excel/style/HeadCellStyle.java new file mode 100644 index 00000000..f26d42f7 --- /dev/null +++ b/src/main/resources/modules/SpringBoot/java/frame/excel/style/HeadCellStyle.java @@ -0,0 +1,15 @@ +package ${basePackage}.frame.excel.style; + +import org.apache.poi.hssf.util.HSSFColor; +import org.apache.poi.ss.usermodel.CellStyle; +import org.apache.poi.ss.usermodel.Workbook; + +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);//上下居中 + } +} diff --git a/src/main/resources/modules/SpringBoot/java/frame/excel/style/NormalFont.java b/src/main/resources/modules/SpringBoot/java/frame/excel/style/NormalFont.java new file mode 100644 index 00000000..2b660e5a --- /dev/null +++ b/src/main/resources/modules/SpringBoot/java/frame/excel/style/NormalFont.java @@ -0,0 +1,18 @@ +package ${basePackage}.frame.excel.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/resources/modules/SpringBoot/java/frame/excel/style/RedFont.java b/src/main/resources/modules/SpringBoot/java/frame/excel/style/RedFont.java new file mode 100644 index 00000000..4c94717c --- /dev/null +++ b/src/main/resources/modules/SpringBoot/java/frame/excel/style/RedFont.java @@ -0,0 +1,18 @@ +package ${basePackage}.frame.excel.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/resources/modules/SpringBoot/java/frame/utils/ClassUtil.java b/src/main/resources/modules/SpringBoot/java/frame/utils/ClassUtil.java new file mode 100644 index 00000000..2b64d39f --- /dev/null +++ b/src/main/resources/modules/SpringBoot/java/frame/utils/ClassUtil.java @@ -0,0 +1,173 @@ +package xyz.wbsite.frame.utils; + + +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 { + + /** + * 获取模板类所有字段 + * + * @param clazz 模板对象 + * @param parentFirst 是否关注父类的字段 + * @return + */ + 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()); + } catch (Exception e) { + method = pojoClass.getMethod( + getMethodName.toString().replace("get", "is") + ); + } + 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(), 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; + } +} diff --git a/src/main/resources/modules/SpringBoot/java/frame/utils/StringUtil.java b/src/main/resources/modules/SpringBoot/java/frame/utils/StringUtil.java new file mode 100644 index 00000000..767dbe88 --- /dev/null +++ b/src/main/resources/modules/SpringBoot/java/frame/utils/StringUtil.java @@ -0,0 +1,87 @@ +package xyz.wbsite.frame.utils; + +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); + } + + 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) { + return !isEmpty(value); + } + + + /** + * 检查对象是否为数字型字符串,包含负数开头的。 + */ + 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 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(); + } +} diff --git a/src/main/resources/modules/SpringBoot/java/frame/utils/ValidationUtil.java b/src/main/resources/modules/SpringBoot/java/frame/utils/ValidationUtil.java index 5e9aac0c..58b09249 100644 --- a/src/main/resources/modules/SpringBoot/java/frame/utils/ValidationUtil.java +++ b/src/main/resources/modules/SpringBoot/java/frame/utils/ValidationUtil.java @@ -3,18 +3,14 @@ package ${basePackage}.frame.utils; import ${basePackage}.frame.base.BaseRequest; import ${basePackage}.frame.base.BaseResponse; import ${basePackage}.frame.base.ErrorType; + 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; /** * 验证工具类。提供一些通用简单的数据验证功能 @@ -51,4 +47,26 @@ public class ValidationUtil { } return response; } + + public static List validate(Object req) { + List validResult = new ArrayList<>(); + if (req == null) { + validResult.add("当前数据为空"); + return validResult; + } + + try { + Validator validator = factory.getValidator(); + Set> constraintViolations = validator.validate(req); + if (constraintViolations.size() > 0) { + for (ConstraintViolation violation : constraintViolations) { + validResult.add(violation.getMessage()); + } + } + } catch (Exception e) { + e.printStackTrace(); + validResult.add("数据检查错误"); + } + return validResult; + } } diff --git a/src/main/resources/modules/SpringBoot/pom.ftl b/src/main/resources/modules/SpringBoot/pom.ftl index 3919b4d4..7dfe17e5 100644 --- a/src/main/resources/modules/SpringBoot/pom.ftl +++ b/src/main/resources/modules/SpringBoot/pom.ftl @@ -27,6 +27,7 @@ 1.1.0 5.5.1 Greenwich.RC2 + 3.8 @@ -101,6 +102,11 @@ dozer + + org.apache.poi + poi-ooxml + + <#if dataBase == 'MYSQL'> mysql @@ -149,6 +155,11 @@ dozer ${r'${dozer-version}'} + + org.apache.poi + poi-ooxml + ${r'${poi-ooxml-version}'} + diff --git a/src/main/resources/modules/SpringBoot/resources/templates/screen/module/mgr.ftl b/src/main/resources/modules/SpringBoot/resources/templates/screen/module/mgr.ftl index bfd34303..9d55692f 100644 --- a/src/main/resources/modules/SpringBoot/resources/templates/screen/module/mgr.ftl +++ b/src/main/resources/modules/SpringBoot/resources/templates/screen/module/mgr.ftl @@ -41,8 +41,18 @@ - - + + + + + + + + + + + + @@ -93,12 +103,13 @@ diff --git a/src/main/resources/modules/SpringBoot/resources/templates/screen/module/system/dict.ftl b/src/main/resources/modules/SpringBoot/resources/templates/screen/module/system/dict.ftl index fac77938..d1c431ae 100644 --- a/src/main/resources/modules/SpringBoot/resources/templates/screen/module/system/dict.ftl +++ b/src/main/resources/modules/SpringBoot/resources/templates/screen/module/system/dict.ftl @@ -24,8 +24,8 @@ - 新增 - + 新增 + 导出 @@ -58,8 +58,18 @@ - - + + + + + + + + + + + + @@ -131,12 +141,13 @@ diff --git a/src/main/resources/modules/SpringBoot/resources/templates/screen/module/system/dictItem.ftl b/src/main/resources/modules/SpringBoot/resources/templates/screen/module/system/dictItem.ftl index 17e2d490..75297dc7 100644 --- a/src/main/resources/modules/SpringBoot/resources/templates/screen/module/system/dictItem.ftl +++ b/src/main/resources/modules/SpringBoot/resources/templates/screen/module/system/dictItem.ftl @@ -28,6 +28,7 @@ 新增 + 导出 @@ -55,8 +56,18 @@ - - + + + + + + + + + + + + @@ -126,11 +137,13 @@