From fe447605aaf0140e015a75f955131e9cd737c1eb Mon Sep 17 00:00:00 2001 From: wangbing Date: Tue, 25 Feb 2020 23:57:03 +0800 Subject: [PATCH] =?UTF-8?q?1=E3=80=81Excel=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Former-commit-id: 63f7c80d0a641e57e244f20c496690532176ba1e --- .../SpringBoot/java/frame/excel/WColumn.java | 13 ++- .../SpringBoot/java/frame/excel/WExcel.java | 89 ++++++++++--------- .../excel/annotation/ColumnDescription.java | 6 +- .../frame/excel/annotation/ColumnList.java | 25 ++++++ .../frame/excel/annotation/ColumnName.java | 6 +- .../frame/excel/annotation/Converter.java | 6 +- .../java/frame/excel/annotation/Ignore.java | 6 +- .../frame/excel/annotation/ParentFirst.java | 6 +- .../frame/excel/annotation/SheetName.java | 6 +- .../excel/converter/BooleanConverter.java | 4 +- .../frame/excel/style/SuccessCellStyle.java | 2 +- 11 files changed, 119 insertions(+), 50 deletions(-) create mode 100644 src/main/resources/modules/SpringBoot/java/frame/excel/annotation/ColumnList.java diff --git a/src/main/resources/modules/SpringBoot/java/frame/excel/WColumn.java b/src/main/resources/modules/SpringBoot/java/frame/excel/WColumn.java index 4e63dbf8..3a162cce 100644 --- a/src/main/resources/modules/SpringBoot/java/frame/excel/WColumn.java +++ b/src/main/resources/modules/SpringBoot/java/frame/excel/WColumn.java @@ -2,7 +2,6 @@ package ${basePackage}.frame.excel; import ${basePackage}.frame.excel.converter.Converter; -import ${basePackage}.frame.utils.StringUtil; import java.io.Serializable; import java.lang.reflect.Field; @@ -52,6 +51,10 @@ public class WColumn implements Serializable { * ExcelType */ private int cellType = 1; + /** + * 下拉列表 + */ + private String[] cellList; public WColumn() { this.name = ""; @@ -132,4 +135,12 @@ public class WColumn implements Serializable { public void setGetMethod(Method getMethod) { this.getMethod = getMethod; } + + public String[] getCellList() { + return cellList; + } + + public void setCellList(String[] cellList) { + this.cellList = cellList; + } } diff --git a/src/main/resources/modules/SpringBoot/java/frame/excel/WExcel.java b/src/main/resources/modules/SpringBoot/java/frame/excel/WExcel.java index eddae08c..e30cc91d 100644 --- a/src/main/resources/modules/SpringBoot/java/frame/excel/WExcel.java +++ b/src/main/resources/modules/SpringBoot/java/frame/excel/WExcel.java @@ -4,11 +4,16 @@ import org.apache.poi.hssf.usermodel.HSSFDateUtil; import org.apache.poi.hssf.usermodel.HSSFWorkbook; import org.apache.poi.ss.usermodel.Cell; import org.apache.poi.ss.usermodel.CellStyle; +import org.apache.poi.ss.usermodel.DataValidation; +import org.apache.poi.ss.usermodel.DataValidationConstraint; +import org.apache.poi.ss.usermodel.DataValidationHelper; 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.ss.util.CellRangeAddressList; import org.apache.poi.xssf.usermodel.XSSFClientAnchor; import org.apache.poi.xssf.usermodel.XSSFComment; +import org.apache.poi.xssf.usermodel.XSSFDataValidation; import org.apache.poi.xssf.usermodel.XSSFDrawing; import org.apache.poi.xssf.usermodel.XSSFRichTextString; import org.apache.poi.xssf.usermodel.XSSFSheet; @@ -36,7 +41,6 @@ import ${basePackage}.frame.excel.style.DataCellStyle; import ${basePackage}.frame.excel.style.ErrorCellStyle; import ${basePackage}.frame.excel.style.HeadCellStyle; import ${basePackage}.frame.excel.style.RedFont; -import ${basePackage}.frame.excel.style.SuccessCellStyle; import ${basePackage}.frame.utils.ClassUtil; import ${basePackage}.frame.utils.FileUtil; import ${basePackage}.frame.utils.LogUtil; @@ -59,7 +63,14 @@ import java.util.Date; import java.util.List; /** - * WExcel - Excel-Sheet对象,完整的数据集合对象。 + * WExcel - 抽象的Excel对象数据集合 + * + * 导出 + * new WExcel(Dept.class).loadData(depts).toFile(file);
+ * + * 导入 + * byte[] bytes = FileUtil.readFileToByteArray(new File("E:\\E.xlsx"));
+ * WExcel check = new WExcel(Dept.class).loadData(bytes); * * @author wangbing * @version 0.0.1 @@ -85,7 +96,7 @@ public class WExcel implements Serializable, Cloneable { /** * 表头的集合 */ - private List columnList = new ArrayList<>(); + private List<${basePackage}.frame.excel.WColumn> columnList = new ArrayList<>(); /** * 单元格里存放的对象 @@ -105,7 +116,7 @@ public class WExcel implements Serializable, Cloneable { * * @return WColumn集合 */ - private List initColumns(Class clazz) { + private List<${basePackage}.frame.excel.WColumn> initColumns(Class clazz) { //获取工作簿名称,没有则以类名为默认工作簿名称 if (clazz.isAnnotationPresent(SheetName.class)) { SheetName sheetName = clazz.getAnnotation(SheetName.class); @@ -123,7 +134,7 @@ public class WExcel implements Serializable, Cloneable { continue; } - WColumn WColumn = new WColumn(); + ${basePackage}.frame.excel.WColumn WColumn = new ${basePackage}.frame.excel.WColumn(); WColumn.setField(field); Method set = ClassUtil.setMethod(field.getName(), clazz, field.getType()); @@ -145,16 +156,18 @@ public class WExcel implements Serializable, Cloneable { if (field.isAnnotationPresent(ColumnDescription.class)) { WColumn.setDescription(field.getAnnotation(ColumnDescription.class).value()); } + //获取下拉列表 + if (field.isAnnotationPresent(${basePackage}.frame.excel.annotation.ColumnList.class)) { + WColumn.setCellList(field.getAnnotation(ColumnList.class).value()); + } //获取列类型 if (field.isAnnotationPresent(${basePackage}.frame.excel.annotation.Converter.class)) { - ${basePackage}.frame.excel.annotation.Converter converter = field.getAnnotation(${basePackage}.frame.excel.annotation.Converter.class); + Converter converter = field.getAnnotation(Converter.class); Class target = converter.target(); try { WColumn.setConverter((Converter) target.newInstance()); - } catch (InstantiationException e) { - e.printStackTrace(); - } catch (IllegalAccessException e) { + } catch (InstantiationException | IllegalAccessException e) { e.printStackTrace(); } } else { @@ -212,7 +225,7 @@ public class WExcel implements Serializable, Cloneable { if (list.size() > 0) { for (T t : list) { WRow row = new WRow(); - for (WColumn column : columnList) { + for (${basePackage}.frame.excel.WColumn column : columnList) { if (column == null) { continue; } @@ -232,7 +245,7 @@ public class WExcel implements Serializable, Cloneable { } // <2层检查>检查模板注解验证是否通过 row.addErrors(ValidationUtil.validate(t)); - // <3层检查>如果没有错误,则可以执行处理器进行逻辑处理 + // <3层检查>如果没有错误,则可以执行处理器进行业务处理 if (!row.hasError() && processor != null) { row.addErrors(processor.exec(t)); } @@ -313,10 +326,12 @@ public class WExcel implements Serializable, Cloneable { } } - int maxRowNumber = sheet.getLastRowNum(); //Excel文件的总行数 + //Excel文件的总行数 + int maxRowNumber = sheet.getLastRowNum(); // 逐行读取导入文件的数据 for (int i = 0; i < maxRowNumber; i++) { - Row inputRow = sheet.getRow(i + 1); //Excel中的一行数据,第0行为表头,所以要加1 + //Excel中的一行数据,第0行为表头,所以要加1 + Row inputRow = sheet.getRow(i + 1); WRow row = new WRow(); rowList.add(row); @@ -345,7 +360,7 @@ public class WExcel implements Serializable, Cloneable { row.addErrors(transferMap(row, t)); // <2层检查>检查模板注解验证是否通过 row.addErrors(ValidationUtil.validate(t)); - // <3层检查>如果没有错误,则可以执行处理器进行逻辑处理 + // <3层检查>如果没有错误,则可以执行处理器进行业务处理 if (!row.hasError() && processor != null) { row.addErrors(processor.exec(t)); } @@ -529,6 +544,25 @@ public class WExcel implements Serializable, Cloneable { firstCell.setCellValue(textString); firstCell.setCellStyle(new HeadCellStyle(workbook).getStyle()); sheet.setColumnWidth(j + offset, (4 + column.getCellWidth()) * 256); + + if (column.getCellList() != null){ + CellRangeAddressList cellRangeAddressList = new CellRangeAddressList(1, 65535, j, j); + DataValidationHelper helper = sheet.getDataValidationHelper(); + DataValidationConstraint constraint = helper.createExplicitListConstraint(column.getCellList()); + DataValidation dataValidation = helper.createValidation(constraint, cellRangeAddressList); + //处理Excel兼容性问题 + if (dataValidation instanceof XSSFDataValidation) { + dataValidation.setSuppressDropDownArrow(true); + dataValidation.setShowErrorBox(true); + } else { + dataValidation.setSuppressDropDownArrow(false); + } + + dataValidation.setEmptyCellAllowed(true); + dataValidation.setShowPromptBox(true); + dataValidation.createPromptBox("提示", "只能选择下拉框里面的数据"); + sheet.addValidationData(dataValidation); + } } // 冻结第一行 @@ -541,7 +575,7 @@ public class WExcel implements Serializable, Cloneable { WRow wRow = this.rowList.get(i); Row row = sheet.createRow(i + 1); - if(offset> 0) { + if (offset > 0) { if (this.rowList.get(i).hasError()) { // 添加结果 List errorList = wRow.getErrorList(); @@ -632,29 +666,4 @@ public class WExcel implements Serializable, Cloneable { fileOutputStream.write(getBytes()); fileOutputStream.close(); } - - public static void main(String[] args) throws IOException { - Dept dept = new Dept(); - dept.setDeptName("AAAAAA"); - ArrayList depts = new ArrayList(); - depts.add(dept); - File file = new File("E:\\E.xlsx"); - - // 导出模板 -// new WExcel(Dept.class).loadData(depts).toFile(file); - - // 检查excel文件是否符合导入 - byte[] bytes = FileUtil.readFileToByteArray(new File("E:\\E.xlsx")); - try { - WExcel check = new WExcel(Dept.class).loadData(bytes); - check.toFile(new File("E:\\E_err.xlsx")); - System.out.println(check.hasError()); - } catch (TemplateNotMatchException e) { - e.printStackTrace(); - } catch (ReadErrorException e) { - e.printStackTrace(); - } - - System.out.println(); - } } 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 index 8e3a99cd..2a1a7e3d 100644 --- a/src/main/resources/modules/SpringBoot/java/frame/excel/annotation/ColumnDescription.java +++ b/src/main/resources/modules/SpringBoot/java/frame/excel/annotation/ColumnDescription.java @@ -1,6 +1,10 @@ package ${basePackage}.frame.excel.annotation; -import java.lang.annotation.*; +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; /** * ColumnDescription - Excel列描述注解 diff --git a/src/main/resources/modules/SpringBoot/java/frame/excel/annotation/ColumnList.java b/src/main/resources/modules/SpringBoot/java/frame/excel/annotation/ColumnList.java new file mode 100644 index 00000000..dbe796fc --- /dev/null +++ b/src/main/resources/modules/SpringBoot/java/frame/excel/annotation/ColumnList.java @@ -0,0 +1,25 @@ +package ${basePackage}.frame.excel.annotation; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * ColumnList - 单元格下拉选项 + * + * @author wangbing + * @version 0.0.1 + * @since 2017-01-01 + */ +@Target({ElementType.FIELD}) +@Retention(RetentionPolicy.RUNTIME) +@Documented +public @interface ColumnList { + + /** + * 下拉列表 + */ + String[] value(); +} 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 index 0c295767..00db0ce4 100644 --- a/src/main/resources/modules/SpringBoot/java/frame/excel/annotation/ColumnName.java +++ b/src/main/resources/modules/SpringBoot/java/frame/excel/annotation/ColumnName.java @@ -1,6 +1,10 @@ package ${basePackage}.frame.excel.annotation; -import java.lang.annotation.*; +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; /** * ColumnName - Excel列名称注解,当Excel模板没有该注解则使用字段名作为列名称 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 index a27bdf88..ab472cc6 100644 --- a/src/main/resources/modules/SpringBoot/java/frame/excel/annotation/Converter.java +++ b/src/main/resources/modules/SpringBoot/java/frame/excel/annotation/Converter.java @@ -1,6 +1,10 @@ package ${basePackage}.frame.excel.annotation; -import java.lang.annotation.*; +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; /** * Converter - Excel列转化器注解 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 index 860ed9db..75327992 100644 --- a/src/main/resources/modules/SpringBoot/java/frame/excel/annotation/Ignore.java +++ b/src/main/resources/modules/SpringBoot/java/frame/excel/annotation/Ignore.java @@ -1,6 +1,10 @@ package ${basePackage}.frame.excel.annotation; -import java.lang.annotation.*; +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; /** * Ignore - Excel列忽略注解,在导入导出过程中不会对存在该注解的字典进行解析 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 index 44687688..999d38cd 100644 --- a/src/main/resources/modules/SpringBoot/java/frame/excel/annotation/ParentFirst.java +++ b/src/main/resources/modules/SpringBoot/java/frame/excel/annotation/ParentFirst.java @@ -1,6 +1,10 @@ package ${basePackage}.frame.excel.annotation; -import java.lang.annotation.*; +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; /** * ParentFirst - 是否读取父类的属性,默认否 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 index 0b857a2b..da262d75 100644 --- a/src/main/resources/modules/SpringBoot/java/frame/excel/annotation/SheetName.java +++ b/src/main/resources/modules/SpringBoot/java/frame/excel/annotation/SheetName.java @@ -1,6 +1,10 @@ package ${basePackage}.frame.excel.annotation; -import java.lang.annotation.*; +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; /** * SheetName - 工作表名称,当Excel模板没有该注解则使用Class类名作为工作表默认名称 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 index bc3e67e2..f24440ce 100644 --- a/src/main/resources/modules/SpringBoot/java/frame/excel/converter/BooleanConverter.java +++ b/src/main/resources/modules/SpringBoot/java/frame/excel/converter/BooleanConverter.java @@ -1,6 +1,6 @@ package ${basePackage}.frame.excel.converter; - import ${basePackage}.frame.excel.exception.ValueConverterException; +import ${basePackage}.frame.excel.exception.ValueConverterException; /** * BooleanConverter - Boolean转化器,重写了对象到String,String到对象的转化方式 @@ -41,6 +41,6 @@ public class BooleanConverter implements Converter { if (var == null) { return ""; } - return var ? "Y" : "N"; + return var ? return var ? "是" : "否"; } } \ No newline at end of file diff --git a/src/main/resources/modules/SpringBoot/java/frame/excel/style/SuccessCellStyle.java b/src/main/resources/modules/SpringBoot/java/frame/excel/style/SuccessCellStyle.java index 136c4744..54c1db4d 100644 --- a/src/main/resources/modules/SpringBoot/java/frame/excel/style/SuccessCellStyle.java +++ b/src/main/resources/modules/SpringBoot/java/frame/excel/style/SuccessCellStyle.java @@ -1,4 +1,4 @@ -package xyz.wbsite.frame.excel.style; +package ${basePackage}.frame.excel.style; import org.apache.poi.hssf.util.HSSFColor; import org.apache.poi.ss.usermodel.CellStyle;