Commit 1dbd344ecac56ded48a0ae85a34916b7c759cfac

Authored by “谢茂盛”
1 parent 0e7f5057

init: 47项目迁移

Showing 43 changed files with 4062 additions and 52 deletions
src/main/java/com/order/erp/common/constant/ServerResultCode.java
1   -package com.canrd.shop.common.constant;
  1 +package com.order.erp.common.constant;
2 2  
3 3  
4 4 import com.order.erp.common.exception.ErrorInfo;
... ...
src/main/java/com/order/erp/common/excel4j/ExcelUtils.java 0 → 100644
  1 +package com.order.erp.common.excel4j;
  2 +
  3 +import com.order.erp.common.excel4j.converter.DefaultConvertible;
  4 +import com.order.erp.common.excel4j.exceptions.Excel4JException;
  5 +import com.order.erp.common.excel4j.exceptions.Excel4jReadException;
  6 +import com.order.erp.common.excel4j.handler.ExcelHeader;
  7 +import com.order.erp.common.excel4j.handler.SheetTemplate;
  8 +import com.order.erp.common.excel4j.handler.SheetTemplateHandler;
  9 +import com.order.erp.common.excel4j.utils.Utils;
  10 +import com.order.erp.common.excel4j.wrapper.MapSheetWrapper;
  11 +import com.order.erp.common.excel4j.wrapper.NoTemplateSheetWrapper;
  12 +import com.order.erp.common.excel4j.wrapper.NormalSheetWrapper;
  13 +import com.order.erp.common.excel4j.wrapper.SimpleSheetWrapper;
  14 +import lombok.extern.slf4j.Slf4j;
  15 +import org.apache.commons.csv.CSVFormat;
  16 +import org.apache.commons.csv.CSVParser;
  17 +import org.apache.commons.csv.CSVPrinter;
  18 +import org.apache.commons.csv.CSVRecord;
  19 +import org.apache.poi.hssf.usermodel.HSSFWorkbook;
  20 +import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
  21 +import org.apache.poi.ss.usermodel.*;
  22 +import org.apache.poi.xssf.usermodel.XSSFWorkbook;
  23 +
  24 +import java.io.*;
  25 +import java.lang.reflect.Array;
  26 +import java.nio.charset.StandardCharsets;
  27 +import java.util.ArrayList;
  28 +import java.util.Collection;
  29 +import java.util.List;
  30 +import java.util.Map;
  31 +
  32 +/**
  33 + * Excel4J的主要操作工具类
  34 + * <p>
  35 + * 主要包含6大操作类型,并且每个类型都配有一个私有handler:<br>
  36 + * 1.读取Excel操作基于注解映射,handler为{@link ExcelUtils#readExcel2ObjectsHandler}<br>
  37 + * 2.读取Excel操作无映射,handler为{@link ExcelUtils#readExcel2ObjectsHandler}<br>
  38 + * 3.基于模板、注解导出Excel,handler为{@link ExcelUtils#exportExcelByModuleHandler}<br>
  39 + * 4.基于模板、注解导出Map数据,handler为{@link ExcelUtils#exportExcelByModuleHandler}<br>
  40 + * 5.无模板基于注解导出,handler为{@link ExcelUtils#exportExcelByMapHandler}<br>
  41 + * 6.无模板无注解导出,handler为{@link ExcelUtils#exportExcelBySimpleHandler}<br>
  42 + * 7.读取CSV操作基于注解,handler为{@link ExcelUtils#readCSVByMapHandler}
  43 + * 8.基于注解导出CSV, handler为{@link ExcelUtils#exportCSVByMapHandler}
  44 + * <p>
  45 + * 另外列举了部分常用的参数格式的方法(不同参数的排列组合实在是太多,没必要完全列出)
  46 + * 如遇没有自己需要的参数类型的方法,可通过最全的方法来自行变换<br>
  47 + * <p>
  48 + */
  49 +@Slf4j
  50 +public final class ExcelUtils {
  51 +
  52 + /**
  53 + * 单例模式
  54 + * 通过{@link ExcelUtils#getInstance()}获取对象实例
  55 + */
  56 + private static volatile ExcelUtils excelUtils;
  57 +
  58 + private ExcelUtils() {
  59 + }
  60 +
  61 + /**
  62 + * 双检锁保证单例
  63 + */
  64 + public static ExcelUtils getInstance() {
  65 + if (null == excelUtils) {
  66 + synchronized (ExcelUtils.class) {
  67 + if (null == excelUtils) {
  68 + excelUtils = new ExcelUtils();
  69 + }
  70 + }
  71 + }
  72 + return excelUtils;
  73 + }
  74 +
  75 + /*---------------------------------------1.读取Excel操作基于注解映射--------------------------------------------*/
  76 + /* 一. 操作流程 : */
  77 + /* 1) 读取表头信息,与给出的Class类注解匹配 */
  78 + /* 2) 读取表头下面的数据内容, 按行读取, 并映射至java对象 */
  79 + /* 二. 参数说明 */
  80 + /* *) excelPath => 目标Excel路径 */
  81 + /* *) InputStream => 目标Excel文件流 */
  82 + /* *) clazz => java映射对象 */
  83 + /* *) offsetLine => 开始读取行坐标(默认0) */
  84 + /* *) limitLine => 最大读取行数(默认表尾) */
  85 + /* *) sheetIndex => Sheet索引(默认0) */
  86 +
  87 + /**
  88 + * 读取Excel操作基于注解映射成绑定的java对象
  89 + *
  90 + * @param excelPath 待导出Excel的路径
  91 + * @param clazz 待绑定的类(绑定属性注解{@link})
  92 + * @param offsetLine Excel表头行(默认是0)
  93 + * @param limitLine 最大读取行数(默认表尾)
  94 + * @param sheetIndex Sheet索引(默认0)
  95 + * @param <T> 绑定的数据类
  96 + * @return 返回转换为设置绑定的java对象集合
  97 + * @throws Excel4JException 异常
  98 + * @throws IOException 异常
  99 + * @throws InvalidFormatException 异常
  100 + * @author Crab2Died
  101 + */
  102 + public <T> List<T> readExcel2Objects(String excelPath, Class<T> clazz, int offsetLine,
  103 + int limitLine, int sheetIndex)
  104 + throws Excel4JException, IOException, InvalidFormatException {
  105 +
  106 + try (Workbook workbook = WorkbookFactory.create(new FileInputStream(new File(excelPath)))) {
  107 + return readExcel2ObjectsHandler(workbook, clazz, offsetLine, limitLine, sheetIndex);
  108 + }
  109 + }
  110 +
  111 + /**
  112 + * 读取Excel操作基于注解映射成绑定的java对象
  113 + *
  114 + * @param is 待导出Excel的数据流
  115 + * @param clazz 待绑定的类(绑定属性注解{@link })
  116 + * @param offsetLine Excel表头行(默认是0)
  117 + * @param limitLine 最大读取行数(默认表尾)
  118 + * @param sheetIndex Sheet索引(默认0)
  119 + * @param <T> 绑定的数据类
  120 + * @return 返回转换为设置绑定的java对象集合
  121 + * @throws Excel4JException 异常
  122 + * @throws IOException 异常
  123 + * @throws InvalidFormatException 异常
  124 + * @author Crab2Died
  125 + */
  126 + public <T> List<T> readExcel2Objects(InputStream is, Class<T> clazz, int offsetLine,
  127 + int limitLine, int sheetIndex)
  128 + throws Excel4JException, IOException, InvalidFormatException {
  129 +
  130 + try (Workbook workbook = WorkbookFactory.create(is)) {
  131 + return readExcel2ObjectsHandler(workbook, clazz, offsetLine, limitLine, sheetIndex);
  132 + }
  133 + }
  134 +
  135 + /**
  136 + * 读取Excel操作基于注解映射成绑定的java对象
  137 + *
  138 + * @param excelPath 待导出Excel的路径
  139 + * @param clazz 待绑定的类(绑定属性注解{@link })
  140 + * @param offsetLine Excel表头行(默认是0)
  141 + * @param sheetIndex Sheet索引(默认0)
  142 + * @param <T> 绑定的数据类
  143 + * @return 返回转换为设置绑定的java对象集合
  144 + * @throws Excel4JException 异常
  145 + * @throws IOException 异常
  146 + * @throws InvalidFormatException 异常
  147 + * @author Crab2Died
  148 + */
  149 + public <T> List<T> readExcel2Objects(String excelPath, Class<T> clazz, int offsetLine, int sheetIndex)
  150 + throws Excel4JException, IOException, InvalidFormatException {
  151 + return readExcel2Objects(excelPath, clazz, offsetLine, Integer.MAX_VALUE, sheetIndex);
  152 + }
  153 +
  154 + /**
  155 + * 读取Excel操作基于注解映射成绑定的java对象
  156 + *
  157 + * @param excelPath 待导出Excel的路径
  158 + * @param clazz 待绑定的类(绑定属性注解{@link })
  159 + * @param sheetIndex Sheet索引(默认0)
  160 + * @param <T> 绑定的数据类
  161 + * @return 返回转换为设置绑定的java对象集合
  162 + * @throws Excel4JException 异常
  163 + * @throws IOException 异常
  164 + * @throws InvalidFormatException 异常
  165 + * @author Crab2Died
  166 + */
  167 + public <T> List<T> readExcel2Objects(String excelPath, Class<T> clazz, int sheetIndex)
  168 + throws Excel4JException, IOException, InvalidFormatException {
  169 + return readExcel2Objects(excelPath, clazz, 0, Integer.MAX_VALUE, sheetIndex);
  170 + }
  171 +
  172 + /**
  173 + * 读取Excel操作基于注解映射成绑定的java对象
  174 + *
  175 + * @param excelPath 待导出Excel的路径
  176 + * @param clazz 待绑定的类(绑定属性注解{@link })
  177 + * @param <T> 绑定的数据类
  178 + * @return 返回转换为设置绑定的java对象集合
  179 + * @throws Excel4JException 异常
  180 + * @throws IOException 异常
  181 + * @throws InvalidFormatException 异常
  182 + * @author Crab2Died
  183 + */
  184 + public <T> List<T> readExcel2Objects(String excelPath, Class<T> clazz)
  185 + throws Excel4JException, IOException, InvalidFormatException {
  186 + return readExcel2Objects(excelPath, clazz, 0, Integer.MAX_VALUE, 0);
  187 + }
  188 +
  189 + /**
  190 + * 读取Excel操作基于注解映射成绑定的java对象
  191 + *
  192 + * @param is 待导出Excel的数据流
  193 + * @param clazz 待绑定的类(绑定属性注解{@link })
  194 + * @param sheetIndex Sheet索引(默认0)
  195 + * @param <T> 绑定的数据类
  196 + * @return 返回转换为设置绑定的java对象集合
  197 + * @throws Excel4JException 异常
  198 + * @throws IOException 异常
  199 + * @throws InvalidFormatException 异常
  200 + * @author Crab2Died
  201 + */
  202 + public <T> List<T> readExcel2Objects(InputStream is, Class<T> clazz, int sheetIndex)
  203 + throws Excel4JException, IOException, InvalidFormatException {
  204 + return readExcel2Objects(is, clazz, 0, Integer.MAX_VALUE, sheetIndex);
  205 + }
  206 +
  207 + /**
  208 + * 读取Excel操作基于注解映射成绑定的java对象
  209 + *
  210 + * @param is 待导出Excel的数据流
  211 + * @param clazz 待绑定的类(绑定属性注解{@link })
  212 + * @param <T> 绑定的数据类
  213 + * @return 返回转换为设置绑定的java对象集合
  214 + * @throws Excel4JException 异常
  215 + * @throws IOException 异常
  216 + * @throws InvalidFormatException 异常
  217 + * @author Crab2Died
  218 + */
  219 + public <T> List<T> readExcel2Objects(InputStream is, Class<T> clazz)
  220 + throws Excel4JException, IOException, InvalidFormatException {
  221 + return readExcel2Objects(is, clazz, 0, Integer.MAX_VALUE, 0);
  222 + }
  223 +
  224 + private <T> List<T> readExcel2ObjectsHandler(Workbook workbook, Class<T> clazz, int offsetLine,
  225 + int limitLine, int sheetIndex)
  226 + throws Excel4JException {
  227 +
  228 + Sheet sheet = workbook.getSheetAt(sheetIndex);
  229 + Row row = sheet.getRow(offsetLine);
  230 + List<T> list = new ArrayList<>();
  231 + Map<Integer, ExcelHeader> maps = Utils.getHeaderMap(row, clazz);
  232 + if (maps == null || maps.size() <= 0) {
  233 + throw new Excel4jReadException(
  234 + "The Excel format to read is not correct, and check to see if the appropriate rows are set"
  235 + );
  236 + }
  237 + long maxLine = sheet.getLastRowNum() > ((long) offsetLine + limitLine) ?
  238 + ((long) offsetLine + limitLine) : sheet.getLastRowNum();
  239 +
  240 + for (int i = offsetLine + 1; i <= maxLine; i++) {
  241 + row = sheet.getRow(i);
  242 + if (null == row) {
  243 + continue;
  244 + }
  245 + T obj;
  246 + try {
  247 + obj = clazz.newInstance();
  248 + } catch (InstantiationException | IllegalAccessException e) {
  249 + throw new Excel4JException(e);
  250 + }
  251 + for (Cell cell : row) {
  252 + int ci = cell.getColumnIndex();
  253 + ExcelHeader header = maps.get(ci);
  254 + if (null == header) {
  255 + continue;
  256 + }
  257 + String val = Utils.getCellValue(cell);
  258 + Object value;
  259 + String filed = header.getFiled();
  260 + // 读取转换器
  261 + if (null != header.getReadConverter() &&
  262 + header.getReadConverter().getClass() != DefaultConvertible.class) {
  263 + value = header.getReadConverter().execRead(val);
  264 + } else {
  265 + // 默认转换
  266 + value = Utils.str2TargetClass(val, header.getFiledClazz());
  267 + }
  268 + Utils.copyProperty(obj, filed, value);
  269 + }
  270 + ExcelValidator.validateEntity(obj);
  271 +
  272 + list.add(obj);
  273 + }
  274 + return list;
  275 + }
  276 +
  277 + /*---------------------------------------2.读取Excel操作无映射-------------------------------------------------*/
  278 + /* 一. 操作流程 : */
  279 + /* *) 按行读取Excel文件,存储形式为 Cell->String => Row->List<Cell> => Excel->List<Row> */
  280 + /* 二. 参数说明 */
  281 + /* *) excelPath => 目标Excel路径 */
  282 + /* *) InputStream => 目标Excel文件流 */
  283 + /* *) offsetLine => 开始读取行坐标(默认0) */
  284 + /* *) limitLine => 最大读取行数(默认表尾) */
  285 + /* *) sheetIndex => Sheet索引(默认0) */
  286 +
  287 + /**
  288 + * 读取Excel表格数据,返回{@code List[List[String]]}类型的数据集合
  289 + *
  290 + * @param excelPath 待读取Excel的路径
  291 + * @param offsetLine Excel表头行(默认是0)
  292 + * @param limitLine 最大读取行数(默认表尾)
  293 + * @param sheetIndex Sheet索引(默认0)
  294 + * @return 返回{@code List<List<String>>}类型的数据集合
  295 + * @throws IOException 异常
  296 + * @throws InvalidFormatException 异常
  297 + * @author Crab2Died
  298 + */
  299 + public List<List<String>> readExcel2List(String excelPath, int offsetLine, int limitLine, int sheetIndex)
  300 + throws IOException, InvalidFormatException {
  301 +
  302 + try (Workbook workbook = WorkbookFactory.create(new FileInputStream(new File(excelPath)))) {
  303 + return readExcel2ObjectsHandler(workbook, offsetLine, limitLine, sheetIndex);
  304 + }
  305 + }
  306 +
  307 + /**
  308 + * 读取Excel表格数据,返回{@code List[List[String]]}类型的数据集合
  309 + *
  310 + * @param is 待读取Excel的数据流
  311 + * @param offsetLine Excel表头行(默认是0)
  312 + * @param limitLine 最大读取行数(默认表尾)
  313 + * @param sheetIndex Sheet索引(默认0)
  314 + * @return 返回{@code List<List<String>>}类型的数据集合
  315 + * @throws Excel4JException 异常
  316 + * @throws IOException 异常
  317 + * @throws InvalidFormatException 异常
  318 + * @author Crab2Died
  319 + */
  320 + public List<List<String>> readExcel2List(InputStream is, int offsetLine, int limitLine, int sheetIndex)
  321 + throws Excel4JException, IOException, InvalidFormatException {
  322 +
  323 + try (Workbook workbook = WorkbookFactory.create(is)) {
  324 + return readExcel2ObjectsHandler(workbook, offsetLine, limitLine, sheetIndex);
  325 + }
  326 + }
  327 +
  328 + /**
  329 + * 读取Excel表格数据,返回{@code List[List[String]]}类型的数据集合
  330 + *
  331 + * @param excelPath 待读取Excel的路径
  332 + * @param offsetLine Excel表头行(默认是0)
  333 + * @return 返回{@code List<List<String>>}类型的数据集合
  334 + * @throws IOException 异常
  335 + * @throws InvalidFormatException 异常
  336 + * @author Crab2Died
  337 + */
  338 + public List<List<String>> readExcel2List(String excelPath, int offsetLine)
  339 + throws IOException, InvalidFormatException {
  340 +
  341 + try (Workbook workbook = WorkbookFactory.create(new FileInputStream(new File(excelPath)))) {
  342 + return readExcel2ObjectsHandler(workbook, offsetLine, Integer.MAX_VALUE, 0);
  343 + }
  344 + }
  345 +
  346 + /**
  347 + * 读取Excel表格数据,返回{@code List[List[String]]}类型的数据集合
  348 + *
  349 + * @param is 待读取Excel的数据流
  350 + * @param offsetLine Excel表头行(默认是0)
  351 + * @return 返回{@code List<List<String>>}类型的数据集合
  352 + * @throws IOException 异常
  353 + * @throws InvalidFormatException 异常
  354 + * @author Crab2Died
  355 + */
  356 + public List<List<String>> readExcel2List(InputStream is, int offsetLine)
  357 + throws IOException, InvalidFormatException {
  358 +
  359 + try (Workbook workbook = WorkbookFactory.create(is)) {
  360 + return readExcel2ObjectsHandler(workbook, offsetLine, Integer.MAX_VALUE, 0);
  361 + }
  362 + }
  363 +
  364 + /**
  365 + * 读取Excel表格数据,返回{@code List[List[String]]}类型的数据集合
  366 + *
  367 + * @param excelPath 待读取Excel的路径
  368 + * @return 返回{@code List<List<String>>}类型的数据集合
  369 + * @throws IOException 异常
  370 + * @throws InvalidFormatException 异常
  371 + * @author Crab2Died
  372 + */
  373 + public List<List<String>> readExcel2List(String excelPath)
  374 + throws IOException, InvalidFormatException {
  375 +
  376 + try (Workbook workbook = WorkbookFactory.create(new FileInputStream(new File(excelPath)))) {
  377 + return readExcel2ObjectsHandler(workbook, 0, Integer.MAX_VALUE, 0);
  378 + }
  379 + }
  380 +
  381 + /**
  382 + * 读取Excel表格数据,返回{@code List[List[String]]}类型的数据集合
  383 + *
  384 + * @param is 待读取Excel的数据流
  385 + * @return 返回{@code List<List<String>>}类型的数据集合
  386 + * @throws IOException 异常
  387 + * @throws InvalidFormatException 异常
  388 + * @author Crab2Died
  389 + */
  390 + public List<List<String>> readExcel2List(InputStream is)
  391 + throws IOException, InvalidFormatException {
  392 +
  393 + try (Workbook workbook = WorkbookFactory.create(is)) {
  394 + return readExcel2ObjectsHandler(workbook, 0, Integer.MAX_VALUE, 0);
  395 + }
  396 + }
  397 +
  398 + private List<List<String>> readExcel2ObjectsHandler(Workbook workbook, int offsetLine,
  399 + int limitLine, int sheetIndex) {
  400 +
  401 + List<List<String>> list = new ArrayList<>();
  402 + Sheet sheet = workbook.getSheetAt(sheetIndex);
  403 + long maxLine = sheet.getLastRowNum() > ((long) offsetLine + limitLine) ?
  404 + ((long) offsetLine + limitLine) : sheet.getLastRowNum();
  405 + for (int i = offsetLine; i <= maxLine; i++) {
  406 + List<String> rows = new ArrayList<>();
  407 + Row row = sheet.getRow(i);
  408 + if (null == row) {
  409 + continue;
  410 + }
  411 + for (Cell cell : row) {
  412 + String val = Utils.getCellValue(cell);
  413 + rows.add(val);
  414 + }
  415 + list.add(rows);
  416 + }
  417 + return list;
  418 + }
  419 +
  420 +
  421 + /*-------------------------------------------3.基于模板、注解导出excel------------------------------------------*/
  422 + /* 一. 操作流程 : */
  423 + /* 1) 初始化模板 */
  424 + /* 2) 根据Java对象映射表头 */
  425 + /* 3) 写入数据内容 */
  426 + /* 二. 参数说明 */
  427 + /* *) templatePath => 模板路径 */
  428 + /* *) sheetIndex => Sheet索引(默认0) */
  429 + /* *) data => 导出内容List集合 */
  430 + /* *) extendMap => 扩展内容Map(具体就是key匹配替换模板#key内容) */
  431 + /* *) clazz => 映射对象Class */
  432 + /* *) isWriteHeader => 是否写入表头 */
  433 + /* *) targetPath => 导出文件路径 */
  434 + /* *) os => 导出文件流 */
  435 +
  436 + /**
  437 + * 基于Excel模板与注解{@link }导出Excel
  438 + *
  439 + * @param templatePath Excel模板路径
  440 + * @param sheetIndex 指定导出Excel的sheet索引号(默认为0)
  441 + * @param data 待导出数据的集合
  442 + * @param extendMap 扩展内容Map数据(具体就是key匹配替换模板#key内容,详情请查阅Excel模板定制方法)
  443 + * @param clazz 映射对象Class
  444 + * @param isWriteHeader 是否写表头
  445 + * @param targetPath 生成的Excel输出全路径
  446 + * @throws Excel4JException 异常
  447 + * @author Crab2Died
  448 + */
  449 + public void exportObjects2Excel(String templatePath, int sheetIndex, List<?> data,
  450 + Map<String, String> extendMap, Class clazz,
  451 + boolean isWriteHeader, String targetPath)
  452 + throws Excel4JException {
  453 +
  454 + try (SheetTemplate sheetTemplate = exportExcelByModuleHandler
  455 + (templatePath, sheetIndex, data, extendMap, clazz, isWriteHeader)) {
  456 + sheetTemplate.write2File(targetPath);
  457 + } catch (IOException e) {
  458 + throw new Excel4JException(e);
  459 + }
  460 + }
  461 +
  462 + /**
  463 + * 基于Excel模板与注解{@link }导出Excel
  464 + *
  465 + * @param templatePath Excel模板路径
  466 + * @param sheetIndex 指定导出Excel的sheet索引号(默认为0)
  467 + * @param data 待导出数据的集合
  468 + * @param extendMap 扩展内容Map数据(具体就是key匹配替换模板#key内容,详情请查阅Excel模板定制方法)
  469 + * @param clazz 映射对象Class
  470 + * @param isWriteHeader 是否写表头
  471 + * @param os 生成的Excel待输出数据流
  472 + * @throws Excel4JException 异常
  473 + * @author Crab2Died
  474 + */
  475 + public void exportObjects2Excel(String templatePath, int sheetIndex, List<?> data,
  476 + Map<String, String> extendMap, Class clazz,
  477 + boolean isWriteHeader, OutputStream os)
  478 + throws Excel4JException {
  479 +
  480 + try (SheetTemplate sheetTemplate = exportExcelByModuleHandler
  481 + (templatePath, sheetIndex, data, extendMap, clazz, isWriteHeader)) {
  482 + sheetTemplate.write2Stream(os);
  483 + } catch (IOException e) {
  484 + throw new Excel4JException(e);
  485 + }
  486 + }
  487 +
  488 + /**
  489 + * 基于Excel模板与注解{@link }导出Excel
  490 + *
  491 + * @param templatePath Excel模板路径
  492 + * @param data 待导出数据的集合
  493 + * @param extendMap 扩展内容Map数据(具体就是key匹配替换模板#key内容,详情请查阅Excel模板定制方法)
  494 + * @param clazz 映射对象Class
  495 + * @param isWriteHeader 是否写表头
  496 + * @param targetPath 生成的Excel输出全路径
  497 + * @throws Excel4JException 异常
  498 + * @author Crab2Died
  499 + */
  500 + public void exportObjects2Excel(String templatePath, List<?> data, Map<String, String> extendMap,
  501 + Class clazz, boolean isWriteHeader, String targetPath)
  502 + throws Excel4JException {
  503 +
  504 + exportObjects2Excel(templatePath, 0, data, extendMap, clazz, isWriteHeader, targetPath);
  505 + }
  506 +
  507 + /**
  508 + * 基于Excel模板与注解{@link }导出Excel
  509 + *
  510 + * @param templatePath Excel模板路径
  511 + * @param data 待导出数据的集合
  512 + * @param extendMap 扩展内容Map数据(具体就是key匹配替换模板#key内容,详情请查阅Excel模板定制方法)
  513 + * @param clazz 映射对象Class
  514 + * @param isWriteHeader 是否写表头
  515 + * @param os 生成的Excel待输出数据流
  516 + * @throws Excel4JException 异常
  517 + * @author Crab2Died
  518 + */
  519 + public void exportObjects2Excel(String templatePath, List<?> data, Map<String, String> extendMap,
  520 + Class clazz, boolean isWriteHeader, OutputStream os)
  521 + throws Excel4JException {
  522 +
  523 + exportObjects2Excel(templatePath, 0, data, extendMap, clazz, isWriteHeader, os);
  524 + }
  525 +
  526 + /**
  527 + * 基于Excel模板与注解{@link }导出Excel
  528 + *
  529 + * @param templatePath Excel模板路径
  530 + * @param data 待导出数据的集合
  531 + * @param extendMap 扩展内容Map数据(具体就是key匹配替换模板#key内容,详情请查阅Excel模板定制方法)
  532 + * @param clazz 映射对象Class
  533 + * @param targetPath 生成的Excel输出全路径
  534 + * @throws Excel4JException 异常
  535 + * @author Crab2Died
  536 + */
  537 + public void exportObjects2Excel(String templatePath, List<?> data, Map<String, String> extendMap,
  538 + Class clazz, String targetPath)
  539 + throws Excel4JException {
  540 +
  541 + exportObjects2Excel(templatePath, 0, data, extendMap, clazz, true, targetPath);
  542 + }
  543 +
  544 + /**
  545 + * 基于Excel模板与注解{@link }导出Excel
  546 + *
  547 + * @param templatePath Excel模板路径
  548 + * @param data 待导出数据的集合
  549 + * @param extendMap 扩展内容Map数据(具体就是key匹配替换模板#key内容,详情请查阅Excel模板定制方法)
  550 + * @param clazz 映射对象Class
  551 + * @param os 生成的Excel待输出数据流
  552 + * @throws Excel4JException 异常
  553 + * @author Crab2Died
  554 + */
  555 + public void exportObjects2Excel(String templatePath, List<?> data, Map<String, String> extendMap,
  556 + Class clazz, OutputStream os)
  557 + throws Excel4JException {
  558 +
  559 + exportObjects2Excel(templatePath, 0, data, extendMap, clazz, true, os);
  560 + }
  561 +
  562 + /**
  563 + * 基于Excel模板与注解{@link }导出Excel
  564 + *
  565 + * @param templatePath Excel模板路径
  566 + * @param data 待导出数据的集合
  567 + * @param clazz 映射对象Class
  568 + * @param targetPath 生成的Excel输出全路径
  569 + * @throws Excel4JException 异常
  570 + * @author Crab2Died
  571 + */
  572 + public void exportObjects2Excel(String templatePath, List<?> data, Class clazz, String targetPath)
  573 + throws Excel4JException {
  574 +
  575 + exportObjects2Excel(templatePath, 0, data, null, clazz, true, targetPath);
  576 + }
  577 +
  578 + /**
  579 + * 基于Excel模板与注解{@link }导出Excel
  580 + *
  581 + * @param templatePath Excel模板路径
  582 + * @param data 待导出数据的集合
  583 + * @param clazz 映射对象Class
  584 + * @param os 生成的Excel待输出数据流
  585 + * @throws Excel4JException 异常
  586 + * @author Crab2Died
  587 + */
  588 + public void exportObjects2Excel(String templatePath, List<?> data, Class clazz, OutputStream os)
  589 + throws Excel4JException {
  590 +
  591 + exportObjects2Excel(templatePath, 0, data, null, clazz, true, os);
  592 + }
  593 +
  594 + // 单sheet导出
  595 + private SheetTemplate exportExcelByModuleHandler(String templatePath,
  596 + int sheetIndex,
  597 + List<?> data,
  598 + Map<String, String> extendMap,
  599 + Class clazz,
  600 + boolean isWriteHeader)
  601 + throws Excel4JException {
  602 +
  603 + SheetTemplate template = SheetTemplateHandler.sheetTemplateBuilder(templatePath);
  604 + generateSheet(sheetIndex, data, extendMap, clazz, isWriteHeader, template);
  605 + return template;
  606 + }
  607 +
  608 + /**
  609 + * 基于Excel模板与注解{@link }导出多sheet的Excel
  610 + *
  611 + * @param sheetWrappers sheet包装类
  612 + * @param templatePath Excel模板路径
  613 + * @param targetPath 导出Excel文件路径
  614 + * @throws Excel4JException 异常
  615 + */
  616 + public void normalSheet2Excel(List<NormalSheetWrapper> sheetWrappers, String templatePath, String targetPath)
  617 + throws Excel4JException {
  618 +
  619 + try (SheetTemplate sheetTemplate = exportExcelByModuleHandler(templatePath, sheetWrappers)) {
  620 + sheetTemplate.write2File(targetPath);
  621 + } catch (IOException e) {
  622 + throw new Excel4JException(e);
  623 + }
  624 + }
  625 +
  626 + /**
  627 + * 基于Excel模板与注解{@link }导出多sheet的Excel
  628 + *
  629 + * @param sheetWrappers sheet包装类
  630 + * @param templatePath Excel模板路径
  631 + * @param os 生成的Excel待输出数据流
  632 + * @throws Excel4JException 异常
  633 + */
  634 + public void normalSheet2Excel(List<NormalSheetWrapper> sheetWrappers, String templatePath, OutputStream os)
  635 + throws Excel4JException {
  636 +
  637 + try (SheetTemplate sheetTemplate = exportExcelByModuleHandler(templatePath, sheetWrappers)) {
  638 + sheetTemplate.write2Stream(os);
  639 + } catch (IOException e) {
  640 + throw new Excel4JException(e);
  641 + }
  642 + }
  643 +
  644 + // 多sheet导出
  645 + private SheetTemplate exportExcelByModuleHandler(String templatePath,
  646 + List<NormalSheetWrapper> sheets)
  647 + throws Excel4JException {
  648 +
  649 + SheetTemplate template = SheetTemplateHandler.sheetTemplateBuilder(templatePath);
  650 + for (NormalSheetWrapper sheet : sheets) {
  651 + generateSheet(sheet.getSheetIndex(), sheet.getData(), sheet.getExtendMap(), sheet.getClazz(),
  652 + sheet.isWriteHeader(), template);
  653 + }
  654 + return template;
  655 + }
  656 +
  657 + // 生成sheet数据
  658 + private void generateSheet(int sheetIndex, List<?> data, Map<String, String> extendMap, Class clazz,
  659 + boolean isWriteHeader, SheetTemplate template)
  660 + throws Excel4JException {
  661 +
  662 + SheetTemplateHandler.loadTemplate(template, sheetIndex);
  663 + SheetTemplateHandler.extendData(template, extendMap);
  664 + List<ExcelHeader> headers = Utils.getHeaderList(clazz);
  665 + if (isWriteHeader) {
  666 + // 写标题
  667 + SheetTemplateHandler.createNewRow(template);
  668 + for (ExcelHeader header : headers) {
  669 + SheetTemplateHandler.createCell(template, header.getTitle(), null);
  670 + }
  671 + }
  672 +
  673 + for (Object object : data) {
  674 + SheetTemplateHandler.createNewRow(template);
  675 + SheetTemplateHandler.insertSerial(template, null);
  676 + for (ExcelHeader header : headers) {
  677 + SheetTemplateHandler.createCell(template, Utils.getProperty(object, header.getFiled(),
  678 + header.getWriteConverter()), null);
  679 + }
  680 + }
  681 + }
  682 +
  683 +
  684 + /*-------------------------------------4.基于模板、注解导出Map数据----------------------------------------------*/
  685 + /* 一. 操作流程 : */
  686 + /* 1) 初始化模板 */
  687 + /* 2) 根据Java对象映射表头 */
  688 + /* 3) 写入数据内容 */
  689 + /* 二. 参数说明 */
  690 + /* *) templatePath => 模板路径 */
  691 + /* *) sheetIndex => Sheet索引(默认0) */
  692 + /* *) data => 导出内容Map集合 */
  693 + /* *) extendMap => 扩展内容Map(具体就是key匹配替换模板#key内容) */
  694 + /* *) clazz => 映射对象Class */
  695 + /* *) isWriteHeader => 是否写入表头 */
  696 + /* *) targetPath => 导出文件路径 */
  697 + /* *) os => 导出文件流 */
  698 +
  699 + /**
  700 + * 基于模板、注解导出{@code Map[String, List[?]]}类型数据
  701 + * 模板定制详见定制说明
  702 + *
  703 + * @param templatePath Excel模板路径
  704 + * @param sheetIndex 指定导出Excel的sheet索引号(默认为0)
  705 + * @param data 待导出的{@code Map<String, List<?>>}类型数据
  706 + * @param extendMap 扩展内容Map数据(具体就是key匹配替换模板#key内容,详情请查阅Excel模板定制方法)
  707 + * @param clazz 映射对象Class
  708 + * @param isWriteHeader 是否写入表头
  709 + * @param targetPath 生成的Excel输出全路径
  710 + * @throws Excel4JException 异常
  711 + * @author Crab2Died
  712 + */
  713 + public void exportMap2Excel(String templatePath, int sheetIndex, Map<String, List<?>> data,
  714 + Map<String, String> extendMap, Class clazz,
  715 + boolean isWriteHeader, String targetPath)
  716 + throws Excel4JException {
  717 +
  718 + try (SheetTemplate sheetTemplate = exportExcelByMapHandler(templatePath, sheetIndex, data, extendMap, clazz,
  719 + isWriteHeader)) {
  720 + sheetTemplate.write2File(targetPath);
  721 + } catch (IOException e) {
  722 + throw new Excel4JException(e);
  723 + }
  724 + }
  725 +
  726 + /**
  727 + * 基于模板、注解导出{@code Map[String, List[?]]}类型数据
  728 + * 模板定制详见定制说明
  729 + *
  730 + * @param templatePath Excel模板路径
  731 + * @param sheetIndex 指定导出Excel的sheet索引号(默认为0)
  732 + * @param data 待导出的{@code Map<String, List<?>>}类型数据
  733 + * @param extendMap 扩展内容Map数据(具体就是key匹配替换模板#key内容,详情请查阅Excel模板定制方法)
  734 + * @param clazz 映射对象Class
  735 + * @param isWriteHeader 是否写入表头
  736 + * @param os 生成的Excel待输出数据流
  737 + * @throws Excel4JException 异常
  738 + * @author Crab2Died
  739 + */
  740 + public void exportMap2Excel(String templatePath, int sheetIndex, Map<String, List<?>> data,
  741 + Map<String, String> extendMap, Class clazz, boolean isWriteHeader, OutputStream os)
  742 + throws Excel4JException {
  743 +
  744 + try (SheetTemplate sheetTemplate = exportExcelByMapHandler(templatePath, sheetIndex, data, extendMap, clazz,
  745 + isWriteHeader)) {
  746 + sheetTemplate.write2Stream(os);
  747 + } catch (IOException e) {
  748 + throw new Excel4JException(e);
  749 + }
  750 + }
  751 +
  752 + /**
  753 + * 基于模板、注解导出{@code Map[String, List[?]]}类型数据
  754 + * 模板定制详见定制说明
  755 + *
  756 + * @param templatePath Excel模板路径
  757 + * @param data 待导出的{@code Map<String, List<?>>}类型数据
  758 + * @param extendMap 扩展内容Map数据(具体就是key匹配替换模板#key内容,详情请查阅Excel模板定制方法)
  759 + * @param clazz 映射对象Class
  760 + * @param targetPath 生成的Excel输出全路径
  761 + * @throws Excel4JException 异常
  762 + * @author Crab2Died
  763 + */
  764 + public void exportMap2Excel(String templatePath, Map<String, List<?>> data,
  765 + Map<String, String> extendMap, Class clazz, String targetPath)
  766 + throws Excel4JException {
  767 +
  768 + try (SheetTemplate sheetTemplate = exportExcelByMapHandler(templatePath, 0, data, extendMap, clazz, true)) {
  769 + sheetTemplate.write2File(targetPath);
  770 + } catch (IOException e) {
  771 + throw new Excel4JException(e);
  772 + }
  773 + }
  774 +
  775 + /**
  776 + * 基于模板、注解导出{@code Map[String, List[?]]}类型数据
  777 + * 模板定制详见定制说明
  778 + *
  779 + * @param templatePath Excel模板路径
  780 + * @param data 待导出的{@code Map<String, List<?>>}类型数据
  781 + * @param extendMap 扩展内容Map数据(具体就是key匹配替换模板#key内容,详情请查阅Excel模板定制方法)
  782 + * @param clazz 映射对象Class
  783 + * @param os 生成的Excel待输出数据流
  784 + * @throws Excel4JException 异常
  785 + * @author Crab2Died
  786 + */
  787 + public void exportMap2Excel(String templatePath, Map<String, List<?>> data,
  788 + Map<String, String> extendMap, Class clazz, OutputStream os)
  789 + throws Excel4JException {
  790 +
  791 + try (SheetTemplate sheetTemplate = exportExcelByMapHandler(templatePath, 0, data, extendMap, clazz, true)) {
  792 + sheetTemplate.write2Stream(os);
  793 + } catch (IOException e) {
  794 + throw new Excel4JException(e);
  795 + }
  796 + }
  797 +
  798 + /**
  799 + * 基于模板、注解导出{@code Map[String, List[?]]}类型数据
  800 + * 模板定制详见定制说明
  801 + *
  802 + * @param templatePath Excel模板路径
  803 + * @param data 待导出的{@code Map<String, List<?>>}类型数据
  804 + * @param clazz 映射对象Class
  805 + * @param targetPath 生成的Excel输出全路径
  806 + * @throws Excel4JException 异常
  807 + * @author Crab2Died
  808 + */
  809 + public void exportMap2Excel(String templatePath, Map<String, List<?>> data,
  810 + Class clazz, String targetPath)
  811 + throws Excel4JException {
  812 +
  813 + try (SheetTemplate sheetTemplate = exportExcelByMapHandler(templatePath, 0, data, null, clazz, true)) {
  814 + sheetTemplate.write2File(targetPath);
  815 + } catch (IOException e) {
  816 + throw new Excel4JException(e);
  817 + }
  818 + }
  819 +
  820 + /**
  821 + * 基于模板、注解导出{@code Map[String, List[?]]}类型数据
  822 + * 模板定制详见定制说明
  823 + *
  824 + * @param templatePath Excel模板路径
  825 + * @param data 待导出的{@code Map<String, List<?>>}类型数据
  826 + * @param clazz 映射对象Class
  827 + * @param os 生成的Excel待输出数据流
  828 + * @throws Excel4JException 异常
  829 + * @author Crab2Died
  830 + */
  831 + public void exportMap2Excel(String templatePath, Map<String, List<?>> data,
  832 + Class clazz, OutputStream os)
  833 + throws Excel4JException {
  834 +
  835 + try (SheetTemplate sheetTemplate = exportExcelByMapHandler(templatePath, 0, data, null, clazz, true)) {
  836 + sheetTemplate.write2Stream(os);
  837 + } catch (IOException e) {
  838 + throw new Excel4JException(e);
  839 + }
  840 + }
  841 +
  842 + // 单sheet导出
  843 + private SheetTemplate exportExcelByMapHandler(String templatePath,
  844 + int sheetIndex,
  845 + Map<String, List<?>> data,
  846 + Map<String, String> extendMap,
  847 + Class clazz,
  848 + boolean isWriteHeader)
  849 + throws Excel4JException {
  850 +
  851 + // 加载模板
  852 + SheetTemplate template = SheetTemplateHandler.sheetTemplateBuilder(templatePath);
  853 +
  854 + // 生成sheet
  855 + generateSheet(template, sheetIndex, data, extendMap, clazz, isWriteHeader);
  856 +
  857 + return template;
  858 + }
  859 +
  860 + /**
  861 + * 基于模板、注解的多sheet导出{@code Map[String, List[?]]}类型数据
  862 + * 模板定制详见定制说明
  863 + *
  864 + * @param sheetWrappers sheet包装类
  865 + * @param templatePath Excel模板
  866 + * @param targetPath 导出Excel路径
  867 + * @throws Excel4JException 异常
  868 + */
  869 + public void mapSheet2Excel(List<MapSheetWrapper> sheetWrappers, String templatePath, String targetPath)
  870 + throws Excel4JException {
  871 +
  872 + try (SheetTemplate sheetTemplate = exportExcelByMapHandler(sheetWrappers, templatePath)) {
  873 + sheetTemplate.write2File(targetPath);
  874 + } catch (IOException e) {
  875 + throw new Excel4JException(e);
  876 + }
  877 + }
  878 +
  879 + /**
  880 + * 基于模板、注解的多sheet导出{@code Map[String, List[?]]}类型数据
  881 + * 模板定制详见定制说明
  882 + *
  883 + * @param sheetWrappers sheet包装类
  884 + * @param templatePath Excel模板
  885 + * @param os 输出流
  886 + * @throws Excel4JException 异常
  887 + */
  888 + public void mapSheet2Excel(List<MapSheetWrapper> sheetWrappers, String templatePath, OutputStream os)
  889 + throws Excel4JException {
  890 +
  891 + try (SheetTemplate sheetTemplate = exportExcelByMapHandler(sheetWrappers, templatePath)) {
  892 + sheetTemplate.write2Stream(os);
  893 + } catch (IOException e) {
  894 + throw new Excel4JException(e);
  895 + }
  896 + }
  897 +
  898 + // 多sheet导出
  899 + private SheetTemplate exportExcelByMapHandler(List<MapSheetWrapper> sheetWrappers,
  900 + String templatePath)
  901 + throws Excel4JException {
  902 +
  903 + // 加载模板
  904 + SheetTemplate template = SheetTemplateHandler.sheetTemplateBuilder(templatePath);
  905 +
  906 + // 多sheet生成
  907 + for (MapSheetWrapper sheet : sheetWrappers) {
  908 + generateSheet(template,
  909 + sheet.getSheetIndex(),
  910 + sheet.getData(),
  911 + sheet.getExtendMap(),
  912 + sheet.getClazz(),
  913 + sheet.isWriteHeader()
  914 + );
  915 + }
  916 +
  917 + return template;
  918 + }
  919 +
  920 + // sheet生成
  921 + private void generateSheet(SheetTemplate template, int sheetIndex,
  922 + Map<String, List<?>> data, Map<String, String> extendMap,
  923 + Class clazz, boolean isWriteHeader)
  924 + throws Excel4JException {
  925 +
  926 + SheetTemplateHandler.loadTemplate(template, sheetIndex);
  927 + SheetTemplateHandler.extendData(template, extendMap);
  928 + List<ExcelHeader> headers = Utils.getHeaderList(clazz);
  929 + if (isWriteHeader) {
  930 + // 写标题
  931 + SheetTemplateHandler.createNewRow(template);
  932 + for (ExcelHeader header : headers) {
  933 + SheetTemplateHandler.createCell(template, header.getTitle(), null);
  934 + }
  935 + }
  936 + for (Map.Entry<String, List<?>> entry : data.entrySet()) {
  937 + for (Object object : entry.getValue()) {
  938 + SheetTemplateHandler.createNewRow(template);
  939 + SheetTemplateHandler.insertSerial(template, entry.getKey());
  940 + for (ExcelHeader header : headers) {
  941 + SheetTemplateHandler.createCell(template,
  942 + Utils.getProperty(object, header.getFiled(), header.getWriteConverter()),
  943 + entry.getKey()
  944 + );
  945 + }
  946 + }
  947 + }
  948 + }
  949 +
  950 +
  951 + /*--------------------------------------5.无模板基于注解导出---------------------------------------------------*/
  952 + /* 一. 操作流程 : */
  953 + /* 1) 根据Java对象映射表头 */
  954 + /* 2) 写入数据内容 */
  955 + /* 二. 参数说明 */
  956 + /* *) data => 导出内容List集合 */
  957 + /* *) isWriteHeader => 是否写入表头 */
  958 + /* *) sheetName => Sheet索引名(默认0) */
  959 + /* *) clazz => 映射对象Class */
  960 + /* *) isXSSF => 是否Excel2007及以上版本 */
  961 + /* *) targetPath => 导出文件路径 */
  962 + /* *) os => 导出文件流 */
  963 +
  964 + /**
  965 + * 无模板、基于注解的数据导出
  966 + *
  967 + * @param data 待导出数据
  968 + * @param clazz {@link }映射对象Class
  969 + * @param isWriteHeader 是否写入表头
  970 + * @param sheetName 指定导出Excel的sheet名称
  971 + * @param isXSSF 导出的Excel是否为Excel2007及以上版本(默认是)
  972 + * @param targetPath 生成的Excel输出全路径
  973 + * @throws Excel4JException 异常
  974 + * @throws IOException 异常
  975 + * @author Crab2Died
  976 + */
  977 + public void exportObjects2Excel(List<?> data, Class clazz, boolean isWriteHeader,
  978 + String sheetName, boolean isXSSF, String targetPath)
  979 + throws Excel4JException, IOException {
  980 +
  981 + try (FileOutputStream fos = new FileOutputStream(targetPath);
  982 + Workbook workbook = exportExcelNoTemplateHandler(data, clazz, isWriteHeader, sheetName, isXSSF)) {
  983 + workbook.write(fos);
  984 + }
  985 + }
  986 +
  987 + /**
  988 + * 无模板、基于注解的数据导出
  989 + *
  990 + * @param data 待导出数据
  991 + * @param clazz {@link }映射对象Class
  992 + * @param isWriteHeader 是否写入表头
  993 + * @param sheetName 指定导出Excel的sheet名称
  994 + * @param isXSSF 导出的Excel是否为Excel2007及以上版本(默认是)
  995 + * @param os 生成的Excel待输出数据流
  996 + * @throws Excel4JException 异常
  997 + * @throws IOException 异常
  998 + * @author Crab2Died
  999 + */
  1000 + public void exportObjects2Excel(List<?> data, Class clazz, boolean isWriteHeader,
  1001 + String sheetName, boolean isXSSF, OutputStream os)
  1002 + throws Excel4JException, IOException {
  1003 +
  1004 + try (Workbook workbook = exportExcelNoTemplateHandler(data, clazz, isWriteHeader, sheetName, isXSSF)) {
  1005 + workbook.write(os);
  1006 + }
  1007 + }
  1008 +
  1009 + /**
  1010 + * 无模板、基于注解的数据导出
  1011 + *
  1012 + * @param data 待导出数据
  1013 + * @param clazz {@link }映射对象Class
  1014 + * @param isWriteHeader 是否写入表头
  1015 + * @param targetPath 生成的Excel输出全路径
  1016 + * @throws Excel4JException 异常
  1017 + * @throws IOException 异常
  1018 + * @author Crab2Died
  1019 + */
  1020 + public void exportObjects2Excel(List<?> data, Class clazz, boolean isWriteHeader, String targetPath)
  1021 + throws Excel4JException, IOException {
  1022 +
  1023 + try (FileOutputStream fos = new FileOutputStream(targetPath);
  1024 + Workbook workbook = exportExcelNoTemplateHandler(data, clazz, isWriteHeader, null, true)) {
  1025 + workbook.write(fos);
  1026 + }
  1027 + }
  1028 +
  1029 + /**
  1030 + * 无模板、基于注解的数据导出
  1031 + *
  1032 + * @param data 待导出数据
  1033 + * @param clazz {@link }映射对象Class
  1034 + * @param isWriteHeader 是否写入表头
  1035 + * @param os 生成的Excel待输出数据流
  1036 + * @throws Excel4JException 异常
  1037 + * @throws IOException 异常
  1038 + * @author Crab2Died
  1039 + */
  1040 + public void exportObjects2Excel(List<?> data, Class clazz, boolean isWriteHeader, OutputStream os)
  1041 + throws Excel4JException, IOException {
  1042 +
  1043 + try (Workbook workbook = exportExcelNoTemplateHandler(data, clazz, isWriteHeader, null, true)) {
  1044 + workbook.write(os);
  1045 + }
  1046 + }
  1047 +
  1048 + /**
  1049 + * 无模板、基于注解的数据导出
  1050 + *
  1051 + * @param data 待导出数据
  1052 + * @param clazz {@link }映射对象Class
  1053 + * @param os 生成的Excel待输出数据流
  1054 + * @throws Excel4JException 异常
  1055 + * @throws IOException 异常
  1056 + * @author Crab2Died
  1057 + */
  1058 + public void exportObjects2Excel(List<?> data, Class clazz, OutputStream os)
  1059 + throws Excel4JException, IOException {
  1060 +
  1061 + try (Workbook workbook = exportExcelNoTemplateHandler(data, clazz, true, null, true)) {
  1062 + workbook.write(os);
  1063 + }
  1064 + }
  1065 +
  1066 + /**
  1067 + * 无模板、基于注解的数据导出
  1068 + *
  1069 + * @param data 待导出数据
  1070 + * @param clazz {@link }映射对象Class
  1071 + * @param targetPath 生成的Excel输出全路径
  1072 + * @throws Excel4JException 异常
  1073 + * @throws IOException 异常
  1074 + * @author Crab2Died
  1075 + */
  1076 + public void exportObjects2Excel(List<?> data, Class clazz, String targetPath)
  1077 + throws Excel4JException, IOException {
  1078 +
  1079 + try (FileOutputStream fos = new FileOutputStream(targetPath);
  1080 + Workbook workbook = exportExcelNoTemplateHandler(data, clazz, true, null, true)) {
  1081 + workbook.write(fos);
  1082 + }
  1083 + }
  1084 +
  1085 + // 单sheet数据导出
  1086 + private Workbook exportExcelNoTemplateHandler(List<?> data, Class clazz, boolean isWriteHeader,
  1087 + String sheetName, boolean isXSSF)
  1088 + throws Excel4JException {
  1089 +
  1090 + Workbook workbook;
  1091 + if (isXSSF) {
  1092 + workbook = new XSSFWorkbook();
  1093 + } else {
  1094 + workbook = new HSSFWorkbook();
  1095 + }
  1096 +
  1097 + generateSheet(workbook, data, clazz, isWriteHeader, sheetName);
  1098 +
  1099 + return workbook;
  1100 + }
  1101 +
  1102 + /**
  1103 + * 无模板、基于注解、多sheet数据
  1104 + *
  1105 + * @param sheets 待导出sheet数据
  1106 + * @param targetPath 生成的Excel输出全路径
  1107 + * @throws Excel4JException 异常
  1108 + * @throws IOException 异常
  1109 + */
  1110 + public void noTemplateSheet2Excel(List<NoTemplateSheetWrapper> sheets, String targetPath)
  1111 + throws Excel4JException, IOException {
  1112 +
  1113 + try (OutputStream fos = new FileOutputStream(targetPath);
  1114 + Workbook workbook = exportExcelNoTemplateHandler(sheets, true)) {
  1115 + workbook.write(fos);
  1116 + }
  1117 + }
  1118 +
  1119 + /**
  1120 + * 无模板、基于注解、多sheet数据
  1121 + *
  1122 + * @param sheets 待导出sheet数据
  1123 + * @param isXSSF 导出的Excel是否为Excel2007及以上版本(默认是)
  1124 + * @param targetPath 生成的Excel输出全路径
  1125 + * @throws Excel4JException 异常
  1126 + * @throws IOException 异常
  1127 + */
  1128 + public void noTemplateSheet2Excel(List<NoTemplateSheetWrapper> sheets, boolean isXSSF, String targetPath)
  1129 + throws Excel4JException, IOException {
  1130 +
  1131 + try (OutputStream fos = new FileOutputStream(targetPath);
  1132 + Workbook workbook = exportExcelNoTemplateHandler(sheets, isXSSF)) {
  1133 + workbook.write(fos);
  1134 + }
  1135 + }
  1136 +
  1137 + /**
  1138 + * 无模板、基于注解、多sheet数据
  1139 + *
  1140 + * @param sheets 待导出sheet数据
  1141 + * @param os 生成的Excel输出文件流
  1142 + * @throws Excel4JException 异常
  1143 + * @throws IOException 异常
  1144 + */
  1145 + public void noTemplateSheet2Excel(List<NoTemplateSheetWrapper> sheets, OutputStream os)
  1146 + throws Excel4JException, IOException {
  1147 +
  1148 + try (Workbook workbook = exportExcelNoTemplateHandler(sheets, true)) {
  1149 + workbook.write(os);
  1150 + }
  1151 + }
  1152 +
  1153 + /**
  1154 + * 无模板、基于注解、多sheet数据
  1155 + *
  1156 + * @param sheets 待导出sheet数据
  1157 + * @param isXSSF 导出的Excel是否为Excel2007及以上版本(默认是)
  1158 + * @param os 生成的Excel输出文件流
  1159 + * @throws Excel4JException 异常
  1160 + * @throws IOException 异常
  1161 + */
  1162 + public void noTemplateSheet2Excel(List<NoTemplateSheetWrapper> sheets, boolean isXSSF, OutputStream os)
  1163 + throws Excel4JException, IOException {
  1164 +
  1165 + try (Workbook workbook = exportExcelNoTemplateHandler(sheets, isXSSF)) {
  1166 + workbook.write(os);
  1167 + }
  1168 + }
  1169 +
  1170 + // 多sheet数据导出
  1171 + private Workbook exportExcelNoTemplateHandler(List<NoTemplateSheetWrapper> sheetWrappers, boolean isXSSF)
  1172 + throws Excel4JException {
  1173 +
  1174 + Workbook workbook;
  1175 + if (isXSSF) {
  1176 + workbook = new XSSFWorkbook();
  1177 + } else {
  1178 + workbook = new HSSFWorkbook();
  1179 + }
  1180 +
  1181 + // 导出sheet
  1182 + for (NoTemplateSheetWrapper sheet : sheetWrappers) {
  1183 + generateSheet(workbook, sheet.getData(),
  1184 + sheet.getClazz(), sheet.isWriteHeader(),
  1185 + sheet.getSheetName()
  1186 + );
  1187 + }
  1188 +
  1189 + return workbook;
  1190 + }
  1191 +
  1192 + // 生成sheet数据
  1193 + private void generateSheet(Workbook workbook, List<?> data, Class clazz,
  1194 + boolean isWriteHeader, String sheetName)
  1195 + throws Excel4JException {
  1196 +
  1197 + Sheet sheet;
  1198 + if (null != sheetName && !"".equals(sheetName)) {
  1199 + sheet = workbook.createSheet(sheetName);
  1200 + } else {
  1201 + sheet = workbook.createSheet();
  1202 + }
  1203 + Row row = sheet.createRow(0);
  1204 + List<ExcelHeader> headers = Utils.getHeaderList(clazz);
  1205 + if (isWriteHeader) {
  1206 + // 写标题
  1207 + for (int i = 0; i < headers.size(); i++) {
  1208 + row.createCell(i).setCellValue(headers.get(i).getTitle());
  1209 + }
  1210 + }
  1211 + // 写数据
  1212 + Object _data;
  1213 + for (int i = 0; i < data.size(); i++) {
  1214 + row = sheet.createRow(i + 1);
  1215 + _data = data.get(i);
  1216 + for (int j = 0; j < headers.size(); j++) {
  1217 + row.createCell(j).setCellValue(Utils.getProperty(_data,
  1218 + headers.get(j).getFiled(),
  1219 + headers.get(j).getWriteConverter()));
  1220 + }
  1221 + }
  1222 +
  1223 + }
  1224 +
  1225 + /*---------------------------------------6.无模板无注解导出----------------------------------------------------*/
  1226 + /* 一. 操作流程 : */
  1227 + /* 1) 写入表头内容(可选) */
  1228 + /* 2) 写入数据内容 */
  1229 + /* 二. 参数说明 */
  1230 + /* *) data => 导出内容List集合 */
  1231 + /* *) header => 表头集合,有则写,无则不写 */
  1232 + /* *) sheetName => Sheet索引名(默认0) */
  1233 + /* *) isXSSF => 是否Excel2007及以上版本 */
  1234 + /* *) targetPath => 导出文件路径 */
  1235 + /* *) os => 导出文件流 */
  1236 +
  1237 + /**
  1238 + * 无模板、无注解的数据(形如{@code List[?]}、{@code List[List[?]]}、{@code List[Object[]]})导出
  1239 + *
  1240 + * @param data 待导出数据
  1241 + * @param header 设置表头信息
  1242 + * @param sheetName 指定导出Excel的sheet名称
  1243 + * @param isXSSF 导出的Excel是否为Excel2007及以上版本(默认是)
  1244 + * @param targetPath 生成的Excel输出全路径
  1245 + * @throws IOException 异常
  1246 + * @author Crab2Died
  1247 + */
  1248 + public void exportObjects2Excel(List<?> data, List<String> header, String sheetName,
  1249 + boolean isXSSF, String targetPath)
  1250 + throws IOException {
  1251 +
  1252 + try (OutputStream fos = new FileOutputStream(targetPath);
  1253 + Workbook workbook = exportExcelBySimpleHandler(data, header, sheetName, isXSSF)) {
  1254 + workbook.write(fos);
  1255 + }
  1256 + }
  1257 +
  1258 + /**
  1259 + * 无模板、无注解的数据(形如{@code List[?]}、{@code List[List[?]]}、{@code List[Object[]]})导出
  1260 + *
  1261 + * @param data 待导出数据
  1262 + * @param header 设置表头信息
  1263 + * @param sheetName 指定导出Excel的sheet名称
  1264 + * @param isXSSF 导出的Excel是否为Excel2007及以上版本(默认是)
  1265 + * @param os 生成的Excel待输出数据流
  1266 + * @throws IOException 异常
  1267 + * @author Crab2Died
  1268 + */
  1269 + public void exportObjects2Excel(List<?> data, List<String> header, String sheetName,
  1270 + boolean isXSSF, OutputStream os)
  1271 + throws IOException {
  1272 +
  1273 + try (Workbook workbook = exportExcelBySimpleHandler(data, header, sheetName, isXSSF)) {
  1274 + workbook.write(os);
  1275 + }
  1276 + }
  1277 +
  1278 + /**
  1279 + * 无模板、无注解的数据(形如{@code List[?]}、{@code List[List[?]]}、{@code List[Object[]]})导出
  1280 + *
  1281 + * @param data 待导出数据
  1282 + * @param header 设置表头信息
  1283 + * @param targetPath 生成的Excel输出全路径
  1284 + * @throws IOException 异常
  1285 + * @author Crab2Died
  1286 + */
  1287 + public void exportObjects2Excel(List<?> data, List<String> header, String targetPath)
  1288 + throws IOException {
  1289 +
  1290 + try (OutputStream fos = new FileOutputStream(targetPath);
  1291 + Workbook workbook = exportExcelBySimpleHandler(data, header, null, true)) {
  1292 + workbook.write(fos);
  1293 + }
  1294 + }
  1295 +
  1296 + /**
  1297 + * 无模板、无注解的数据(形如{@code List[?]}、{@code List[List[?]]}、{@code List[Object[]]})导出
  1298 + *
  1299 + * @param data 待导出数据
  1300 + * @param header 设置表头信息
  1301 + * @param os 生成的Excel待输出数据流
  1302 + * @throws IOException 异常
  1303 + * @author Crab2Died
  1304 + */
  1305 + public void exportObjects2Excel(List<?> data, List<String> header, OutputStream os)
  1306 + throws IOException {
  1307 +
  1308 + try (Workbook workbook = exportExcelBySimpleHandler(data, header, null, true)) {
  1309 + workbook.write(os);
  1310 + }
  1311 + }
  1312 +
  1313 + /**
  1314 + * 无模板、无注解的数据(形如{@code List[?]}、{@code List[List[?]]}、{@code List[Object[]]})导出
  1315 + *
  1316 + * @param data 待导出数据
  1317 + * @param targetPath 生成的Excel输出全路径
  1318 + * @throws IOException 异常
  1319 + * @author Crab2Died
  1320 + */
  1321 + public void exportObjects2Excel(List<?> data, String targetPath)
  1322 + throws IOException {
  1323 +
  1324 + try (OutputStream fos = new FileOutputStream(targetPath);
  1325 + Workbook workbook = exportExcelBySimpleHandler(data, null, null, true)) {
  1326 + workbook.write(fos);
  1327 + }
  1328 + }
  1329 +
  1330 + /**
  1331 + * 无模板、无注解的数据(形如{@code List[?]}、{@code List[List[?]]}、{@code List[Object[]]})导出
  1332 + *
  1333 + * @param data 待导出数据
  1334 + * @param os 生成的Excel待输出数据流
  1335 + * @throws IOException 异常
  1336 + * @author Crab2Died
  1337 + */
  1338 + public void exportObjects2Excel(List<?> data, OutputStream os)
  1339 + throws IOException {
  1340 +
  1341 + try (Workbook workbook = exportExcelBySimpleHandler(data, null, null, true)) {
  1342 + workbook.write(os);
  1343 + }
  1344 + }
  1345 +
  1346 + private Workbook exportExcelBySimpleHandler(List<?> data, List<String> header,
  1347 + String sheetName, boolean isXSSF) {
  1348 +
  1349 + Workbook workbook;
  1350 + if (isXSSF) {
  1351 + workbook = new XSSFWorkbook();
  1352 + } else {
  1353 + workbook = new HSSFWorkbook();
  1354 + }
  1355 + // 生成sheet
  1356 + this.generateSheet(workbook, data, header, sheetName);
  1357 +
  1358 + return workbook;
  1359 + }
  1360 +
  1361 + /**
  1362 + * 无模板、无注解、多sheet数据
  1363 + *
  1364 + * @param sheets 待导出sheet数据
  1365 + * @param targetPath 生成的Excel输出全路径
  1366 + * @throws IOException 异常
  1367 + */
  1368 + public void simpleSheet2Excel(List<SimpleSheetWrapper> sheets, String targetPath)
  1369 + throws IOException {
  1370 +
  1371 + try (OutputStream fos = new FileOutputStream(targetPath);
  1372 + Workbook workbook = exportExcelBySimpleHandler(sheets, true)) {
  1373 + workbook.write(fos);
  1374 + }
  1375 + }
  1376 +
  1377 + /**
  1378 + * 无模板、无注解、多sheet数据
  1379 + *
  1380 + * @param sheets 待导出sheet数据
  1381 + * @param isXSSF 导出的Excel是否为Excel2007及以上版本(默认是)
  1382 + * @param targetPath 生成的Excel输出全路径
  1383 + * @throws IOException 异常
  1384 + */
  1385 + public void simpleSheet2Excel(List<SimpleSheetWrapper> sheets, boolean isXSSF, String targetPath)
  1386 + throws IOException {
  1387 +
  1388 + try (OutputStream fos = new FileOutputStream(targetPath);
  1389 + Workbook workbook = exportExcelBySimpleHandler(sheets, isXSSF)) {
  1390 + workbook.write(fos);
  1391 + }
  1392 + }
  1393 +
  1394 + /**
  1395 + * 无模板、无注解、多sheet数据
  1396 + *
  1397 + * @param sheets 待导出sheet数据
  1398 + * @param os 生成的Excel待输出数据流
  1399 + * @throws IOException 异常
  1400 + */
  1401 + public void simpleSheet2Excel(List<SimpleSheetWrapper> sheets, OutputStream os)
  1402 + throws IOException {
  1403 +
  1404 + try (Workbook workbook = exportExcelBySimpleHandler(sheets, true)) {
  1405 + workbook.write(os);
  1406 + }
  1407 + }
  1408 +
  1409 + /**
  1410 + * 无模板、无注解、多sheet数据
  1411 + *
  1412 + * @param sheets 待导出sheet数据
  1413 + * @param isXSSF 导出的Excel是否为Excel2007及以上版本(默认是)
  1414 + * @param os 生成的Excel待输出数据流
  1415 + * @throws IOException 异常
  1416 + */
  1417 + public void simpleSheet2Excel(List<SimpleSheetWrapper> sheets, boolean isXSSF, OutputStream os)
  1418 + throws IOException {
  1419 +
  1420 + try (Workbook workbook = exportExcelBySimpleHandler(sheets, isXSSF)) {
  1421 + workbook.write(os);
  1422 + }
  1423 + }
  1424 +
  1425 + private Workbook exportExcelBySimpleHandler(List<SimpleSheetWrapper> sheets, boolean isXSSF) {
  1426 +
  1427 + Workbook workbook;
  1428 + if (isXSSF) {
  1429 + workbook = new XSSFWorkbook();
  1430 + } else {
  1431 + workbook = new HSSFWorkbook();
  1432 + }
  1433 + // 生成多sheet
  1434 + for (SimpleSheetWrapper sheet : sheets) {
  1435 + this.generateSheet(workbook, sheet.getData(), sheet.getHeader(), sheet.getSheetName());
  1436 + }
  1437 +
  1438 + return workbook;
  1439 + }
  1440 +
  1441 + // 生成sheet数据内容
  1442 + private void generateSheet(Workbook workbook, List<?> data, List<String> header, String sheetName) {
  1443 +
  1444 + Sheet sheet;
  1445 + if (null != sheetName && !"".equals(sheetName)) {
  1446 + sheet = workbook.createSheet(sheetName);
  1447 + } else {
  1448 + sheet = workbook.createSheet();
  1449 + }
  1450 +
  1451 + int rowIndex = 0;
  1452 + if (null != header && header.size() > 0) {
  1453 + // 写标题
  1454 + Row row = sheet.createRow(rowIndex++);
  1455 + for (int i = 0; i < header.size(); i++) {
  1456 + row.createCell(i, CellType.STRING).setCellValue(header.get(i));
  1457 + }
  1458 + }
  1459 + for (Object object : data) {
  1460 + Row row = sheet.createRow(rowIndex++);
  1461 + if (object.getClass().isArray()) {
  1462 + for (int j = 0; j < Array.getLength(object); j++) {
  1463 + row.createCell(j, CellType.STRING).setCellValue(Array.get(object, j).toString());
  1464 + }
  1465 + } else if (object instanceof Collection) {
  1466 + Collection<?> items = (Collection<?>) object;
  1467 + int j = 0;
  1468 + for (Object item : items) {
  1469 + row.createCell(j++, CellType.STRING).setCellValue(item.toString());
  1470 + }
  1471 + } else {
  1472 + row.createCell(0, CellType.STRING).setCellValue(object.toString());
  1473 + }
  1474 + }
  1475 + }
  1476 +
  1477 + /*---------------------------------------7.基于注解的CSV读取--------------------------------------------------*/
  1478 + /* 一. 操作流程 : */
  1479 + /* 1) 读取表头信息,与给出的Class类注解匹配 */
  1480 + /* 2) 读取表头下面的数据内容, 按行读取, 并映射至java对象 */
  1481 + /* 二. 参数说明 */
  1482 + /* *) path => 待读取文件路径 */
  1483 + /* *) is => 待读取文件流 */
  1484 + /* *) clazz => 映射对象 */
  1485 +
  1486 + /**
  1487 + * 基于注解读取CSV文件
  1488 + *
  1489 + * @param path 待读取文件路径
  1490 + * @param clazz 待绑定的类(绑定属性注解{@link })
  1491 + * @return 返回转换为设置绑定的java对象集合
  1492 + * @throws Excel4jReadException exception
  1493 + */
  1494 + public <T> List<T> readCSV2Objects(String path, Class<T> clazz) {
  1495 +
  1496 + try (InputStream is = new FileInputStream(new File(path))) {
  1497 + return readCSVByMapHandler(is, clazz);
  1498 + } catch (IOException | Excel4JException e) {
  1499 + throw new Excel4jReadException("read [" + path + "] CSV Error: ", e);
  1500 + }
  1501 + }
  1502 +
  1503 + /**
  1504 + * 基于注解读取CSV文件
  1505 + *
  1506 + * @param is 待读取文件输入流
  1507 + * @param clazz 待绑定的类(绑定属性注解{@link })
  1508 + * @return 返回转换为设置绑定的java对象集合
  1509 + * @throws Excel4jReadException exception
  1510 + */
  1511 + public <T> List<T> readCSV2Objects(InputStream is, Class<T> clazz) {
  1512 +
  1513 + try {
  1514 + return readCSVByMapHandler(is, clazz);
  1515 + } catch (Excel4JException | IOException e) {
  1516 + throw new Excel4jReadException("read CSV Error: ", e);
  1517 + }
  1518 + }
  1519 +
  1520 + // 读取csv
  1521 + private <T> List<T> readCSVByMapHandler(InputStream is, Class<T> clazz)
  1522 + throws IOException, Excel4JException {
  1523 +
  1524 + List<T> records = new ArrayList<>();
  1525 +
  1526 + List<ExcelHeader> headers = Utils.getHeaderList(clazz);
  1527 + if (null == headers || headers.size() <= 0) {
  1528 + throw new Excel4jReadException("[" + clazz + "] must configuration @ExcelFiled");
  1529 + }
  1530 + String[] csvHeaders = new String[headers.size()];
  1531 + for (int i = 0; i < headers.size(); i++) {
  1532 + csvHeaders[i] = headers.get(i).getTitle();
  1533 + }
  1534 + CSVFormat format = CSVFormat.EXCEL.withHeader(csvHeaders).withSkipHeaderRecord(true);
  1535 + try (Reader read = new InputStreamReader(is, StandardCharsets.UTF_8);
  1536 + CSVParser parser = new CSVParser(read, format)) {
  1537 + for (CSVRecord _parser : parser) {
  1538 + T obj;
  1539 + try {
  1540 + obj = clazz.newInstance();
  1541 + } catch (InstantiationException | IllegalAccessException e) {
  1542 + throw new Excel4jReadException(e);
  1543 + }
  1544 + for (ExcelHeader header : headers) {
  1545 + String value = _parser.get(header.getTitle());
  1546 + Object objectVal;
  1547 + String filed = header.getFiled();
  1548 + // 读取转换器
  1549 + if (null != header.getReadConverter() &&
  1550 + header.getReadConverter().getClass() != DefaultConvertible.class) {
  1551 + objectVal = header.getReadConverter().execRead(value);
  1552 + } else {
  1553 + // 默认转换
  1554 + objectVal = Utils.str2TargetClass(value, header.getFiledClazz());
  1555 + }
  1556 + Utils.copyProperty(obj, filed, objectVal);
  1557 + }
  1558 + records.add(obj);
  1559 + }
  1560 + }
  1561 + return records;
  1562 + }
  1563 +
  1564 + /*---------------------------------------8.基于注解的CSV导出--------------------------------------------------*/
  1565 + /* 一. 操作流程 : */
  1566 + /* 1) 写入表头内容(可选) */
  1567 + /* 2) 写入数据内容 */
  1568 + /* 二. 参数说明 */
  1569 + /* *) data => 导出内容List集合 */
  1570 + /* *) isWriteHeader => 是否写表头 */
  1571 + /* *) path => 导出文件路径 */
  1572 + /* *) os => 导出文件流 */
  1573 + /* *) clazz => 映射对象 */
  1574 +
  1575 + /**
  1576 + * 基于注解导出CSV文件
  1577 + *
  1578 + * @param data 待导出
  1579 + * @param clazz {@link }映射对象Class
  1580 + * @param path 导出文件路径
  1581 + * @throws Excel4JException exception
  1582 + */
  1583 + public void exportObjects2CSV(List<?> data, Class clazz, String path)
  1584 + throws Excel4JException {
  1585 +
  1586 + try {
  1587 + Writer writer = new FileWriter(path);
  1588 + exportCSVByMapHandler(data, clazz, true, writer);
  1589 + } catch (Excel4JException | IOException e) {
  1590 + throw new Excel4JException(e);
  1591 + }
  1592 + }
  1593 +
  1594 + /**
  1595 + * 基于注解导出CSV文件流
  1596 + *
  1597 + * @param data 待导出
  1598 + * @param clazz {@link }映射对象Class
  1599 + * @param os 输出流
  1600 + * @throws Excel4JException exception
  1601 + */
  1602 + public void exportObjects2CSV(List<?> data, Class clazz, OutputStream os)
  1603 + throws Excel4JException {
  1604 +
  1605 + try {
  1606 + Writer writer = new OutputStreamWriter(os);
  1607 + exportCSVByMapHandler(data, clazz, true, writer);
  1608 + } catch (Excel4JException | IOException e) {
  1609 + throw new Excel4JException(e);
  1610 + }
  1611 + }
  1612 +
  1613 + /**
  1614 + * 基于注解导出CSV文件
  1615 + *
  1616 + * @param data 待导出
  1617 + * @param clazz {@link }映射对象Class
  1618 + * @param isWriteHeader 是否写入文件
  1619 + * @param path 导出文件路径
  1620 + * @throws Excel4JException exception
  1621 + */
  1622 + public void exportObjects2CSV(List<?> data, Class clazz, boolean isWriteHeader, String path)
  1623 + throws Excel4JException {
  1624 +
  1625 + try {
  1626 + Writer writer = new FileWriter(path);
  1627 + exportCSVByMapHandler(data, clazz, isWriteHeader, writer);
  1628 + } catch (Excel4JException | IOException e) {
  1629 + throw new Excel4JException(e);
  1630 + }
  1631 + }
  1632 +
  1633 + /**
  1634 + * 基于注解导出CSV文件流
  1635 + *
  1636 + * @param data 待导出
  1637 + * @param clazz {@link }映射对象Class
  1638 + * @param isWriteHeader 是否写入文件
  1639 + * @param os 输出流
  1640 + * @throws Excel4JException exception
  1641 + */
  1642 + public void exportObjects2CSV(List<?> data, Class clazz, boolean isWriteHeader, OutputStream os)
  1643 + throws Excel4JException {
  1644 +
  1645 + try {
  1646 + Writer writer = new OutputStreamWriter(os);
  1647 + exportCSVByMapHandler(data, clazz, isWriteHeader, writer);
  1648 + } catch (Excel4JException | IOException e) {
  1649 + throw new Excel4JException(e);
  1650 + }
  1651 + }
  1652 +
  1653 + private static final byte[] UTF_8_DOM = {(byte) 0xEF, (byte) 0xBB, (byte) 0xBF};
  1654 +
  1655 + // 生成CSV
  1656 + private void exportCSVByMapHandler(List<?> data, Class clazz, boolean isWriteHeader, Appendable appendable)
  1657 + throws Excel4JException, IOException {
  1658 +
  1659 + List<ExcelHeader> headers = Utils.getHeaderList(clazz);
  1660 + appendable.append(new String(UTF_8_DOM, StandardCharsets.UTF_8));
  1661 +
  1662 + try (CSVPrinter printer = new CSVPrinter(appendable, CSVFormat.EXCEL)) {
  1663 +
  1664 + if (isWriteHeader) {
  1665 + for (ExcelHeader header : headers) {
  1666 + printer.print(header.getTitle());
  1667 + }
  1668 + printer.println();
  1669 + }
  1670 + // 写数据
  1671 + for (Object _data : data) {
  1672 + for (ExcelHeader header : headers) {
  1673 + printer.print(
  1674 + Utils.getProperty(_data, header.getFiled(), header.getWriteConverter())
  1675 + );
  1676 + }
  1677 + printer.println();
  1678 + }
  1679 + printer.flush();
  1680 + }
  1681 + }
  1682 +
  1683 +}
... ...
src/main/java/com/order/erp/common/excel4j/ExcelValidator.java 0 → 100644
  1 +package com.order.erp.common.excel4j;
  2 +
  3 +import com.order.erp.common.constant.Constant;
  4 +import com.order.erp.common.exception.BusinessException;
  5 +import com.order.erp.common.utils.StringUtils;
  6 +import lombok.extern.slf4j.Slf4j;
  7 +
  8 +import javax.validation.ConstraintViolation;
  9 +import javax.validation.Validation;
  10 +import javax.validation.Validator;
  11 +import javax.validation.groups.Default;
  12 +import java.util.Set;
  13 +
  14 +/**
  15 + * @author fanzhenyu
  16 + * @date 2023-02-23
  17 + */
  18 +@Slf4j
  19 +public class ExcelValidator {
  20 +
  21 +
  22 + private static Validator validator = Validation.buildDefaultValidatorFactory().getValidator();
  23 +
  24 + /**
  25 + * 校验遇到第一个不合法的字段直接返回不合法字段,后续字段不再校验
  26 + * @param <T>
  27 + * @return
  28 + */
  29 + public static <T> void validateEntity(T obj) {
  30 + Set<ConstraintViolation<T>> set = validator.validate(obj, Default.class);
  31 + String err = collectError(set);
  32 + if (StringUtils.isNotBlank(err)){
  33 + throw new BusinessException(com.canrd.shop.common.constant.ServerResultCode.ILLEGAL_ARGUMENT.getErrorCode(),err);
  34 + }
  35 + }
  36 +
  37 + private static <T> String collectError(Set<ConstraintViolation<T>> set) {
  38 + StringBuilder result = new StringBuilder();
  39 + if (set != null && !set.isEmpty()) {
  40 + for (ConstraintViolation<T> cv : set) {
  41 + result.append(cv.getMessage());
  42 + result.append(Constant.SEMICOLON_CHARACTER);
  43 + }
  44 + }
  45 + return result.toString();
  46 + }
  47 +
  48 +
  49 +
  50 +}
... ...
src/main/java/com/order/erp/common/excel4j/annotation/ExcelField.java 0 → 100644
  1 +package com.order.erp.common.excel4j.annotation;
  2 +
  3 +
  4 +import com.order.erp.common.excel4j.converter.DefaultConvertible;
  5 +import com.order.erp.common.excel4j.converter.ReadConvertible;
  6 +import com.order.erp.common.excel4j.converter.WriteConvertible;
  7 +
  8 +import java.lang.annotation.ElementType;
  9 +import java.lang.annotation.Retention;
  10 +import java.lang.annotation.RetentionPolicy;
  11 +import java.lang.annotation.Target;
  12 +
  13 +/**
  14 + * 功能说明: 用来在对象的属性上加入的annotation,通过该annotation说明某个属性所对应的标题
  15 + */
  16 +@Retention(RetentionPolicy.RUNTIME)
  17 +@Target(ElementType.FIELD)
  18 +public @interface ExcelField {
  19 +
  20 + /**
  21 + * 属性的标题名称
  22 + *
  23 + * @return 表头名
  24 + */
  25 + String title();
  26 +
  27 + /**
  28 + * 写数据转换器
  29 + *
  30 + * @return 写入Excel数据转换器
  31 + * @see WriteConvertible
  32 + */
  33 + Class<? extends WriteConvertible> writeConverter()
  34 + default DefaultConvertible.class;
  35 +
  36 + /**
  37 + * 读数据转换器
  38 + *
  39 + * @return 读取Excel数据转换器
  40 + * @see ReadConvertible
  41 + */
  42 + Class<? extends ReadConvertible> readConverter()
  43 + default DefaultConvertible.class;
  44 +
  45 + /**
  46 + * 在excel的顺序
  47 + *
  48 + * @return 列表顺序
  49 + */
  50 + int order() default Integer.MAX_VALUE;
  51 +}
... ...
src/main/java/com/order/erp/common/excel4j/converter/DefaultConvertible.java 0 → 100644
  1 +package com.order.erp.common.excel4j.converter;
  2 +
  3 +/**
  4 + * 抽象默认转换器, 实现了{@link WriteConvertible} 与 {@link ReadConvertible}接口
  5 + */
  6 +public class DefaultConvertible implements WriteConvertible, ReadConvertible {
  7 +
  8 + @Override
  9 + public Object execRead(String object) {
  10 + throw new UnsupportedOperationException();
  11 + }
  12 +
  13 + @Override
  14 + public Object execWrite(Object object) {
  15 + throw new UnsupportedOperationException();
  16 + }
  17 +}
... ...
src/main/java/com/order/erp/common/excel4j/converter/ReadConvertible.java 0 → 100644
  1 +package com.order.erp.common.excel4j.converter;
  2 +
  3 +/**
  4 + * 写入excel内容转换器
  5 + */
  6 +public interface ReadConvertible {
  7 +
  8 + /**
  9 + * 读取Excel列内容转换
  10 + *
  11 + * @param object 待转换数据
  12 + * @return 转换完成的结果
  13 + */
  14 + Object execRead(String object);
  15 +}
... ...
src/main/java/com/order/erp/common/excel4j/converter/WriteConvertible.java 0 → 100644
  1 +package com.order.erp.common.excel4j.converter;
  2 +
  3 +/**
  4 + * 写入excel内容转换器
  5 + */
  6 +public interface WriteConvertible {
  7 +
  8 + /**
  9 + * 写入Excel列内容转换
  10 + *
  11 + * @param object 待转换数据
  12 + * @return 转换完成的结果
  13 + */
  14 + Object execWrite(Object object);
  15 +}
... ...
src/main/java/com/order/erp/common/excel4j/exceptions/Excel4JException.java 0 → 100644
  1 +package com.order.erp.common.excel4j.exceptions;
  2 +
  3 +public class Excel4JException extends Exception {
  4 +
  5 + public Excel4JException() {
  6 + }
  7 +
  8 + public Excel4JException(String message) {
  9 + super(message);
  10 + }
  11 +
  12 + public Excel4JException(String message, Throwable cause) {
  13 + super(message, cause);
  14 + }
  15 +
  16 + public Excel4JException(Throwable cause) {
  17 + super(cause);
  18 + }
  19 +}
... ...
src/main/java/com/order/erp/common/excel4j/exceptions/Excel4jReadException.java 0 → 100644
  1 +package com.order.erp.common.excel4j.exceptions;
  2 +
  3 +public class Excel4jReadException extends RuntimeException {
  4 +
  5 + private static final long serialVersionUID = 8735084330744657672L;
  6 +
  7 + public Excel4jReadException() {
  8 + super();
  9 + }
  10 +
  11 + public Excel4jReadException(Throwable cause) {
  12 + super(cause);
  13 + }
  14 +
  15 + public Excel4jReadException(String message) {
  16 + super(message);
  17 + }
  18 +
  19 + public Excel4jReadException(String message, Throwable cause) {
  20 + super(message, cause);
  21 + }
  22 +}
... ...
src/main/java/com/order/erp/common/excel4j/exceptions/IllegalGroupIndexException.java 0 → 100644
  1 +package com.order.erp.common.excel4j.exceptions;
  2 +
  3 +public class IllegalGroupIndexException extends RuntimeException {
  4 +
  5 + private static final long serialVersionUID = 7725478743860387475L;
  6 +
  7 + public IllegalGroupIndexException(String message) {
  8 + super(message);
  9 + }
  10 +}
... ...
src/main/java/com/order/erp/common/excel4j/exceptions/TimeMatchFormatException.java 0 → 100644
  1 +package com.order.erp.common.excel4j.exceptions;
  2 +
  3 +public class TimeMatchFormatException extends RuntimeException {
  4 +
  5 + private static final long serialVersionUID = 206910143412957809L;
  6 +
  7 + public TimeMatchFormatException() {
  8 + }
  9 +
  10 + public TimeMatchFormatException(String message) {
  11 + super(message);
  12 + }
  13 +
  14 + public TimeMatchFormatException(String message, Throwable cause) {
  15 + super(message, cause);
  16 + }
  17 +}
... ...
src/main/java/com/order/erp/common/excel4j/handler/ExcelHeader.java 0 → 100644
  1 +package com.order.erp.common.excel4j.handler;
  2 +
  3 +
  4 +import com.order.erp.common.excel4j.converter.ReadConvertible;
  5 +import com.order.erp.common.excel4j.converter.WriteConvertible;
  6 +
  7 +/**
  8 + * 功能说明: 用来存储Excel标题的对象,通过该对象可以获取标题和方法的对应关系
  9 + */
  10 +public class ExcelHeader implements Comparable<ExcelHeader> {
  11 +
  12 + /**
  13 + * excel的标题名称
  14 + */
  15 + private String title;
  16 +
  17 + /**
  18 + * 每一个标题的顺序
  19 + */
  20 + private int order;
  21 +
  22 + /**
  23 + * 写数据转换器
  24 + */
  25 + private WriteConvertible writeConverter;
  26 +
  27 + /**
  28 + * 读数据转换器
  29 + */
  30 + private ReadConvertible readConverter;
  31 +
  32 + /**
  33 + * 注解域
  34 + */
  35 + private String filed;
  36 +
  37 + /**
  38 + * 属性类型
  39 + */
  40 + private Class<?> filedClazz;
  41 +
  42 +
  43 + public String getTitle() {
  44 + return title;
  45 + }
  46 +
  47 + public void setTitle(String title) {
  48 + this.title = title;
  49 + }
  50 +
  51 + public int getOrder() {
  52 + return order;
  53 + }
  54 +
  55 + public void setOrder(int order) {
  56 + this.order = order;
  57 + }
  58 +
  59 + public WriteConvertible getWriteConverter() {
  60 + return writeConverter;
  61 + }
  62 +
  63 + public void setWriteConverter(WriteConvertible writeConverter) {
  64 + this.writeConverter = writeConverter;
  65 + }
  66 +
  67 + public ReadConvertible getReadConverter() {
  68 + return readConverter;
  69 + }
  70 +
  71 + public void setReadConverter(ReadConvertible readConverter) {
  72 + this.readConverter = readConverter;
  73 + }
  74 +
  75 + public String getFiled() {
  76 + return filed;
  77 + }
  78 +
  79 + public void setFiled(String filed) {
  80 + this.filed = filed;
  81 + }
  82 +
  83 + public Class<?> getFiledClazz() {
  84 + return filedClazz;
  85 + }
  86 +
  87 + public void setFiledClazz(Class<?> filedClazz) {
  88 + this.filedClazz = filedClazz;
  89 + }
  90 +
  91 + @Override
  92 + public int compareTo(ExcelHeader o) {
  93 + return order - o.order;
  94 + }
  95 +
  96 + public ExcelHeader() {
  97 + super();
  98 + }
  99 +
  100 + public ExcelHeader(String title, int order, WriteConvertible writeConverter,
  101 + ReadConvertible readConverter, String filed, Class<?> filedClazz) {
  102 + super();
  103 + this.title = title;
  104 + this.order = order;
  105 + this.writeConverter = writeConverter;
  106 + this.readConverter = readConverter;
  107 + this.filed = filed;
  108 + this.filedClazz = filedClazz;
  109 + }
  110 +
  111 +
  112 +}
... ...
src/main/java/com/order/erp/common/excel4j/handler/HandlerConstant.java 0 → 100644
  1 +package com.order.erp.common.excel4j.handler;
  2 +
  3 +
  4 +/**
  5 + * <p>Excel模板自定义属性,不区分大小写</p>
  6 + */
  7 +final class HandlerConstant {
  8 +
  9 + // 数据插入起始坐标点
  10 + static final String DATA_INIT_INDEX = "$data_index";
  11 +
  12 + // 默认样式
  13 + static final String DEFAULT_STYLE = "$default_style";
  14 +
  15 + // 当前标记行样式
  16 + static final String APPOINT_LINE_STYLE = "$appoint_line_style";
  17 +
  18 + // 单数行样式
  19 + static final String SINGLE_LINE_STYLE = "$single_line_style";
  20 +
  21 + // 双数行样式
  22 + static final String DOUBLE_LINE_STYLE = "$double_line_style";
  23 +
  24 + // 序号列坐标点
  25 + static final String SERIAL_NUMBER = "$serial_number";
  26 +
  27 +}
... ...
src/main/java/com/order/erp/common/excel4j/handler/SheetTemplate.java 0 → 100644
  1 +package com.order.erp.common.excel4j.handler;
  2 +
  3 +import com.order.erp.common.excel4j.exceptions.Excel4JException;
  4 +import org.apache.poi.ss.usermodel.CellStyle;
  5 +import org.apache.poi.ss.usermodel.Row;
  6 +import org.apache.poi.ss.usermodel.Sheet;
  7 +import org.apache.poi.ss.usermodel.Workbook;
  8 +
  9 +import java.io.Closeable;
  10 +import java.io.FileOutputStream;
  11 +import java.io.IOException;
  12 +import java.io.OutputStream;
  13 +import java.util.HashMap;
  14 +import java.util.Map;
  15 +
  16 +public class SheetTemplate implements Closeable {
  17 +
  18 + /**
  19 + * 当前工作簿
  20 + */
  21 + Workbook workbook;
  22 + /**
  23 + * 当前工作sheet表
  24 + */
  25 + Sheet sheet;
  26 + /**
  27 + * 当前表编号
  28 + */
  29 + int sheetIndex;
  30 + /**
  31 + * 当前行
  32 + */
  33 + Row currentRow;
  34 + /**
  35 + * 当前列数
  36 + */
  37 + int currentColumnIndex;
  38 + /**
  39 + * 当前行数
  40 + */
  41 + int currentRowIndex;
  42 + /**
  43 + * 默认样式
  44 + */
  45 + CellStyle defaultStyle;
  46 + /**
  47 + * 指定行样式
  48 + */
  49 + Map<Integer, CellStyle> appointLineStyle = new HashMap<>();
  50 + /**
  51 + * 分类样式模板
  52 + */
  53 + Map<String, CellStyle> classifyStyle = new HashMap<>();
  54 + /**
  55 + * 单数行样式
  56 + */
  57 + CellStyle singleLineStyle;
  58 + /**
  59 + * 双数行样式
  60 + */
  61 + CellStyle doubleLineStyle;
  62 + /**
  63 + * 数据的初始化列数
  64 + */
  65 + int initColumnIndex;
  66 + /**
  67 + * 数据的初始化行数
  68 + */
  69 + int initRowIndex;
  70 +
  71 + /**
  72 + * 最后一行的数据
  73 + */
  74 + int lastRowIndex;
  75 + /**
  76 + * 默认行高
  77 + */
  78 + float rowHeight;
  79 + /**
  80 + * 序号坐标点
  81 + */
  82 + int serialNumberColumnIndex = -1;
  83 + /**
  84 + * 当前序号
  85 + */
  86 + int serialNumber;
  87 +
  88 + /*-----------------------------------写出数据开始-----------------------------------*/
  89 +
  90 + /**
  91 + * 将文件写到相应的路径下
  92 + *
  93 + * @param filePath 输出文件路径
  94 + */
  95 + public void write2File(String filePath) throws Excel4JException {
  96 +
  97 + try (FileOutputStream fos = new FileOutputStream(filePath)) {
  98 + this.workbook.write(fos);
  99 + } catch (IOException e) {
  100 + throw new Excel4JException(e);
  101 + }
  102 + }
  103 +
  104 + /**
  105 + * 将文件写到某个输出流中
  106 + *
  107 + * @param os 输出流
  108 + */
  109 + public void write2Stream(OutputStream os) throws Excel4JException {
  110 +
  111 + try {
  112 + this.workbook.write(os);
  113 + } catch (IOException e) {
  114 + throw new Excel4JException(e);
  115 + }
  116 + }
  117 +
  118 + /*-----------------------------------写出数据结束-----------------------------------*/
  119 +
  120 + @Override
  121 + public void close() throws IOException {
  122 + if (null != this.workbook) {
  123 + this.workbook.close();
  124 + }
  125 + }
  126 +
  127 +}
... ...
src/main/java/com/order/erp/common/excel4j/handler/SheetTemplateHandler.java 0 → 100644
  1 +package com.order.erp.common.excel4j.handler;
  2 +
  3 +import com.order.erp.common.excel4j.exceptions.Excel4JException;
  4 +import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
  5 +import org.apache.poi.ss.usermodel.*;
  6 +
  7 +import java.io.File;
  8 +import java.io.FileInputStream;
  9 +import java.io.IOException;
  10 +import java.io.InputStream;
  11 +import java.util.Calendar;
  12 +import java.util.Date;
  13 +import java.util.Map;
  14 +
  15 +public class SheetTemplateHandler {
  16 +
  17 + // 构建SheetTemplate
  18 + public static SheetTemplate sheetTemplateBuilder(String templatePath)
  19 + throws Excel4JException {
  20 + SheetTemplate sheetTemplate = new SheetTemplate();
  21 + try {
  22 + // 读取模板文件
  23 + sheetTemplate.workbook = WorkbookFactory.create(new FileInputStream(new File(templatePath)));
  24 + } catch (Exception e) {
  25 + // 读取模板相对文件
  26 + try {
  27 + sheetTemplate.workbook = WorkbookFactory.create(
  28 + SheetTemplateHandler.class.getResourceAsStream(templatePath)
  29 + );
  30 + } catch (IOException | InvalidFormatException e1) {
  31 + throw new Excel4JException(e1);
  32 + }
  33 + }
  34 + return sheetTemplate;
  35 + }
  36 +
  37 + public static SheetTemplate sheetTemplateBuilder(InputStream is)
  38 + throws Excel4JException {
  39 + SheetTemplate sheetTemplate = new SheetTemplate();
  40 +
  41 + // 读取模板文件
  42 + try {
  43 + sheetTemplate.workbook = WorkbookFactory.create(is);
  44 + } catch (IOException | InvalidFormatException e) {
  45 + throw new Excel4JException(e);
  46 + }
  47 + return sheetTemplate;
  48 + }
  49 +
  50 + /*-----------------------------------初始化模板开始-----------------------------------*/
  51 +
  52 + public static void loadTemplate(SheetTemplate template, int sheetIndex) {
  53 +
  54 + if (sheetIndex < 0) {
  55 + sheetIndex = 0;
  56 + }
  57 + template.sheetIndex = sheetIndex;
  58 + template.sheet = template.workbook.getSheetAt(sheetIndex);
  59 + initModuleConfig(template);
  60 + template.currentRowIndex = template.initRowIndex;
  61 + template.currentColumnIndex = template.initColumnIndex;
  62 + template.lastRowIndex = template.sheet.getLastRowNum();
  63 + }
  64 +
  65 + /**
  66 + * 初始化数据信息
  67 + */
  68 + private static void initModuleConfig(SheetTemplate template) {
  69 +
  70 + for (Row row : template.sheet) {
  71 + for (Cell c : row) {
  72 + if (c.getCellTypeEnum() != CellType.STRING) {
  73 + continue;
  74 + }
  75 + String str = c.getStringCellValue().trim().toLowerCase();
  76 + // 寻找序号列
  77 + if (HandlerConstant.SERIAL_NUMBER.equals(str)) {
  78 + template.serialNumberColumnIndex = c.getColumnIndex();
  79 + }
  80 + // 寻找数据列
  81 + if (HandlerConstant.DATA_INIT_INDEX.equals(str)) {
  82 + template.initColumnIndex = c.getColumnIndex();
  83 + template.initRowIndex = row.getRowNum();
  84 + template.rowHeight = row.getHeightInPoints();
  85 + }
  86 + // 初始化自定义模板样式
  87 + initStyles(template, c, str);
  88 + }
  89 + }
  90 + }
  91 +
  92 + /**
  93 + * 初始化样式信息
  94 + */
  95 + private static void initStyles(SheetTemplate template, Cell cell, String moduleContext) {
  96 + if (null == moduleContext || "".equals(moduleContext)) {
  97 + return;
  98 + }
  99 + if (!moduleContext.startsWith("&")) {
  100 + moduleContext = moduleContext.toLowerCase();
  101 + }
  102 +
  103 + if (HandlerConstant.DEFAULT_STYLE.equals(moduleContext)) {
  104 + template.defaultStyle = cell.getCellStyle();
  105 + clearCell(cell);
  106 + }
  107 + if (moduleContext.startsWith("&") && moduleContext.length() > 1) {
  108 + template.classifyStyle.put(moduleContext.substring(1), cell.getCellStyle());
  109 + clearCell(cell);
  110 + }
  111 + if (HandlerConstant.APPOINT_LINE_STYLE.equals(moduleContext)) {
  112 + template.appointLineStyle.put(cell.getRowIndex(), cell.getCellStyle());
  113 + clearCell(cell);
  114 + }
  115 + if (HandlerConstant.SINGLE_LINE_STYLE.equals(moduleContext)) {
  116 + template.singleLineStyle = cell.getCellStyle();
  117 + clearCell(cell);
  118 + }
  119 + if (HandlerConstant.DOUBLE_LINE_STYLE.equals(moduleContext)) {
  120 + template.doubleLineStyle = cell.getCellStyle();
  121 + clearCell(cell);
  122 + }
  123 + }
  124 +
  125 + private static void clearCell(Cell cell) {
  126 + cell.setCellStyle(null);
  127 + cell.setCellValue("");
  128 + }
  129 +
  130 + /*-----------------------------------初始化模板结束-----------------------------------*/
  131 +
  132 + /*-----------------------------------数据填充开始------------------------------------*/
  133 +
  134 + /**
  135 + * 根据map替换相应的常量,通过Map中的值来替换#开头的值
  136 + *
  137 + * @param data 替换映射
  138 + */
  139 + public static void extendData(SheetTemplate template, Map<String, String> data) {
  140 + if (data == null) {
  141 + return;
  142 + }
  143 +
  144 + for (Row row : template.sheet) {
  145 + for (Cell c : row) {
  146 + if (c.getCellTypeEnum() != CellType.STRING) {
  147 + continue;
  148 + }
  149 + String str = c.getStringCellValue().trim();
  150 + if (str.startsWith("#") && data.containsKey(str.substring(1))) {
  151 + c.setCellValue(data.get(str.substring(1)));
  152 + }
  153 + }
  154 + }
  155 + }
  156 +
  157 + /**
  158 + * 创建新行,在使用时只要添加完一行,需要调用该方法创建
  159 + */
  160 + public static void createNewRow(SheetTemplate template) {
  161 + if (template.lastRowIndex > template.currentRowIndex && template.currentRowIndex != template.initRowIndex) {
  162 + template.sheet.shiftRows(template.currentRowIndex, template.lastRowIndex, 1, true, true);
  163 + template.lastRowIndex++;
  164 + }
  165 + template.currentRow = template.sheet.createRow(template.currentRowIndex);
  166 + template.currentRow.setHeightInPoints(template.rowHeight);
  167 + template.currentRowIndex++;
  168 + template.currentColumnIndex = template.initColumnIndex;
  169 + }
  170 +
  171 + /**
  172 + * 插入序号,会自动找相应的序号标示的位置完成插入
  173 + *
  174 + * @param styleKey 样式标识
  175 + */
  176 + public static void insertSerial(SheetTemplate template, String styleKey) {
  177 + if (template.serialNumberColumnIndex < 0) {
  178 + return;
  179 + }
  180 +
  181 + template.serialNumber++;
  182 + Cell c = template.currentRow.createCell(template.serialNumberColumnIndex);
  183 + setCellStyle(template, c, styleKey);
  184 + c.setCellValue(template.serialNumber);
  185 + }
  186 +
  187 + /**
  188 + * <p>设置Excel元素样式及内容</p>
  189 + *
  190 + * @param value 内容
  191 + * @param styleKey 样式
  192 + */
  193 + public static void createCell(SheetTemplate template, Object value, String styleKey) {
  194 + Cell cell = template.currentRow.createCell(template.currentColumnIndex);
  195 + setCellStyle(template, cell, styleKey);
  196 + if (null == value || "".equals(value)) {
  197 + template.currentColumnIndex++;
  198 + return;
  199 + }
  200 +
  201 + if (String.class == value.getClass()) {
  202 + cell.setCellValue((String) value);
  203 + template.currentColumnIndex++;
  204 + return;
  205 + }
  206 +
  207 + if (int.class == value.getClass()) {
  208 + cell.setCellValue((int) value);
  209 + template.currentColumnIndex++;
  210 + return;
  211 + }
  212 +
  213 + if (Integer.class == value.getClass()) {
  214 + cell.setCellValue((Integer) value);
  215 + template.currentColumnIndex++;
  216 + return;
  217 + }
  218 +
  219 + if (double.class == value.getClass()) {
  220 + cell.setCellValue((double) value);
  221 + template.currentColumnIndex++;
  222 + return;
  223 + }
  224 +
  225 + if (Double.class == value.getClass()) {
  226 + cell.setCellValue((Double) value);
  227 + template.currentColumnIndex++;
  228 + return;
  229 + }
  230 +
  231 + if (Date.class == value.getClass()) {
  232 + cell.setCellValue((Date) value);
  233 + template.currentColumnIndex++;
  234 + return;
  235 + }
  236 +
  237 + if (boolean.class == value.getClass()) {
  238 + cell.setCellValue((boolean) value);
  239 + template.currentColumnIndex++;
  240 + return;
  241 + }
  242 +
  243 + if (Boolean.class == value.getClass()) {
  244 + cell.setCellValue((Boolean) value);
  245 + template.currentColumnIndex++;
  246 + return;
  247 + }
  248 +
  249 + if (Calendar.class == value.getClass()) {
  250 + cell.setCellValue((Calendar) value);
  251 + template.currentColumnIndex++;
  252 + return;
  253 + }
  254 +
  255 + if (RichTextString.class == value.getClass()) {
  256 + cell.setCellValue((RichTextString) value);
  257 + template.currentColumnIndex++;
  258 + return;
  259 + }
  260 + // default value#toString
  261 + cell.setCellValue(value.toString());
  262 + template.currentColumnIndex++;
  263 + }
  264 +
  265 + /**
  266 + * 设置某个元素的样式
  267 + *
  268 + * @param cell cell元素
  269 + * @param styleKey 样式标识
  270 + */
  271 + private static void setCellStyle(SheetTemplate template, Cell cell, String styleKey) {
  272 + if (null != styleKey && null != template.classifyStyle.get(styleKey)) {
  273 + cell.setCellStyle(template.classifyStyle.get(styleKey));
  274 + return;
  275 + }
  276 +
  277 + if (null != template.appointLineStyle && template.appointLineStyle.containsKey(cell.getRowIndex())) {
  278 + cell.setCellStyle(template.appointLineStyle.get(cell.getRowIndex()));
  279 + return;
  280 + }
  281 + if (null != template.singleLineStyle && (cell.getRowIndex() % 2 != 0)) {
  282 + cell.setCellStyle(template.singleLineStyle);
  283 + return;
  284 + }
  285 + if (null != template.doubleLineStyle && (cell.getRowIndex() % 2 == 0)) {
  286 + cell.setCellStyle(template.doubleLineStyle);
  287 + return;
  288 + }
  289 + if (null != template.defaultStyle) {
  290 + cell.setCellStyle(template.defaultStyle);
  291 + }
  292 +
  293 + }
  294 +
  295 + /*-----------------------------------数据填充结束-----------------------------------*/
  296 +
  297 +}
... ...
src/main/java/com/order/erp/common/excel4j/utils/DateUtils.java 0 → 100644
  1 +package com.order.erp.common.excel4j.utils;
  2 +
  3 +import com.order.erp.common.excel4j.exceptions.TimeMatchFormatException;
  4 +
  5 +import java.text.ParseException;
  6 +import java.text.SimpleDateFormat;
  7 +import java.util.Date;
  8 +
  9 +/**
  10 + * <p>时间处理工具类</p>
  11 + * author : Crab2Died
  12 + * date : 2017/5/23 10:35
  13 + */
  14 +public class DateUtils {
  15 +
  16 + public static final String DATE_FORMAT_DAY = "yyyy-MM-dd";
  17 + public static final String DATE_FORMAT_DAY_2 = "yyyy/MM/dd";
  18 + public static final String TIME_FORMAT_SEC = "HH:mm:ss";
  19 + public static final String DATE_FORMAT_SEC = "yyyy-MM-dd HH:mm:ss";
  20 + public static final String DATE_FORMAT_MSEC = "yyyy-MM-dd HH:mm:ss.SSS";
  21 + public static final String DATE_FORMAT_MSEC_T = "yyyy-MM-dd'T'HH:mm:ss.SSS";
  22 + public static final String DATE_FORMAT_MSEC_T_Z = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'";
  23 + public static final String DATE_FORMAT_DAY_SIMPLE = "y/M/d";
  24 +
  25 + /**
  26 + * 匹配yyyy-MM-dd
  27 + */
  28 + private static final String DATE_REG = "^[1-9]\\d{3}-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])$";
  29 + /**
  30 + * 匹配yyyy/MM/dd
  31 + */
  32 + private static final String DATE_REG_2 = "^[1-9]\\d{3}/(0[1-9]|1[0-2])/(0[1-9]|[1-2][0-9]|3[0-1])$";
  33 + /**
  34 + * 匹配y/M/d
  35 + */
  36 + private static final String DATE_REG_SIMPLE_2 = "^[1-9]\\d{3}/([1-9]|1[0-2])/([1-9]|[1-2][0-9]|3[0-1])$";
  37 + /**
  38 + * 匹配HH:mm:ss
  39 + */
  40 + private static final String TIME_SEC_REG = "^(20|21|22|23|[0-1]\\d):[0-5]\\d:[0-5]\\d$";
  41 + /**
  42 + * 匹配yyyy-MM-dd HH:mm:ss
  43 + */
  44 + private static final String DATE_TIME_REG = "^[1-9]\\d{3}-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])\\s" +
  45 + "(20|21|22|23|[0-1]\\d):[0-5]\\d:[0-5]\\d$";
  46 + /**
  47 + * 匹配yyyy-MM-dd HH:mm:ss.SSS
  48 + */
  49 + private static final String DATE_TIME_MSEC_REG = "^[1-9]\\d{3}-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])\\s" +
  50 + "(20|21|22|23|[0-1]\\d):[0-5]\\d:[0-5]\\d\\.\\d{3}$";
  51 + /**
  52 + * 匹配yyyy-MM-dd'T'HH:mm:ss.SSS
  53 + */
  54 + private static final String DATE_TIME_MSEC_T_REG = "^[1-9]\\d{3}-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])T" +
  55 + "(20|21|22|23|[0-1]\\d):[0-5]\\d:[0-5]\\d\\.\\d{3}$";
  56 + /**
  57 + * 匹配yyyy-MM-dd'T'HH:mm:ss.SSS'Z'
  58 + */
  59 + private static final String DATE_TIME_MSEC_T_Z_REG = "^[1-9]\\d{3}-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])T" +
  60 + "(20|21|22|23|[0-1]\\d):[0-5]\\d:[0-5]\\d\\.\\d{3}Z$";
  61 +
  62 + /**
  63 + * <p>将{@link Date}类型转换为指定格式的字符串</p>
  64 + * author : Crab2Died
  65 + * date : 2017年06月02日 15:32:04
  66 + *
  67 + * @param date {@link Date}类型的时间
  68 + * @param format 指定格式化类型
  69 + * @return 返回格式化后的时间字符串
  70 + */
  71 + public static String date2Str(Date date, String format) {
  72 + SimpleDateFormat sdf = new SimpleDateFormat(format);
  73 + return sdf.format(date);
  74 + }
  75 +
  76 + /**
  77 + * <p>将{@link Date}类型转换为默认为[yyyy-MM-dd HH:mm:ss]类型的字符串</p>
  78 + * author : Crab2Died
  79 + * date : 2017年06月02日 15:30:01
  80 + *
  81 + * @param date {@link Date}类型的时间
  82 + * @return 返回格式化后的时间字符串
  83 + */
  84 + public static String date2Str(Date date) {
  85 + SimpleDateFormat sdf = new SimpleDateFormat(DATE_FORMAT_SEC);
  86 + return sdf.format(date);
  87 + }
  88 +
  89 + /**
  90 + * <p>根据给出的格式化类型将时间字符串转为{@link Date}类型</p>
  91 + * author : Crab2Died
  92 + * date : 2017年06月02日 15:27:22
  93 + *
  94 + * @param strDate 时间字符串
  95 + * @param format 格式化类型
  96 + * @return 返回{@link java.util.Date}类型
  97 + */
  98 + public static Date str2Date(String strDate, String format) {
  99 + Date date = null;
  100 + SimpleDateFormat sdf = new SimpleDateFormat(format);
  101 + try {
  102 + date = sdf.parse(strDate);
  103 + } catch (ParseException e) {
  104 + throw new TimeMatchFormatException("[" + strDate + "] parse to [" + format + "] exception", e);
  105 + }
  106 + return date;
  107 + }
  108 +
  109 + /**
  110 + * <p>字符串时间转为{@link Date}类型,
  111 + * 未找到匹配类型则抛出{@link TimeMatchFormatException}异常</p>
  112 + * <p>支持匹配类型列表:</p>
  113 + * <p>yyyy-MM-dd</p>
  114 + * <p>yyyy/MM/dd</p>
  115 + * <p>HH:mm:ss</p>
  116 + * <p>yyyy-MM-dd HH:mm:ss</p>
  117 + * <p>yyyy-MM-dd'T'HH:mm:ss.SSS</p>
  118 + * <p>yyyy-MM-dd'T'HH:mm:ss.SSS'Z'</p>
  119 + * <p>
  120 + * author : Crab2Died
  121 + * date : 2017年06月02日 15:21:54
  122 + *
  123 + * @param strDate 时间字符串
  124 + * @return Date {@link Date}时间
  125 + * @throws ParseException 异常
  126 + */
  127 + public static Date str2Date(String strDate) throws ParseException {
  128 +
  129 + strDate = strDate.trim();
  130 + SimpleDateFormat sdf = null;
  131 + if (RegularUtils.isMatched(strDate, DATE_REG)) {
  132 + sdf = new SimpleDateFormat(DATE_FORMAT_DAY);
  133 + }
  134 + if (RegularUtils.isMatched(strDate, DATE_REG_2)) {
  135 + sdf = new SimpleDateFormat(DATE_FORMAT_DAY_2);
  136 + }
  137 + if (RegularUtils.isMatched(strDate, DATE_REG_SIMPLE_2)) {
  138 + sdf = new SimpleDateFormat(DATE_FORMAT_DAY_SIMPLE);
  139 + }
  140 + if (RegularUtils.isMatched(strDate, TIME_SEC_REG)) {
  141 + sdf = new SimpleDateFormat(TIME_FORMAT_SEC);
  142 + }
  143 + if (RegularUtils.isMatched(strDate, DATE_TIME_REG)) {
  144 + sdf = new SimpleDateFormat(DATE_FORMAT_SEC);
  145 + }
  146 + if (RegularUtils.isMatched(strDate, DATE_TIME_MSEC_REG)) {
  147 + sdf = new SimpleDateFormat(DATE_FORMAT_MSEC);
  148 + }
  149 + if (RegularUtils.isMatched(strDate, DATE_TIME_MSEC_T_REG)) {
  150 + sdf = new SimpleDateFormat(DATE_FORMAT_MSEC_T);
  151 + }
  152 + if (RegularUtils.isMatched(strDate, DATE_TIME_MSEC_T_Z_REG)) {
  153 + sdf = new SimpleDateFormat(DATE_FORMAT_MSEC_T_Z);
  154 + }
  155 + if (null != sdf) {
  156 + return sdf.parse(strDate);
  157 + }
  158 + throw new TimeMatchFormatException(
  159 + String.format("[%s] can not matching right time format", strDate));
  160 + }
  161 +
  162 + /**
  163 + * <p>字符串时间转为{@link Date}类型,未找到匹配类型则返NULL</p>
  164 + * <p>支持匹配类型列表:</p>
  165 + * <p>yyyy-MM-dd</p>
  166 + * <p>yyyy/MM/dd</p>
  167 + * <p>HH:mm:ss</p>
  168 + * <p>yyyy-MM-dd HH:mm:ss</p>
  169 + * <p>yyyy-MM-dTHH:mm:ss.SSS</p>
  170 + * <p>
  171 + * author : Crab2Died
  172 + * date : 2017年06月02日 15:21:54
  173 + *
  174 + * @param strDate 时间字符串
  175 + * @return Date {@link Date}时间
  176 + */
  177 + public static Date str2DateUnmatch2Null(String strDate) {
  178 + Date date;
  179 + try {
  180 + date = str2Date(strDate);
  181 + } catch (Exception e) {
  182 + throw new TimeMatchFormatException("[" + strDate + "] date auto parse exception", e);
  183 + }
  184 + return date;
  185 + }
  186 +
  187 +}
... ...
src/main/java/com/order/erp/common/excel4j/utils/RegularUtils.java 0 → 100644
  1 +package com.order.erp.common.excel4j.utils;
  2 +
  3 +
  4 +
  5 +import com.order.erp.common.excel4j.exceptions.IllegalGroupIndexException;
  6 +
  7 +import java.util.ArrayList;
  8 +import java.util.List;
  9 +import java.util.regex.Matcher;
  10 +import java.util.regex.Pattern;
  11 +
  12 +/**
  13 + * <p>正则匹配相关工具</p>
  14 + * author : Crab2Died
  15 + * date : 2017/5/24 9:43
  16 + */
  17 +public class RegularUtils {
  18 +
  19 + private static Pattern compile = Pattern.compile("^(\\d+)(\\.0*)?$");
  20 +
  21 + /**
  22 + * <p>判断内容是否匹配</p>
  23 + * author : Crab2Died
  24 + * date : 2017年06月02日 15:46:25
  25 + *
  26 + * @param pattern 匹配目标内容
  27 + * @param reg 正则表达式
  28 + * @return 返回boolean
  29 + */
  30 + public static boolean isMatched(String pattern, String reg) {
  31 + Pattern compile = Pattern.compile(reg);
  32 + return compile.matcher(pattern).matches();
  33 + }
  34 +
  35 + /**
  36 + * <p>正则提取匹配到的内容</p>
  37 + * <p>例如:</p>
  38 + * <p>
  39 + * author : Crab2Died
  40 + * date : 2017年06月02日 15:49:51
  41 + *
  42 + * @param pattern 匹配目标内容
  43 + * @param reg 正则表达式
  44 + * @param group 提取内容索引
  45 + * @return 提取内容集合
  46 + */
  47 + public static List<String> match(String pattern, String reg, int group) {
  48 +
  49 + List<String> matchGroups = new ArrayList<>();
  50 + Pattern compile = Pattern.compile(reg);
  51 + Matcher matcher = compile.matcher(pattern);
  52 + if (group > matcher.groupCount() || group < 0) {
  53 + throw new IllegalGroupIndexException("Illegal match group :" + group);
  54 + }
  55 + while (matcher.find()) {
  56 + matchGroups.add(matcher.group(group));
  57 + }
  58 + return matchGroups;
  59 + }
  60 +
  61 + /**
  62 + * <p>正则提取匹配到的内容,默认提取索引为0</p>
  63 + * <p>例如:</p>
  64 + * <p>
  65 + * author : Crab2Died
  66 + * date : 2017年06月02日 15:49:51
  67 + *
  68 + * @param pattern 匹配目标内容
  69 + * @param reg 正则表达式
  70 + * @return 提取内容集合
  71 + */
  72 + public static String match(String pattern, String reg) {
  73 +
  74 + String match = null;
  75 + List<String> matches = match(pattern, reg, 0);
  76 + if (null != matches && matches.size() > 0) {
  77 + match = matches.get(0);
  78 + }
  79 + return match;
  80 + }
  81 +
  82 + public static String converNumByReg(String number) {
  83 +
  84 + Matcher matcher = compile.matcher(number);
  85 + while (matcher.find()) {
  86 + number = matcher.group(1);
  87 + }
  88 + return number;
  89 + }
  90 +}
... ...
src/main/java/com/order/erp/common/excel4j/utils/Utils.java 0 → 100644
  1 +package com.order.erp.common.excel4j.utils;
  2 +
  3 +import com.order.erp.common.excel4j.annotation.ExcelField;
  4 +import com.order.erp.common.excel4j.converter.DefaultConvertible;
  5 +import com.order.erp.common.excel4j.converter.WriteConvertible;
  6 +import com.order.erp.common.excel4j.exceptions.Excel4JException;
  7 +import com.order.erp.common.excel4j.handler.ExcelHeader;
  8 +import org.apache.poi.ss.usermodel.Cell;
  9 +import org.apache.poi.ss.usermodel.CellValue;
  10 +import org.apache.poi.ss.usermodel.DateUtil;
  11 +import org.apache.poi.ss.usermodel.Row;
  12 +
  13 +import java.beans.BeanInfo;
  14 +import java.beans.IntrospectionException;
  15 +import java.beans.Introspector;
  16 +import java.beans.PropertyDescriptor;
  17 +import java.lang.reflect.Field;
  18 +import java.lang.reflect.InvocationTargetException;
  19 +import java.lang.reflect.Method;
  20 +import java.math.BigDecimal;
  21 +import java.util.*;
  22 +import java.util.regex.Pattern;
  23 +
  24 +/**
  25 + * Excel4J工具类
  26 + */
  27 +public class Utils {
  28 +
  29 + /**
  30 + * getter或setter枚举
  31 + */
  32 + public enum FieldAccessType {
  33 +
  34 + GETTER, SETTER
  35 + }
  36 +
  37 + /**
  38 + * <p>根据JAVA对象注解获取Excel表头信息</p>
  39 + *
  40 + * @param clz 类型
  41 + * @return 表头信息
  42 + */
  43 + public static List<ExcelHeader> getHeaderList(Class<?> clz) throws Excel4JException {
  44 +
  45 + List<ExcelHeader> headers = new ArrayList<>();
  46 + List<Field> fields = new ArrayList<>();
  47 + for (Class<?> clazz = clz; clazz != Object.class; clazz = clazz.getSuperclass()) {
  48 + fields.addAll(Arrays.asList(clazz.getDeclaredFields()));
  49 + }
  50 + for (Field field : fields) {
  51 + // 是否使用ExcelField注解
  52 + if (field.isAnnotationPresent(ExcelField.class)) {
  53 + ExcelField er = field.getAnnotation(ExcelField.class);
  54 + try {
  55 + headers.add(new ExcelHeader(
  56 + er.title(),
  57 + er.order(),
  58 + er.writeConverter().newInstance(),
  59 + er.readConverter().newInstance(),
  60 + field.getName(),
  61 + field.getType()
  62 + ));
  63 + } catch (InstantiationException | IllegalAccessException e) {
  64 + throw new Excel4JException(e);
  65 + }
  66 + }
  67 + }
  68 + Collections.sort(headers);
  69 + return headers;
  70 + }
  71 +
  72 + /**
  73 + * 获取excel列表头
  74 + *
  75 + * @param titleRow excel行
  76 + * @param clz 类型
  77 + * @return ExcelHeader集合
  78 + * @throws Excel4JException 异常
  79 + */
  80 + public static Map<Integer, ExcelHeader> getHeaderMap(Row titleRow, Class<?> clz)
  81 + throws Excel4JException {
  82 +
  83 + List<ExcelHeader> headers = getHeaderList(clz);
  84 + Map<Integer, ExcelHeader> maps = new HashMap<>();
  85 + for (Cell c : titleRow) {
  86 + String title = c.getStringCellValue();
  87 + for (ExcelHeader eh : headers) {
  88 + if (eh.getTitle().equals(title.trim())) {
  89 + maps.put(c.getColumnIndex(), eh);
  90 + break;
  91 + }
  92 + }
  93 + }
  94 + return maps;
  95 + }
  96 +
  97 + /**
  98 + * 获取单元格内容
  99 + *
  100 + * @param c 单元格
  101 + * @return 单元格内容
  102 + */
  103 + public static String getCellValue(Cell c) {
  104 + String o;
  105 + switch (c.getCellTypeEnum()) {
  106 + case BLANK:
  107 + o = "";
  108 + break;
  109 + case BOOLEAN:
  110 + o = String.valueOf(c.getBooleanCellValue());
  111 + break;
  112 + case FORMULA:
  113 + o = calculationFormula(c);
  114 + break;
  115 + case NUMERIC:
  116 + if (DateUtil.isCellDateFormatted(c)) {
  117 + o = DateUtils.date2Str(c.getDateCellValue());
  118 + } else {
  119 + o = String.valueOf(c.getNumericCellValue());
  120 + o = matchDoneBigDecimal(o);
  121 + o = RegularUtils.converNumByReg(o);
  122 + }
  123 + break;
  124 + case STRING:
  125 + o = c.getStringCellValue();
  126 + break;
  127 + default:
  128 + o = null;
  129 + break;
  130 + }
  131 + return o;
  132 + }
  133 +
  134 + /**
  135 + * 字符串转对象
  136 + *
  137 + * @param strField 字符串
  138 + * @param clazz 待转类型
  139 + * @return 转换后数据
  140 + */
  141 + public static Object str2TargetClass(String strField, Class<?> clazz) {
  142 + if (null == strField || "".equals(strField)) {
  143 + return null;
  144 + }
  145 + if ((Long.class == clazz) || (long.class == clazz)) {
  146 + strField = matchDoneBigDecimal(strField);
  147 + strField = RegularUtils.converNumByReg(strField);
  148 + return Long.parseLong(strField);
  149 + }
  150 + if ((Integer.class == clazz) || (int.class == clazz)) {
  151 + strField = matchDoneBigDecimal(strField);
  152 + strField = RegularUtils.converNumByReg(strField);
  153 + return Integer.parseInt(strField);
  154 + }
  155 + if ((Float.class == clazz) || (float.class == clazz)) {
  156 + strField = matchDoneBigDecimal(strField);
  157 + return Float.parseFloat(strField);
  158 + }
  159 + if ((Double.class == clazz) || (double.class == clazz)) {
  160 + strField = matchDoneBigDecimal(strField);
  161 + return Double.parseDouble(strField);
  162 + }
  163 + if ((Character.class == clazz) || (char.class == clazz)) {
  164 + return strField.toCharArray()[0];
  165 + }
  166 + if ((Boolean.class == clazz) || (boolean.class == clazz)) {
  167 + return Boolean.parseBoolean(strField);
  168 + }
  169 + if (Date.class == clazz) {
  170 + return DateUtils.str2DateUnmatch2Null(strField);
  171 + }
  172 + return strField;
  173 + }
  174 +
  175 + /**
  176 + * 科学计数法数据转换
  177 + *
  178 + * @param bigDecimal 科学计数法
  179 + * @return 数据字符串
  180 + */
  181 + private static String matchDoneBigDecimal(String bigDecimal) {
  182 + // 对科学计数法进行处理
  183 + boolean flg = Pattern.matches("^-?\\d+(\\.\\d+)?(E-?\\d+)?$", bigDecimal);
  184 + if (flg) {
  185 + BigDecimal bd = new BigDecimal(bigDecimal);
  186 + bigDecimal = bd.toPlainString();
  187 + }
  188 + return bigDecimal;
  189 + }
  190 +
  191 + /**
  192 + * <p>根据java对象属性{@link Field}获取该属性的getter或setter方法名,
  193 + * 另对{@link boolean}及{@link Boolean}做了行管处理</p>
  194 + *
  195 + * @param clazz 操作对象
  196 + * @param fieldName 对象属性
  197 + * @param methodType 方法类型,getter或setter枚举
  198 + * @return getter或setter方法
  199 + * @throws IntrospectionException 异常
  200 + * @author Crab2Died
  201 + */
  202 + public static Method getterOrSetter(Class clazz, String fieldName, FieldAccessType methodType)
  203 + throws IntrospectionException {
  204 +
  205 + if (null == fieldName || "".equals(fieldName)) {
  206 + return null;
  207 + }
  208 +
  209 + BeanInfo beanInfo = Introspector.getBeanInfo(clazz);
  210 + PropertyDescriptor[] props = beanInfo.getPropertyDescriptors();
  211 + for (PropertyDescriptor prop : props) {
  212 + if (fieldName.equals(prop.getName())) {
  213 + if (FieldAccessType.SETTER == methodType) {
  214 + return prop.getWriteMethod();
  215 + }
  216 + if (FieldAccessType.GETTER == methodType) {
  217 + return prop.getReadMethod();
  218 + }
  219 + }
  220 + }
  221 + throw new IntrospectionException("Can not get the getter or setter method");
  222 + }
  223 +
  224 + /**
  225 + * <p>根据对象的属性名{@code fieldName}获取某个java的属性{@link Field}</p>
  226 + *
  227 + * @param clazz java对象的class属性
  228 + * @param fieldName 属性名
  229 + * @return {@link Field} java对象的属性
  230 + * @author Crab2Died
  231 + */
  232 + private static Field matchClassField(Class clazz, String fieldName) {
  233 +
  234 + List<Field> fields = new ArrayList<>();
  235 + for (; clazz != Object.class; clazz = clazz.getSuperclass()) {
  236 + fields.addAll(Arrays.asList(clazz.getDeclaredFields()));
  237 + }
  238 + for (Field field : fields) {
  239 + if (fieldName.equals(field.getName())) {
  240 + return field;
  241 + }
  242 + }
  243 + throw new IllegalArgumentException("[" + clazz.getName() + "] can`t found field with [" + fieldName + "]");
  244 + }
  245 +
  246 + /**
  247 + * 根据属性名与属性类型获取字段内容
  248 + *
  249 + * @param bean 对象
  250 + * @param fieldName 字段名
  251 + * @param writeConvertible 写入转换器
  252 + * @return 对象指定字段内容
  253 + * @throws Excel4JException 异常
  254 + */
  255 + public static String getProperty(Object bean, String fieldName, WriteConvertible writeConvertible)
  256 + throws Excel4JException {
  257 +
  258 + if (bean == null || fieldName == null) {
  259 + throw new IllegalArgumentException("Operating bean or filed class must not be null");
  260 + }
  261 + Method method;
  262 + Object object;
  263 + try {
  264 + method = getterOrSetter(bean.getClass(), fieldName, FieldAccessType.GETTER);
  265 + object = method.invoke(bean);
  266 + } catch (IntrospectionException | IllegalAccessException | InvocationTargetException e) {
  267 + throw new Excel4JException(e);
  268 + }
  269 + if (null != writeConvertible && writeConvertible.getClass() != DefaultConvertible.class) {
  270 + // 写入转换器
  271 + object = writeConvertible.execWrite(object);
  272 + }
  273 + return object == null ? "" : object.toString();
  274 + }
  275 +
  276 + /**
  277 + * 根据属性名与属性类型获取字段内容
  278 + *
  279 + * @param bean 对象
  280 + * @param name 字段名
  281 + * @param value 字段类型
  282 + */
  283 + public static void copyProperty(Object bean, String name, Object value)
  284 + throws Excel4JException {
  285 +
  286 + if (null == name || null == value) {
  287 + return;
  288 + }
  289 + Field field = matchClassField(bean.getClass(), name);
  290 + if (null == field) {
  291 + return;
  292 + }
  293 + Method method;
  294 + try {
  295 + method = getterOrSetter(bean.getClass(), name, FieldAccessType.SETTER);
  296 +
  297 + if (value.getClass() == field.getType()) {
  298 + method.invoke(bean, value);
  299 + } else {
  300 + method.invoke(bean, str2TargetClass(value.toString(), field.getType()));
  301 + }
  302 + } catch (IntrospectionException | IllegalAccessException | InvocationTargetException e) {
  303 + throw new Excel4JException(e);
  304 + }
  305 +
  306 + }
  307 +
  308 + /**
  309 + * 计算公式结果
  310 + *
  311 + * @param cell 单元格类型为公式的单元格
  312 + * @return 返回单元格计算后的值 格式化成String
  313 + * @author QingMings
  314 + * Email:1821063757@qq.com
  315 + * date 2018-01-13
  316 + */
  317 + public static String calculationFormula(Cell cell) {
  318 +
  319 + CellValue cellValue = cell.getSheet().getWorkbook().getCreationHelper()
  320 + .createFormulaEvaluator().evaluate(cell);
  321 + return cellValue.formatAsString();
  322 + }
  323 +}
... ...
src/main/java/com/order/erp/common/excel4j/wrapper/MapSheetWrapper.java 0 → 100644
  1 +package com.order.erp.common.excel4j.wrapper;
  2 +
  3 +import java.util.List;
  4 +import java.util.Map;
  5 +
  6 +/**
  7 + * <p>基于模板、注解的Map数据导出的sheet包装类</p>
  8 + */
  9 +public class MapSheetWrapper {
  10 +
  11 + /**
  12 + * sheet序号
  13 + */
  14 + private int sheetIndex;
  15 +
  16 + /**
  17 + * 表格行数据
  18 + */
  19 + private Map<String, List<?>> data;
  20 +
  21 + /**
  22 + * 扩展数据
  23 + */
  24 + private Map<String, String> extendMap;
  25 +
  26 + /**
  27 + * 注解的class
  28 + */
  29 + private Class clazz;
  30 +
  31 + /**
  32 + * 是否写表头
  33 + */
  34 + private boolean isWriteHeader;
  35 +
  36 + public MapSheetWrapper() {
  37 + }
  38 +
  39 + public MapSheetWrapper(Map<String, List<?>> data, Class clazz) {
  40 + this.data = data;
  41 + this.clazz = clazz;
  42 + }
  43 +
  44 + public MapSheetWrapper(int sheetIndex, Map<String, List<?>> data, Class clazz) {
  45 + this.sheetIndex = sheetIndex;
  46 + this.data = data;
  47 + this.clazz = clazz;
  48 + }
  49 +
  50 + public MapSheetWrapper(Map<String, List<?>> data, Map<String, String> extendMap, Class clazz) {
  51 + this.data = data;
  52 + this.extendMap = extendMap;
  53 + this.clazz = clazz;
  54 + }
  55 +
  56 + public MapSheetWrapper(int sheetIndex, Map<String, List<?>> data, Map<String, String> extendMap, Class clazz,
  57 + boolean isWriteHeader) {
  58 + this.sheetIndex = sheetIndex;
  59 + this.data = data;
  60 + this.extendMap = extendMap;
  61 + this.clazz = clazz;
  62 + this.isWriteHeader = isWriteHeader;
  63 + }
  64 +
  65 + public int getSheetIndex() {
  66 + return sheetIndex;
  67 + }
  68 +
  69 + public void setSheetIndex(int sheetIndex) {
  70 + this.sheetIndex = sheetIndex;
  71 + }
  72 +
  73 + public Map<String, List<?>> getData() {
  74 + return data;
  75 + }
  76 +
  77 + public void setData(Map<String, List<?>> data) {
  78 + this.data = data;
  79 + }
  80 +
  81 + public Map<String, String> getExtendMap() {
  82 + return extendMap;
  83 + }
  84 +
  85 + public void setExtendMap(Map<String, String> extendMap) {
  86 + this.extendMap = extendMap;
  87 + }
  88 +
  89 + public Class getClazz() {
  90 + return clazz;
  91 + }
  92 +
  93 + public void setClazz(Class clazz) {
  94 + this.clazz = clazz;
  95 + }
  96 +
  97 + public boolean isWriteHeader() {
  98 + return isWriteHeader;
  99 + }
  100 +
  101 + public void setWriteHeader(boolean writeHeader) {
  102 + isWriteHeader = writeHeader;
  103 + }
  104 +}
... ...
src/main/java/com/order/erp/common/excel4j/wrapper/NoTemplateSheetWrapper.java 0 → 100644
  1 +package com.order.erp.common.excel4j.wrapper;
  2 +
  3 +import java.util.List;
  4 +
  5 +/**
  6 + * <p>无模板、基于注解导出的sheet包装类</p>
  7 + */
  8 +public class NoTemplateSheetWrapper {
  9 +
  10 + /**
  11 + * 待导出行数据
  12 + */
  13 + private List<?> data;
  14 +
  15 + /**
  16 + * 基于注解的class
  17 + */
  18 + private Class clazz;
  19 +
  20 + /**
  21 + * 是否写入表头
  22 + */
  23 + private boolean isWriteHeader;
  24 +
  25 + /**
  26 + * sheet名
  27 + */
  28 + private String sheetName;
  29 +
  30 + public NoTemplateSheetWrapper() {
  31 + }
  32 +
  33 + public NoTemplateSheetWrapper(List<?> data, Class clazz) {
  34 + this.data = data;
  35 + this.clazz = clazz;
  36 + }
  37 +
  38 + public NoTemplateSheetWrapper(List<?> data, Class clazz, boolean isWriteHeader) {
  39 + this.data = data;
  40 + this.clazz = clazz;
  41 + this.isWriteHeader = isWriteHeader;
  42 + }
  43 +
  44 + public NoTemplateSheetWrapper(List<?> data, Class clazz, boolean isWriteHeader, String sheetName) {
  45 + this.data = data;
  46 + this.clazz = clazz;
  47 + this.isWriteHeader = isWriteHeader;
  48 + this.sheetName = sheetName;
  49 + }
  50 +
  51 + public List<?> getData() {
  52 + return data;
  53 + }
  54 +
  55 + public void setData(List<?> data) {
  56 + this.data = data;
  57 + }
  58 +
  59 + public Class getClazz() {
  60 + return clazz;
  61 + }
  62 +
  63 + public void setClazz(Class clazz) {
  64 + this.clazz = clazz;
  65 + }
  66 +
  67 + public boolean isWriteHeader() {
  68 + return isWriteHeader;
  69 + }
  70 +
  71 + public void setWriteHeader(boolean writeHeader) {
  72 + isWriteHeader = writeHeader;
  73 + }
  74 +
  75 + public String getSheetName() {
  76 + return sheetName;
  77 + }
  78 +
  79 + public void setSheetName(String sheetName) {
  80 + this.sheetName = sheetName;
  81 + }
  82 +}
... ...
src/main/java/com/order/erp/common/excel4j/wrapper/NormalSheetWrapper.java 0 → 100644
  1 +package com.order.erp.common.excel4j.wrapper;
  2 +
  3 +import java.util.List;
  4 +import java.util.Map;
  5 +
  6 +/**
  7 + * <p>基于模板、注解的通用sheet包装类</p>
  8 + */
  9 +public class NormalSheetWrapper {
  10 +
  11 + /**
  12 + * sheet的序号
  13 + */
  14 + private int sheetIndex;
  15 +
  16 + /**
  17 + * 表格行数据
  18 + */
  19 + private List<?> data;
  20 +
  21 + /**
  22 + * 扩张数据
  23 + */
  24 + private Map<String, String> extendMap;
  25 +
  26 + /**
  27 + * 基于注解的class
  28 + */
  29 + private Class clazz;
  30 +
  31 + /**
  32 + * 是否写入表头
  33 + */
  34 + private boolean isWriteHeader;
  35 +
  36 + public NormalSheetWrapper() {
  37 + }
  38 +
  39 + public NormalSheetWrapper(List<?> data, Class clazz) {
  40 + this.data = data;
  41 + this.clazz = clazz;
  42 + }
  43 +
  44 + public NormalSheetWrapper(int sheetIndex, List<?> data, Class clazz) {
  45 + this.sheetIndex = sheetIndex;
  46 + this.data = data;
  47 + this.clazz = clazz;
  48 + }
  49 +
  50 + public NormalSheetWrapper(int sheetIndex, List<?> data, Map<String, String> extendMap, Class clazz,
  51 + boolean isWriteHeader) {
  52 + this.sheetIndex = sheetIndex;
  53 + this.data = data;
  54 + this.extendMap = extendMap;
  55 + this.clazz = clazz;
  56 + this.isWriteHeader = isWriteHeader;
  57 + }
  58 +
  59 + public int getSheetIndex() {
  60 + return sheetIndex;
  61 + }
  62 +
  63 + public void setSheetIndex(int sheetIndex) {
  64 + this.sheetIndex = sheetIndex;
  65 + }
  66 +
  67 + public List<?> getData() {
  68 + return data;
  69 + }
  70 +
  71 + public void setData(List<?> data) {
  72 + this.data = data;
  73 + }
  74 +
  75 + public Map<String, String> getExtendMap() {
  76 + return extendMap;
  77 + }
  78 +
  79 + public void setExtendMap(Map<String, String> extendMap) {
  80 + this.extendMap = extendMap;
  81 + }
  82 +
  83 + public Class getClazz() {
  84 + return clazz;
  85 + }
  86 +
  87 + public void setClazz(Class clazz) {
  88 + this.clazz = clazz;
  89 + }
  90 +
  91 + public boolean isWriteHeader() {
  92 + return isWriteHeader;
  93 + }
  94 +
  95 + public void setWriteHeader(boolean writeHeader) {
  96 + isWriteHeader = writeHeader;
  97 + }
  98 +}
... ...
src/main/java/com/order/erp/common/excel4j/wrapper/SimpleSheetWrapper.java 0 → 100644
  1 +package com.order.erp.common.excel4j.wrapper;
  2 +
  3 +import java.util.List;
  4 +
  5 +/**
  6 + * <p>无模板,无注解的简单sheet包装类</p>
  7 + */
  8 +public class SimpleSheetWrapper {
  9 +
  10 + /**
  11 + * 每个sheet的列表数据
  12 + */
  13 + private List<?> data;
  14 +
  15 + /**
  16 + * 每个sheet的表头
  17 + */
  18 + private List<String> header;
  19 +
  20 + /**
  21 + * 每个sheet的名字
  22 + */
  23 + private String sheetName;
  24 +
  25 + public SimpleSheetWrapper() {
  26 + }
  27 +
  28 + public SimpleSheetWrapper(List<?> data, List<String> header, String sheetName) {
  29 + this.data = data;
  30 + this.header = header;
  31 + this.sheetName = sheetName;
  32 + }
  33 +
  34 + public SimpleSheetWrapper(List<?> data, List<String> header) {
  35 + this.data = data;
  36 + this.header = header;
  37 + }
  38 +
  39 + public SimpleSheetWrapper(List<?> data, String sheetName) {
  40 + this.data = data;
  41 + this.sheetName = sheetName;
  42 + }
  43 +
  44 + public SimpleSheetWrapper(List<?> data) {
  45 + this.data = data;
  46 + }
  47 +
  48 + public List<?> getData() {
  49 + return data;
  50 + }
  51 +
  52 + public void setData(List<?> data) {
  53 + this.data = data;
  54 + }
  55 +
  56 + public List<String> getHeader() {
  57 + return header;
  58 + }
  59 +
  60 + public void setHeader(List<String> header) {
  61 + this.header = header;
  62 + }
  63 +
  64 + public String getSheetName() {
  65 + return sheetName;
  66 + }
  67 +
  68 + public void setSheetName(String sheetName) {
  69 + this.sheetName = sheetName;
  70 + }
  71 +}
... ...
src/main/java/com/order/erp/config/AdminMetaObjectHandler.java
... ... @@ -30,14 +30,18 @@ public class AdminMetaObjectHandler implements MetaObjectHandler {
30 30 this.strictInsertFill(metaObject, CREATE_TIME, LocalDateTime.class, now);
31 31 this.strictInsertFill(metaObject, MODIFY_TIME, LocalDateTime.class, now);
32 32 this.strictInsertFill(metaObject, ENABLE_FLAG, Integer.class, Constant.ENABLE_TEN);
33   - UserDetails loginUser = SecurityUtils.getUserDetails();
34   - if (null == loginUser) {
35   - return;
36   - }
  33 + try {
  34 + UserDetails loginUser = SecurityUtils.getUserDetails();
  35 +
  36 + this.strictInsertFill(metaObject, CREATE_BY, String.class, loginUser.getUsername());
  37 +
  38 + this.strictInsertFill(metaObject, MODIFY_BY, String.class, loginUser.getUsername());
  39 + }catch (Exception e) {
  40 + this.strictInsertFill(metaObject, CREATE_BY, String.class, "system");
37 41  
38   - this.strictInsertFill(metaObject, CREATE_BY, String.class, loginUser.getUsername());
  42 + this.strictInsertFill(metaObject, MODIFY_BY, String.class, "system");
  43 + }
39 44  
40   - this.strictInsertFill(metaObject, MODIFY_BY, String.class, loginUser.getUsername());
41 45  
42 46 }
43 47  
... ... @@ -46,10 +50,16 @@ public class AdminMetaObjectHandler implements MetaObjectHandler {
46 50  
47 51 this.strictUpdateFill(metaObject, MODIFY_TIME, LocalDateTime.class, LocalDateTime.now());
48 52  
49   - UserDetails loginUser = SecurityUtils.getUserDetails();
50   - if (null == loginUser) {
51   - return;
  53 +
  54 + try {
  55 + UserDetails loginUser = SecurityUtils.getUserDetails();
  56 + if (null == loginUser) {
  57 + return;
  58 + }
  59 + this.strictUpdateFill(metaObject, MODIFY_BY, String.class, loginUser.getUsername());
  60 + }catch (Exception e) {
  61 + this.strictUpdateFill(metaObject, MODIFY_BY, String.class, "system");
52 62 }
53   - this.strictUpdateFill(metaObject, MODIFY_BY, String.class, loginUser.getUsername());
  63 +
54 64 }
55 65 }
... ...
src/main/java/com/order/erp/controller/DeptController.java
1 1 package com.order.erp.controller;
2 2  
  3 +import com.order.erp.common.annotation.AnonymousAccess;
3 4 import com.order.erp.common.constant.ServerResult;
4 5 import com.order.erp.domain.vo.admin.AdminDeptQueryVO;
5 6 import com.order.erp.domain.vo.admin.AdminDeptVO;
... ... @@ -28,7 +29,7 @@ public class DeptController {
28 29 @Log("查询部门")
29 30 @ApiOperation("查询部门")
30 31 @PostMapping(value = "/list_by_page")
31   - @PreAuthorize("@el.check('user:list','dept:list')")
  32 + @AnonymousAccess
32 33 public ServerResult listByPage(@RequestBody @Validated AdminDeptQueryVO queryVO) {
33 34 return deptService.list(queryVO);
34 35 }
... ... @@ -36,7 +37,7 @@ public class DeptController {
36 37 @Log("新增部门")
37 38 @ApiOperation("新增部门")
38 39 @PostMapping("/add")
39   - @PreAuthorize("@el.check('dept:add')")
  40 + @AnonymousAccess
40 41 public ServerResult add(@RequestBody @Validated AdminDeptVO deptVO) {
41 42 return deptService.add(deptVO);
42 43 }
... ... @@ -44,7 +45,7 @@ public class DeptController {
44 45 @Log("修改部门")
45 46 @ApiOperation("修改部门")
46 47 @PutMapping
47   - @PreAuthorize("@el.check('dept:edit')")
  48 + @AnonymousAccess
48 49 public ServerResult edit(@RequestBody @Validated AdminDeptVO deptVO) {
49 50 return deptService.edit(deptVO);
50 51 }
... ... @@ -52,7 +53,7 @@ public class DeptController {
52 53 @Log("删除部门")
53 54 @ApiOperation("删除部门")
54 55 @DeleteMapping
55   - @PreAuthorize("@el.check('dept:del')")
  56 + @AnonymousAccess
56 57 public ServerResult delete(@RequestBody @Validated AdminDeptQueryVO queryVO) {
57 58 return deptService.deleteById(queryVO);
58 59 }
... ...
src/main/java/com/order/erp/controller/DictionaryController.java
1 1 package com.order.erp.controller;
2 2  
  3 +import com.order.erp.common.annotation.AnonymousAccess;
3 4 import com.order.erp.common.constant.ServerResult;
4 5 import com.order.erp.domain.vo.admin.DictionaryQueryVO;
5 6 import com.order.erp.domain.vo.admin.DictionaryVO;
... ... @@ -31,7 +32,7 @@ public class DictionaryController {
31 32 @Log("查询字典列表")
32 33 @ApiOperation("查询字典列表")
33 34 @PostMapping(value = "/list_by_page")
34   - @PreAuthorize("@el.check('user:list','dept:list')")
  35 + @AnonymousAccess
35 36 public ServerResult listByPage(@RequestBody @Validated DictionaryQueryVO queryVO) {
36 37 return dictionaryService.listByPage(queryVO);
37 38 }
... ... @@ -39,7 +40,7 @@ public class DictionaryController {
39 40 @Log("获取所有字典")
40 41 @ApiOperation("获取所有字典")
41 42 @PostMapping(value = "/get_all")
42   - @PreAuthorize("@el.check('user:list','dept:list')")
  43 + @AnonymousAccess
43 44 public ServerResult getAll(@RequestBody @Validated DictionaryQueryVO queryVO) {
44 45 return dictionaryService.getAll(queryVO);
45 46 }
... ... @@ -47,7 +48,7 @@ public class DictionaryController {
47 48 @Log("新增字典")
48 49 @ApiOperation("新增字典")
49 50 @PostMapping("/add")
50   - @PreAuthorize("@el.check('dept:add')")
  51 + @AnonymousAccess
51 52 public ServerResult add(@RequestBody @Validated DictionaryVO dictionaryVO) {
52 53 return dictionaryService.add(dictionaryVO);
53 54 }
... ... @@ -55,7 +56,7 @@ public class DictionaryController {
55 56 @Log("修改字典")
56 57 @ApiOperation("修改字典")
57 58 @PostMapping("/edit")
58   - @PreAuthorize("@el.check('dept:edit')")
  59 + @AnonymousAccess
59 60 public ServerResult edit(@RequestBody @Validated DictionaryVO dictionaryVO) {
60 61 return dictionaryService.edit(dictionaryVO);
61 62 }
... ... @@ -63,7 +64,7 @@ public class DictionaryController {
63 64 @Log("删除字典")
64 65 @ApiOperation("删除字典")
65 66 @PostMapping("/delete")
66   - @PreAuthorize("@el.check('dept:del')")
  67 + @AnonymousAccess
67 68 public ServerResult delete(@RequestBody @Validated DictionaryQueryVO queryVO) {
68 69 return dictionaryService.deleteById(queryVO);
69 70 }
... ...
src/main/java/com/order/erp/controller/JobController.java
1 1 package com.order.erp.controller;
2 2  
  3 +import com.order.erp.common.annotation.AnonymousAccess;
3 4 import com.order.erp.common.constant.ServerResult;
4 5 import com.order.erp.domain.vo.admin.AdminJobQueryVO;
5 6 import com.order.erp.domain.vo.admin.AdminJobVO;
... ... @@ -30,7 +31,7 @@ public class JobController {
30 31 @Log("查询岗位")
31 32 @ApiOperation("查询岗位")
32 33 @PostMapping(value = "/list_by_page")
33   - @PreAuthorize("@el.check('job:list','user:list')")
  34 + @AnonymousAccess
34 35 public ServerResult listByPage(@RequestBody @Validated AdminJobQueryVO queryVO) {
35 36 return jobService.list(queryVO);
36 37 }
... ... @@ -38,7 +39,7 @@ public class JobController {
38 39 @Log("新增岗位")
39 40 @ApiOperation("新增岗位")
40 41 @PostMapping(value = "/add")
41   - @PreAuthorize("@el.check('job:add')")
  42 + @AnonymousAccess
42 43 public ServerResult add(@RequestBody @Validated AdminJobVO jobVO) {
43 44 return jobService.add(jobVO);
44 45 }
... ... @@ -46,7 +47,7 @@ public class JobController {
46 47 @Log("修改岗位")
47 48 @ApiOperation("修改岗位")
48 49 @PostMapping(value = "/edit")
49   - @PreAuthorize("@el.check('job:edit')")
  50 + @AnonymousAccess
50 51 public ServerResult edit(@RequestBody @Validated AdminJobVO jobVO) {
51 52 return jobService.edit(jobVO);
52 53 }
... ... @@ -54,7 +55,7 @@ public class JobController {
54 55 @Log("删除岗位")
55 56 @ApiOperation("删除岗位")
56 57 @PostMapping(value = "/delete")
57   - @PreAuthorize("@el.check('job:del')")
  58 + @AnonymousAccess
58 59 public ServerResult delete(@RequestBody @Validated AdminJobQueryVO queryVO) {
59 60 return jobService.deleteById(queryVO);
60 61 }
... ...
src/main/java/com/order/erp/controller/MenuController.java
1 1 package com.order.erp.controller;
2 2  
  3 +import com.order.erp.common.annotation.AnonymousAccess;
3 4 import com.order.erp.common.constant.ServerResult;
4 5 import com.order.erp.domain.vo.admin.AdminMenuQueryVO;
5 6 import com.order.erp.domain.vo.admin.AdminMenuVO;
... ... @@ -30,13 +31,14 @@ public class MenuController {
30 31  
31 32 @ApiOperation("获取前端所需菜单")
32 33 @PostMapping(value = "/build")
  34 + @AnonymousAccess
33 35 public ServerResult buildMenus() {
34 36 return ServerResult.success();
35 37 }
36 38  
37 39 @ApiOperation("返回全部的菜单")
38 40 @PostMapping(value = "/tree")
39   - @PreAuthorize("@el.check('menu:list','roles:list')")
  41 + @AnonymousAccess
40 42 public ServerResult getMenuTree() {
41 43 return ServerResult.success();
42 44 }
... ... @@ -44,7 +46,7 @@ public class MenuController {
44 46 @Log("查询菜单")
45 47 @ApiOperation("查询菜单")
46 48 @PostMapping(value = "/all")
47   - @PreAuthorize("@el.check('menu:list')")
  49 + @AnonymousAccess
48 50 public ServerResult all(@RequestBody @Validated AdminMenuQueryVO queryVO) {
49 51 return menuService.all(queryVO);
50 52 }
... ... @@ -52,7 +54,7 @@ public class MenuController {
52 54 @Log("新增菜单")
53 55 @ApiOperation("新增菜单")
54 56 @PostMapping(value = "/add")
55   - @PreAuthorize("@el.check('menu:add')")
  57 + @AnonymousAccess
56 58 public ServerResult add(@RequestBody @Validated AdminMenuVO menuVO) {
57 59 return menuService.add(menuVO);
58 60 }
... ... @@ -60,7 +62,7 @@ public class MenuController {
60 62 @Log("修改菜单")
61 63 @ApiOperation("修改菜单")
62 64 @PostMapping(value = "/edit")
63   - @PreAuthorize("@el.check('menu:edit')")
  65 + @AnonymousAccess
64 66 public ServerResult edit(@RequestBody @Validated AdminMenuVO menuVO) {
65 67 return menuService.edit(menuVO);
66 68 }
... ... @@ -68,7 +70,7 @@ public class MenuController {
68 70 @Log("删除菜单")
69 71 @ApiOperation("删除菜单")
70 72 @PostMapping(value = "/delete")
71   - @PreAuthorize("@el.check('menu:del')")
  73 + @AnonymousAccess
72 74 public ServerResult delete(@RequestBody @Validated AdminMenuQueryVO queryVO) {
73 75 return menuService.deleteById(queryVO);
74 76 }
... ...
src/main/java/com/order/erp/controller/OrderAuditLogController.java
1 1 package com.order.erp.controller;
2 2  
  3 +import com.order.erp.common.annotation.AnonymousAccess;
3 4 import com.order.erp.common.constant.ServerResult;
4 5 import com.order.erp.domain.vo.order.OrderAuditLogQueryVO;
5 6 import com.order.erp.service.order.OrderAuditLogService;
... ... @@ -33,6 +34,7 @@ public class OrderAuditLogController {
33 34 * @return 查询结果
34 35 */
35 36 @PostMapping("/list")
  37 + @AnonymousAccess
36 38 public ServerResult list(@RequestBody @Validated OrderAuditLogQueryVO orderAuditLogQueryVO) {
37 39 return orderAuditLogService.list(orderAuditLogQueryVO);
38 40 }
... ... @@ -44,6 +46,7 @@ public class OrderAuditLogController {
44 46 * @return 单条数据
45 47 */
46 48 @PostMapping("/query_by_id")
  49 + @AnonymousAccess
47 50 public ServerResult queryById(@RequestBody OrderAuditLogQueryVO orderAuditLogQueryVO) {
48 51 return orderAuditLogService.queryById(orderAuditLogQueryVO);
49 52 }
... ...
src/main/java/com/order/erp/controller/OrderController.java
... ... @@ -2,7 +2,11 @@ package com.order.erp.controller;
2 2  
3 3 import com.order.erp.common.annotation.AnonymousAccess;
4 4 import com.order.erp.common.constant.ServerResult;
5   -import com.order.erp.domain.vo.order.*;
  5 +import com.order.erp.common.excel4j.exceptions.Excel4JException;
  6 +import com.order.erp.domain.vo.order.OrderAddVO;
  7 +import com.order.erp.domain.vo.order.OrderBaseInfoQueryVO;
  8 +import com.order.erp.domain.vo.order.OrderBaseInfoVO;
  9 +import com.order.erp.domain.vo.order.OrderUnlockFieldApplyVO;
6 10 import com.order.erp.service.order.OrderBaseInfoService;
7 11 import org.springframework.validation.annotation.Validated;
8 12 import org.springframework.web.bind.annotation.PostMapping;
... ... @@ -11,6 +15,8 @@ import org.springframework.web.bind.annotation.RequestMapping;
11 15 import org.springframework.web.bind.annotation.RestController;
12 16  
13 17 import javax.annotation.Resource;
  18 +import javax.servlet.http.HttpServletResponse;
  19 +import java.io.IOException;
14 20  
15 21 /**
16 22 * 订单基础信息表(OrderBaseInfo)表控制层
... ... @@ -40,6 +46,18 @@ public class OrderController {
40 46 }
41 47  
42 48 /**
  49 + * 导出订单
  50 + *
  51 + * @param orderBaseInfoQueryVO 查询条件
  52 + * @return 查询结果
  53 + */
  54 + @PostMapping("/export")
  55 + @AnonymousAccess
  56 + public ServerResult export(HttpServletResponse response, @RequestBody @Validated OrderBaseInfoQueryVO orderBaseInfoQueryVO) throws IOException, Excel4JException {
  57 + return orderBaseInfoService.export(response, orderBaseInfoQueryVO);
  58 + }
  59 +
  60 + /**
43 61 * 通过主键查询单条数据
44 62 *
45 63 * @param orderBaseInfoQueryVO 查询条件
... ...
src/main/java/com/order/erp/controller/OrderFieldLockApplyController.java
1 1 package com.order.erp.controller;
2 2  
  3 +import com.order.erp.common.annotation.AnonymousAccess;
3 4 import com.order.erp.common.constant.ServerResult;
4 5 import com.order.erp.domain.vo.order.OrderFieldLockApplyQueryVO;
5 6 import com.order.erp.domain.vo.order.OrderFieldLockApplyVO;
... ... @@ -34,6 +35,7 @@ public class OrderFieldLockApplyController {
34 35 * @return 查询结果
35 36 */
36 37 @PostMapping("/list")
  38 + @AnonymousAccess
37 39 public ServerResult list(@RequestBody @Validated OrderFieldLockApplyQueryVO orderFieldLockApplyQueryVO) {
38 40 return orderFieldLockApplyService.list(orderFieldLockApplyQueryVO);
39 41 }
... ... @@ -45,6 +47,7 @@ public class OrderFieldLockApplyController {
45 47 * @return 单条数据
46 48 */
47 49 @PostMapping("/query_by_id")
  50 + @AnonymousAccess
48 51 public ServerResult queryById(@RequestBody OrderFieldLockApplyQueryVO orderFieldLockApplyQueryVO) {
49 52 return orderFieldLockApplyService.queryById(orderFieldLockApplyQueryVO);
50 53 }
... ... @@ -56,6 +59,7 @@ public class OrderFieldLockApplyController {
56 59 * @return 新增结果
57 60 */
58 61 @PostMapping("/add")
  62 + @AnonymousAccess
59 63 public ServerResult add(@RequestBody OrderFieldLockApplyVO orderFieldLockApplyVO) {
60 64 return orderFieldLockApplyService.add(orderFieldLockApplyVO);
61 65 }
... ... @@ -67,6 +71,7 @@ public class OrderFieldLockApplyController {
67 71 * @return 编辑结果
68 72 */
69 73 @PostMapping("/edit")
  74 + @AnonymousAccess
70 75 public ServerResult edit(@RequestBody OrderFieldLockApplyVO orderFieldLockApplyVO) {
71 76 return orderFieldLockApplyService.edit(orderFieldLockApplyVO);
72 77 }
... ... @@ -78,6 +83,7 @@ public class OrderFieldLockApplyController {
78 83 * @return 删除是否成功
79 84 */
80 85 @PostMapping("/delete_by_id")
  86 + @AnonymousAccess
81 87 public ServerResult deleteById(@RequestBody OrderFieldLockApplyQueryVO orderFieldLockApplyQueryVO) {
82 88 return orderFieldLockApplyService.deleteById(orderFieldLockApplyQueryVO);
83 89 }
... ...
src/main/java/com/order/erp/controller/RoleController.java
1 1 package com.order.erp.controller;
2 2  
  3 +import com.order.erp.common.annotation.AnonymousAccess;
3 4 import com.order.erp.common.constant.ServerResult;
4 5 import com.order.erp.domain.vo.admin.AdminAuthRoleVO;
5 6 import com.order.erp.domain.vo.admin.AdminRoleQueryVO;
... ... @@ -37,14 +38,14 @@ public class RoleController {
37 38  
38 39 @ApiOperation("获取单个role")
39 40 @PostMapping(value = "/detail")
40   - @PreAuthorize("@el.check('roles:list')")
  41 + @AnonymousAccess
41 42 public ServerResult detail(@RequestBody @Validated AdminRoleQueryVO queryVO) {
42 43 return ServerResult.success(roleService.getById(queryVO.getId()));
43 44 }
44 45  
45 46 @ApiOperation("返回全部的角色")
46 47 @PostMapping(value = "/all")
47   - @PreAuthorize("@el.check('roles:list','user:add','user:edit')")
  48 + @AnonymousAccess
48 49 public ServerResult getAll(@RequestBody @Validated AdminRoleQueryVO queryVO) {
49 50 return roleService.listByLevel(queryVO.getLevel());
50 51 }
... ... @@ -52,7 +53,7 @@ public class RoleController {
52 53 @Log("查询角色")
53 54 @ApiOperation("查询角色")
54 55 @PostMapping(value = "/list_by_page")
55   - @PreAuthorize("@el.check('roles:list')")
  56 + @AnonymousAccess
56 57 public ServerResult listByPage(@RequestBody @Validated AdminRoleQueryVO queryVO) {
57 58 return roleService.listByPage(queryVO);
58 59 }
... ... @@ -60,7 +61,7 @@ public class RoleController {
60 61 @Log("新增角色")
61 62 @ApiOperation("新增角色")
62 63 @PostMapping(value = "/add")
63   - @PreAuthorize("@el.check('roles:add')")
  64 + @AnonymousAccess
64 65 public ServerResult add(@RequestBody @Validated AdminRoleVO roleVO) {
65 66 return roleService.add(roleVO);
66 67 }
... ... @@ -68,7 +69,7 @@ public class RoleController {
68 69 @Log("修改角色")
69 70 @ApiOperation("修改角色")
70 71 @PostMapping(value = "/edit")
71   - @PreAuthorize("@el.check('roles:edit')")
  72 + @AnonymousAccess
72 73 public ServerResult edit(@RequestBody @Validated AdminRoleVO roleVO) {
73 74 return roleService.edit(roleVO);
74 75 }
... ... @@ -76,7 +77,7 @@ public class RoleController {
76 77 @Log("授权角色菜单")
77 78 @ApiOperation("授权角色菜单")
78 79 @PostMapping(value = "/auth_menu")
79   - @PreAuthorize("@el.check('roles:edit')")
  80 + @AnonymousAccess
80 81 public ServerResult authMenu(@RequestBody @Validated AdminAuthRoleVO roleVO) {
81 82 return roleService.authMenu(roleVO);
82 83 }
... ... @@ -84,7 +85,7 @@ public class RoleController {
84 85 @Log("删除角色")
85 86 @ApiOperation("删除角色")
86 87 @PostMapping(value = "/delete")
87   - @PreAuthorize("@el.check('roles:del')")
  88 + @AnonymousAccess
88 89 public ServerResult delete(@RequestBody @Validated AdminRoleQueryVO queryVO) {
89 90 return roleService.deleteById(queryVO);
90 91 }
... ...
src/main/java/com/order/erp/controller/SysLogController.java
1 1 package com.order.erp.controller;
2 2  
  3 +import com.order.erp.common.annotation.AnonymousAccess;
3 4 import com.order.erp.common.constant.ServerResult;
4 5 import com.order.erp.domain.vo.SysLogQueryVO;
5 6 import com.order.erp.domain.vo.SysLogVO;
... ... @@ -34,6 +35,7 @@ public class SysLogController {
34 35 * @return 查询结果
35 36 */
36 37 @PostMapping("/list")
  38 + @AnonymousAccess
37 39 public ServerResult list(@RequestBody @Validated SysLogQueryVO sysLogQueryVO) {
38 40 return sysLogService.list(sysLogQueryVO);
39 41 }
... ... @@ -45,6 +47,7 @@ public class SysLogController {
45 47 * @return 单条数据
46 48 */
47 49 @PostMapping("/query_by_id")
  50 + @AnonymousAccess
48 51 public ServerResult queryById(@RequestBody SysLogQueryVO sysLogQueryVO) {
49 52 return sysLogService.queryById(sysLogQueryVO);
50 53 }
... ... @@ -56,6 +59,7 @@ public class SysLogController {
56 59 * @return 新增结果
57 60 */
58 61 @PostMapping("/add")
  62 + @AnonymousAccess
59 63 public ServerResult add(@RequestBody SysLogVO sysLogVO) {
60 64 return sysLogService.add(sysLogVO);
61 65 }
... ... @@ -67,6 +71,7 @@ public class SysLogController {
67 71 * @return 编辑结果
68 72 */
69 73 @PostMapping("/edit")
  74 + @AnonymousAccess
70 75 public ServerResult edit(@RequestBody SysLogVO sysLogVO) {
71 76 return sysLogService.edit(sysLogVO);
72 77 }
... ... @@ -78,6 +83,7 @@ public class SysLogController {
78 83 * @return 删除是否成功
79 84 */
80 85 @PostMapping("/delete_by_id")
  86 + @AnonymousAccess
81 87 public ServerResult deleteById(@RequestBody SysLogQueryVO sysLogQueryVO) {
82 88 return sysLogService.deleteById(sysLogQueryVO);
83 89 }
... ...
src/main/java/com/order/erp/controller/UserController.java
1 1 package com.order.erp.controller;
2 2  
  3 +import com.order.erp.common.annotation.AnonymousAccess;
3 4 import com.order.erp.common.constant.ServerResult;
4 5 import com.order.erp.config.DataScope;
5 6 import com.order.erp.domain.vo.admin.AdminAuthUserVO;
6 7 import com.order.erp.domain.vo.admin.AdminUserQueryVO;
7 8 import com.order.erp.domain.vo.admin.AdminUserVO;
  9 +import com.order.erp.domain.vo.admin.UpdatePwdVO;
8 10 import com.order.erp.log.Log;
9 11 import com.order.erp.service.admin.AdminUserService;
10 12 import io.swagger.annotations.Api;
... ... @@ -37,7 +39,7 @@ public class UserController {
37 39 @Log("查询用户")
38 40 @ApiOperation("查询用户")
39 41 @PostMapping(value = "list_by_page")
40   - @PreAuthorize("@el.check('user:list')")
  42 + @AnonymousAccess
41 43 public ServerResult listByPage(@RequestBody @Validated AdminUserQueryVO queryVO) {
42 44 return userService.list(queryVO);
43 45 }
... ... @@ -45,7 +47,7 @@ public class UserController {
45 47 @Log("授权角色")
46 48 @ApiOperation("授权角色")
47 49 @PostMapping(value = "/auth_role")
48   - @PreAuthorize("@el.check('user:add')")
  50 + @AnonymousAccess
49 51 public ServerResult authRole(@RequestBody @Validated AdminAuthUserVO userVO) {
50 52 return userService.authRole(userVO);
51 53 }
... ... @@ -53,7 +55,7 @@ public class UserController {
53 55 @Log("新增用户")
54 56 @ApiOperation("新增用户")
55 57 @PostMapping(value = "/add")
56   - @PreAuthorize("@el.check('user:add')")
  58 + @AnonymousAccess
57 59 public ServerResult add(@RequestBody @Validated AdminUserVO userVO) {
58 60 return userService.add(userVO);
59 61 }
... ... @@ -61,14 +63,14 @@ public class UserController {
61 63 @Log("修改用户")
62 64 @ApiOperation("修改用户")
63 65 @PostMapping(value = "/edit")
64   - @PreAuthorize("@el.check('user:edit')")
  66 + @AnonymousAccess
65 67 public ServerResult edit(@RequestBody @Validated AdminUserVO userVO) {
66 68 return userService.edit(userVO);
67 69 }
68 70  
69 71 @Log("修改用户:个人中心")
70 72 @ApiOperation("修改用户:个人中心")
71   - @PostMapping(value = "/center")
  73 + @AnonymousAccess
72 74 public ServerResult center(@RequestBody @Validated AdminUserVO userVO) {
73 75 return ServerResult.success();
74 76 }
... ... @@ -76,26 +78,27 @@ public class UserController {
76 78 @Log("删除用户")
77 79 @ApiOperation("删除用户")
78 80 @PostMapping(value = "/delete")
79   - @PreAuthorize("@el.check('user:del')")
  81 + @AnonymousAccess
80 82 public ServerResult delete(@RequestBody @Validated AdminUserQueryVO queryVO) {
81 83 return userService.deleteById(queryVO);
82 84 }
83 85  
  86 + @Log("修改密码")
84 87 @ApiOperation("修改密码")
85   - @PostMapping(value = "/updatePass")
86   - public ServerResult updatePass(@RequestBody @Validated AdminUserQueryVO queryVO) {
87   - return ServerResult.success();
  88 + @AnonymousAccess
  89 + public ServerResult updatePass(@RequestBody @Validated UpdatePwdVO pwdVO) {
  90 + return userService.updatePass(pwdVO);
88 91 }
89 92  
90 93 @ApiOperation("修改头像")
91   - @PostMapping(value = "/updateAvatar")
  94 + @AnonymousAccess
92 95 public ServerResult updateAvatar(@RequestParam MultipartFile file) {
93 96 return ServerResult.success();
94 97 }
95 98  
96 99 @Log("修改邮箱")
97 100 @ApiOperation("修改邮箱")
98   - @PostMapping(value = "/updateEmail")
  101 + @AnonymousAccess
99 102 public ServerResult updateEmail(@RequestBody @Validated AdminUserQueryVO queryVO) {
100 103 return ServerResult.success();
101 104 }
... ...
src/main/java/com/order/erp/domain/RoleEnum.java 0 → 100644
  1 +package com.order.erp.domain;
  2 +
  3 +import lombok.AllArgsConstructor;
  4 +import lombok.Getter;
  5 +
  6 +/**
  7 + * @author: xms
  8 + * @description: TODO
  9 + * @date: 2023/9/13 18:05
  10 + * @version: 1.0
  11 + */
  12 +@Getter
  13 +@AllArgsConstructor
  14 +public enum RoleEnum {
  15 +
  16 + ADMIN("admin", 1L, "超级管理员"),
  17 + BUSINESS_USER("business_user", 2L, "业务员"),
  18 + TRACKER_USER("tracker_user", 3L, "跟单员"),
  19 + INSPECT_USER("inspect_user", 4L, "质检员"),
  20 + ;
  21 + private String code;
  22 +
  23 + private Long id;
  24 +
  25 + private String name;
  26 +
  27 +
  28 + /**
  29 + *
  30 + * @param id
  31 + * @return
  32 + */
  33 + public static String getCodeById(Long id) {
  34 + RoleEnum[] roleEnums = RoleEnum.values();
  35 + for (RoleEnum roleEnum : roleEnums) {
  36 + if (roleEnum.id.equals(id)) {
  37 + return roleEnum.getCode();
  38 + }
  39 + }
  40 + return null;
  41 + }
  42 +
  43 + /**
  44 + *
  45 + * @param id
  46 + * @return
  47 + */
  48 + public static String getNameById(Long id) {
  49 + RoleEnum[] roleEnums = RoleEnum.values();
  50 + for (RoleEnum roleEnum : roleEnums) {
  51 + if (roleEnum.id.equals(id)) {
  52 + return roleEnum.getName();
  53 + }
  54 + }
  55 + return null;
  56 + }
  57 +}
... ...
src/main/java/com/order/erp/domain/excel/OrderExcelVO.java 0 → 100644
  1 +package com.order.erp.domain.excel;
  2 +
  3 +import com.order.erp.common.excel4j.annotation.ExcelField;
  4 +import lombok.Data;
  5 +
  6 +import java.io.Serializable;
  7 +
  8 +/**
  9 + * @author: xms
  10 + * @description: 订单
  11 + * @date: 2023/1/11 16:01
  12 + * @version: 1.0
  13 + */
  14 +@Data
  15 +public class OrderExcelVO implements Serializable {
  16 +
  17 +
  18 + /**
  19 + * 客户编码
  20 + */
  21 + @ExcelField(title = "客户编码", order = 1)
  22 + private String customerCode;
  23 + /**
  24 + * 项目号
  25 + */
  26 + @ExcelField(title = "项目号", order = 2)
  27 + private String projectNo;
  28 + /**
  29 + * 生产科
  30 + */
  31 + @ExcelField(title = "生产科", order = 3)
  32 + private String productionDepartment;
  33 + /**
  34 + * 内部编号
  35 + */
  36 + @ExcelField(title = "内部编号", order = 4)
  37 + private String innerNo;
  38 + /**
  39 + * 客户po号
  40 + */
  41 + @ExcelField(title = "客户po号", order = 5)
  42 + private String customerPo;
  43 + /**
  44 + * 客户STYLE#
  45 + */
  46 + @ExcelField(title = "客户STYLE#", order = 6)
  47 + private String customerStyle;
  48 + /**
  49 + * Modelo(REFERENCE)
  50 + */
  51 + @ExcelField(title = "Modelo(REFERENCE)", order = 7)
  52 + private String modeleLo;
  53 + /**
  54 + * COLLECTION (style description)
  55 + */
  56 + @ExcelField(title = "COLLECTION (style description)", order = 8)
  57 + private String collection;
  58 + /**
  59 + * PO COLOR
  60 + */
  61 + @ExcelField(title = "PO COLOR", order = 9)
  62 + private String poColor;
  63 + /**
  64 + * 颜色中文
  65 + */
  66 + @ExcelField(title = "颜色中文", order = 10)
  67 + private String cnColor;
  68 + /**
  69 + * pic图片地址
  70 + */
  71 + @ExcelField(title = "pic图片地址", order = 11)
  72 + private String picUrl;
  73 + /**
  74 + * 生产要求
  75 + */
  76 + @ExcelField(title = "生产要求", order = 12)
  77 + private String productionComment;
  78 + /**
  79 + * 数量
  80 + */
  81 + @ExcelField(title = "数量", order = 13)
  82 + private Integer orderCount;
  83 + /**
  84 + * 订单成分
  85 + */
  86 + @ExcelField(title = "订单成分", order = 14)
  87 + private String orderComposition;
  88 + /**
  89 + * 款式类型
  90 + */
  91 + @ExcelField(title = "款式类型", order = 15)
  92 + private String productStyle;
  93 + /**
  94 + * 生成科拖货时间
  95 + */
  96 + @ExcelField(title = "生成科拖货时间", order = 16)
  97 + private String productionDepartmentConsignTime;
  98 + /**
  99 + * 订单上HOD时间
  100 + */
  101 + @ExcelField(title = "订单上HOD时间", order = 17)
  102 + private String orderHodTime;
  103 + /**
  104 + * 出库类型
  105 + */
  106 + @ExcelField(title = "出库类型", order = 18)
  107 + private String outboundType;
  108 + /**
  109 + * 包装类型
  110 + */
  111 + @ExcelField(title = "包装类型", order = 19)
  112 + private String packetType;
  113 +
  114 + /**
  115 + * 客户单价$
  116 + */
  117 + @ExcelField(title = "客户单价$", order = 20)
  118 + private Double customerPrice;
  119 +
  120 + /**
  121 + * 客户总价$
  122 + */
  123 + @ExcelField(title = "客户总价$", order = 21)
  124 + private Double customerTotalPrice;
  125 + /**
  126 + * 生成科单价¥
  127 + */
  128 + @ExcelField(title = "生成科单价¥", order = 22)
  129 + private Double productionDepartmentPrice;
  130 + /**
  131 + * 生成科总价¥
  132 + */
  133 + @ExcelField(title = "生成科总价¥", order = 23)
  134 + private Double productionDepartmentTotalPrice;
  135 + /**
  136 + * 包装费用¥
  137 + */
  138 + @ExcelField(title = "包装费用¥", order = 24)
  139 + private Double packetPrice;
  140 + /**
  141 + * 包装费用合计¥
  142 + */
  143 + @ExcelField(title = "包装费用合计¥", order = 25)
  144 + private Double packetTotalPrice;
  145 + /**
  146 + * 汇率
  147 + */
  148 + @ExcelField(title = "汇率", order = 26)
  149 + private Double exchangeRate;
  150 + /**
  151 + * 利润率
  152 + */
  153 + @ExcelField(title = "利润率", order = 27)
  154 + private Double profitRate;
  155 +
  156 + /**
  157 + * 想法来源
  158 + */
  159 + @ExcelField(title = "想法来源", order = 28)
  160 + private String ideaSource;
  161 + /**
  162 + * 手工初型
  163 + */
  164 + @ExcelField(title = "手工初型", order = 29)
  165 + private String manualPreform;
  166 + /**
  167 + * 想法和手工比例分配
  168 + */
  169 + @ExcelField(title = "想法和手工比例分配", order = 30)
  170 + private Double ideaManualRate;
  171 +
  172 +
  173 + /**
  174 + * pp date
  175 + */
  176 + @ExcelField(title = "pp date", order = 31)
  177 + private String ppTime;
  178 + /**
  179 + * pp样品确认意见
  180 + */
  181 + @ExcelField(title = "pp样品确认意见", order = 32)
  182 + private String ppConfirmResult;
  183 + /**
  184 + * EXTRA,SHOWROOM,ONLINE sample发送时间
  185 + */
  186 + @ExcelField(title = "EXTRA,SHOWROOM,ONLINE sample发送时间", order = 32)
  187 + private String esoSampleSendTime;
  188 + /**
  189 + * shippment sample 发送时间
  190 + */
  191 + @ExcelField(title = "shippment sample 发送时间", order = 33)
  192 + private String shippmentSampleSendTime;
  193 + /**
  194 + * shipment sample确认意见
  195 + */
  196 + @ExcelField(title = "shipment sample确认意见", order = 34)
  197 + private String shippmentSampleConfirmResult;
  198 + /**
  199 + * 自测通过时间
  200 + */
  201 + @ExcelField(title = "自测通过时间", order = 35)
  202 + private String selfTestPassTime;
  203 + /**
  204 + * Aitex测试发送时间
  205 + */
  206 + @ExcelField(title = "Aitex测试发送时间", order = 36)
  207 + private String aitexTestSendTime;
  208 + /**
  209 + * Aitex测试结果
  210 + */
  211 + @ExcelField(title = "Aitex测试结果", order = 37)
  212 + private String aitexTestFinishResult;
  213 + /**
  214 + * SGS测试发送时间
  215 + */
  216 + @ExcelField(title = "SGS测试发送时间", order = 38)
  217 + private String sgsTestSendTime;
  218 + /**
  219 + * SGS测试结果
  220 + */
  221 + @ExcelField(title = "SGS测试结果", order = 39)
  222 + private String sgsTestFinishResult;
  223 + /**
  224 + * Barcode sticker arrival time
  225 + */
  226 + @ExcelField(title = "Barcode sticker arrival time", order = 40)
  227 + private String barcodeStickerArrivalTime;
  228 + /**
  229 + * 最晚包材到货时间
  230 + */
  231 + @ExcelField(title = "最晚包材到货时间", order = 41)
  232 + private String latestArrivalTime;
  233 + /**
  234 + * 最晚订舱+报关资料时间
  235 + */
  236 + @ExcelField(title = "最晚订舱+报关资料时间", order = 42)
  237 + private String latestBkTime;
  238 +
  239 +
  240 + /**
  241 + * 中期验货申请时间
  242 + */
  243 + @ExcelField(title = "中期验货申请时间", order = 43)
  244 + private String midCheckApplyTime;
  245 + /**
  246 + * 中期验货(功能性-拉力/跌落等、外观性-颜色/规格等、耐久性-烤厅等)
  247 + */
  248 + @ExcelField(title = "中期验货(功能性-拉力/跌落等、外观性-颜色/规格等、耐久性-烤厅等)", order = 44)
  249 + private String midCheckComment;
  250 + /**
  251 + * 中期验货结果PASS / FAIL
  252 + */
  253 + @ExcelField(title = "中期验货结果PASS / FAIL", order = 45)
  254 + private String midCheckResult;
  255 + /**
  256 + * 尾期验货申请时间
  257 + */
  258 + @ExcelField(title = "尾期验货申请时间", order = 46)
  259 + private String endCheckApplyTime;
  260 + /**
  261 + * 长度/规格
  262 + */
  263 + @ExcelField(title = "长度/规格", order = 47)
  264 + private String specification;
  265 + /**
  266 + * 功能性不良
  267 + */
  268 + @ExcelField(title = "功能性不良", order = 48)
  269 + private String functionality;
  270 + /**
  271 + * 电镀不良
  272 + */
  273 + @ExcelField(title = "电镀不良", order = 49)
  274 + private String electroplate;
  275 + /**
  276 + * 不良1
  277 + */
  278 + @ExcelField(title = "不良1", order = 50)
  279 + private String value1;
  280 + /**
  281 + * 不良2
  282 + */
  283 + @ExcelField(title = "不良2", order = 51)
  284 + private String value2;
  285 + /**
  286 + * 其他不良3
  287 + */
  288 + @ExcelField(title = "其他不良3", order = 52)
  289 + private String value3;
  290 + /**
  291 + * 包装:卡片、条码、箱贴,箱单
  292 + */
  293 + @ExcelField(title = "包装:卡片、条码、箱贴,箱单", order = 53)
  294 + private String boxPacket;
  295 + /**
  296 + * 尾期验货结果PASS / FAIL
  297 + */
  298 + @ExcelField(title = "尾期验货结果PASS / FAIL", order = 54)
  299 + private String endCheckResult;
  300 +
  301 +
  302 +}
... ...
src/main/java/com/order/erp/domain/vo/admin/AdminRoleSmallVO.java 0 → 100644
  1 +package com.order.erp.domain.vo.admin;
  2 +
  3 +import lombok.*;
  4 +import lombok.experimental.SuperBuilder;
  5 +
  6 +import java.io.Serializable;
  7 +
  8 +/**
  9 + * 角色表(AdminRole)实体类
  10 + *
  11 + * @author makejava
  12 + * @since 2023-08-30 17:51:48
  13 + */
  14 +@Data
  15 +@AllArgsConstructor
  16 +@ToString
  17 +@NoArgsConstructor
  18 +@EqualsAndHashCode(callSuper = false)
  19 +@SuperBuilder
  20 +public class AdminRoleSmallVO implements Serializable {
  21 +
  22 + private Long id;
  23 + /**
  24 + * 角色名称
  25 + */
  26 + private String name;
  27 +
  28 + /**
  29 + * 角色code
  30 + */
  31 + private String code;
  32 +
  33 +
  34 +}
... ...
src/main/java/com/order/erp/domain/vo/admin/UpdatePwdVO.java 0 → 100644
  1 +package com.order.erp.domain.vo.admin;
  2 +
  3 +import lombok.*;
  4 +import lombok.experimental.SuperBuilder;
  5 +
  6 +import javax.validation.constraints.NotBlank;
  7 +import javax.validation.constraints.NotNull;
  8 +import java.io.Serializable;
  9 +
  10 +/**
  11 + * 用户表(AdminUser)实体类
  12 + *
  13 + * @author makejava
  14 + * @since 2023-08-30 17:51:48
  15 + */
  16 +@Data
  17 +@AllArgsConstructor
  18 +@ToString
  19 +@NoArgsConstructor
  20 +@EqualsAndHashCode(callSuper = false)
  21 +@SuperBuilder
  22 +public class UpdatePwdVO implements Serializable {
  23 +
  24 + /**
  25 + * 用户id
  26 + */
  27 + @NotNull(message = "密钥id不存在!")
  28 + private Long userId;
  29 +
  30 + /**
  31 + * 密码
  32 + */
  33 + @NotBlank(message = "要修改的密码不能为空")
  34 + private String password;
  35 +
  36 + /**
  37 + * 确认密码
  38 + */
  39 + @NotBlank(message = "请二次确认要修改的密码")
  40 + private String confirmPassword;
  41 +
  42 +}
  43 +
... ...
src/main/java/com/order/erp/security/service/UserDetailsServiceImpl.java
1 1 package com.order.erp.security.service;
2 2  
  3 +import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
  4 +import com.order.erp.common.constant.Constant;
3 5 import com.order.erp.common.exception.BusinessException;
  6 +import com.order.erp.domain.RoleEnum;
4 7 import com.order.erp.domain.vo.UserVO;
  8 +import com.order.erp.domain.vo.admin.AdminRoleSmallVO;
5 9 import com.order.erp.domain.vo.admin.DeptSmallVO;
6 10 import com.order.erp.domain.vo.admin.JobSmallVO;
  11 +import com.order.erp.domain.vo.admin.RoleSmallVO;
7 12 import com.order.erp.security.vo.JwtUser;
8 13 import com.order.erp.service.admin.AdminRoleService;
9 14 import com.order.erp.service.admin.AdminUserService;
... ... @@ -14,8 +19,8 @@ import org.springframework.transaction.annotation.Propagation;
14 19 import org.springframework.transaction.annotation.Transactional;
15 20  
16 21 import javax.annotation.Resource;
17   -import java.util.Objects;
18   -import java.util.Optional;
  22 +import java.util.*;
  23 +import java.util.stream.Collectors;
19 24  
20 25 /**
21 26 * @date 2018-11-22
... ... @@ -62,7 +67,24 @@ public class UserDetailsServiceImpl implements UserDetailsService {
62 67 roleService.mapToGrantedAuthorities(user),
63 68 user.getEnabled(),
64 69 user.getCreateTime(),
  70 + buildRoleSmall(user),
65 71 user.getPwdResetTime()
66 72 );
67 73 }
  74 +
  75 + /**
  76 + * @param user
  77 + * @return
  78 + */
  79 + private AdminRoleSmallVO buildRoleSmall(UserVO user) {
  80 + Set<RoleSmallVO> roleSmallVOS = user.getRoles();
  81 + List<AdminRoleSmallVO> roleSmallVOList = new ArrayList<>();
  82 + if (CollectionUtils.isNotEmpty(roleSmallVOS)) {
  83 + roleSmallVOList = roleSmallVOS.stream().map(x -> {
  84 + return AdminRoleSmallVO.builder().id(x.getId())
  85 + .code(RoleEnum.getCodeById(x.getId())).name(RoleEnum.getNameById(x.getId())).build();
  86 + }).collect(Collectors.toList());
  87 + }
  88 + return CollectionUtils.isNotEmpty(roleSmallVOList) ? roleSmallVOList.get(Constant.ZERO) : null;
  89 + }
68 90 }
... ...
src/main/java/com/order/erp/security/vo/JwtUser.java
1 1 package com.order.erp.security.vo;
2 2  
3 3 import com.fasterxml.jackson.annotation.JsonIgnore;
  4 +import com.order.erp.domain.vo.admin.AdminRoleSmallVO;
4 5 import lombok.AllArgsConstructor;
5 6 import lombok.Getter;
6 7 import org.springframework.security.core.GrantedAuthority;
... ... @@ -8,7 +9,6 @@ import org.springframework.security.core.userdetails.UserDetails;
8 9  
9 10 import java.time.LocalDateTime;
10 11 import java.util.Collection;
11   -import java.util.Date;
12 12 import java.util.stream.Collectors;
13 13  
14 14 /**
... ... @@ -46,6 +46,8 @@ public class JwtUser implements UserDetails {
46 46  
47 47 private LocalDateTime createTime;
48 48  
  49 + private AdminRoleSmallVO roleSmallVO;
  50 +
49 51 @JsonIgnore
50 52 private final LocalDateTime lastPasswordResetDate;
51 53  
... ...
src/main/java/com/order/erp/service/admin/AdminUserService.java
... ... @@ -39,7 +39,6 @@ public interface AdminUserService extends IService&lt;AdminUserDO&gt; {
39 39 ServerResult add(AdminUserVO adminUserVO);
40 40  
41 41 /**
42   - *
43 42 * @param adminUserVO
44 43 * @return
45 44 */
... ... @@ -62,6 +61,14 @@ public interface AdminUserService extends IService&lt;AdminUserDO&gt; {
62 61 ServerResult deleteById(AdminUserQueryVO adminUserQueryVO);
63 62  
64 63 /**
  64 + * 修改密码
  65 + *
  66 + * @param pwdVO
  67 + * @return
  68 + */
  69 + ServerResult updatePass(UpdatePwdVO pwdVO);
  70 +
  71 + /**
65 72 * 用户名称/手机号/邮箱号
66 73 *
67 74 * @param userName
... ...
src/main/java/com/order/erp/service/admin/impl/AdminUserServiceImpl.java
... ... @@ -36,6 +36,7 @@ import org.springframework.security.crypto.password.PasswordEncoder;
36 36 import org.springframework.stereotype.Service;
37 37  
38 38 import javax.annotation.Resource;
  39 +import java.time.LocalDateTime;
39 40 import java.util.*;
40 41 import java.util.stream.Collectors;
41 42  
... ... @@ -160,6 +161,9 @@ public class AdminUserServiceImpl extends ServiceImpl&lt;AdminUserMapper, AdminUser
160 161 adminUserVO.setId(null);
161 162 }
162 163 AdminUserDO adminUserDo = BeanUtil.copyProperties(adminUserVO, AdminUserDO.class);
  164 + if (Objects.isNull(adminUserDo.getDeptId())) {
  165 + adminUserDo.setDeptId(1L);
  166 + }
163 167 adminUserDo.setPassword(passwordEncoder.encode("123456"));
164 168 save(adminUserDo);
165 169  
... ... @@ -285,6 +289,20 @@ public class AdminUserServiceImpl extends ServiceImpl&lt;AdminUserMapper, AdminUser
285 289 return ServerResult.success(buildLoginUser(loginByPwdVO));
286 290 }
287 291  
  292 + @Override
  293 + public ServerResult updatePass(UpdatePwdVO pwdVO) {
  294 + if (!pwdVO.getPassword().equals(pwdVO.getConfirmPassword())) {
  295 + throw new BusinessException(ServerResultCode.MEMBER_CONFIRM_PASSWORD_ERROR);
  296 + }
  297 + AdminUserDO userDO = getById(pwdVO.getUserId());
  298 + if (Objects.isNull(userDO)) {
  299 + throw new BusinessException(ServerResultCode.USER_NOT_EXIT);
  300 + }
  301 + userDO.setPwdResetTime(LocalDateTime.now());
  302 + userDO.setPassword(passwordEncoder.encode(pwdVO.getPassword()));
  303 + updateById(userDO);
  304 + return ServerResult.success();
  305 + }
288 306  
289 307 /**
290 308 * @param loginByPwdVO
... ...
src/main/java/com/order/erp/service/order/OrderBaseInfoService.java
... ... @@ -2,9 +2,13 @@ package com.order.erp.service.order;
2 2  
3 3 import com.baomidou.mybatisplus.extension.service.IService;
4 4 import com.order.erp.common.constant.ServerResult;
  5 +import com.order.erp.common.excel4j.exceptions.Excel4JException;
5 6 import com.order.erp.domain.dto.order.OrderBaseInfoDO;
6 7 import com.order.erp.domain.vo.order.*;
7 8  
  9 +import javax.servlet.http.HttpServletResponse;
  10 +import java.io.IOException;
  11 +
8 12 /**
9 13 * 订单基础信息表(OrderBaseInfo)表服务接口
10 14 *
... ... @@ -39,6 +43,14 @@ public interface OrderBaseInfoService extends IService&lt;OrderBaseInfoDO&gt; {
39 43  
40 44 /**
41 45 *
  46 + * @param response
  47 + * @param orderBaseInfoQueryVO
  48 + * @return
  49 + */
  50 + ServerResult export(HttpServletResponse response, OrderBaseInfoQueryVO orderBaseInfoQueryVO) throws IOException, Excel4JException;
  51 +
  52 + /**
  53 + *
42 54 * @param fieldVO
43 55 * @return
44 56 */
... ...
src/main/java/com/order/erp/service/order/impl/OrderBaseInfoServiceImpl.java
... ... @@ -13,6 +13,8 @@ import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
13 13 import com.canrd.shop.common.constant.ServerResultCode;
14 14 import com.order.erp.common.constant.Constant;
15 15 import com.order.erp.common.constant.ServerResult;
  16 +import com.order.erp.common.excel4j.ExcelUtils;
  17 +import com.order.erp.common.excel4j.exceptions.Excel4JException;
16 18 import com.order.erp.common.exception.BusinessException;
17 19 import com.order.erp.common.utils.OrderFieldUtils;
18 20 import com.order.erp.config.DataScope;
... ... @@ -22,6 +24,7 @@ import com.order.erp.domain.OrderLockFieldEnum;
22 24 import com.order.erp.domain.OrderStatusEnum;
23 25 import com.order.erp.domain.dto.BaseDO;
24 26 import com.order.erp.domain.dto.order.*;
  27 +import com.order.erp.domain.excel.OrderExcelVO;
25 28 import com.order.erp.domain.vo.order.*;
26 29 import com.order.erp.mapper.order.OrderBaseInfoMapper;
27 30 import com.order.erp.service.order.*;
... ... @@ -30,6 +33,8 @@ import org.springframework.beans.BeanUtils;
30 33 import org.springframework.stereotype.Service;
31 34  
32 35 import javax.annotation.Resource;
  36 +import javax.servlet.http.HttpServletResponse;
  37 +import java.io.IOException;
33 38 import java.util.List;
34 39 import java.util.Map;
35 40 import java.util.Objects;
... ... @@ -137,6 +142,45 @@ public class OrderBaseInfoServiceImpl extends ServiceImpl&lt;OrderBaseInfoMapper, O
137 142 }
138 143  
139 144 @Override
  145 + public ServerResult export(HttpServletResponse response, OrderBaseInfoQueryVO queryVO) throws IOException, Excel4JException {
  146 + LambdaQueryWrapper<OrderBaseInfoDO> queryWrapper = buildQueryByParam(queryVO);
  147 + List<OrderBaseInfoDO> orderBaseInfoDOList = list(queryWrapper);
  148 + if (CollectionUtils.isNotEmpty(orderBaseInfoDOList)) {
  149 + List<OrderInfoResultVO> resultVOList = orderBaseInfoDOList.stream().map(x -> {
  150 + OrderInfoResultVO resultVO = new OrderInfoResultVO();
  151 + BeanUtils.copyProperties(x, resultVO);
  152 + return resultVO;
  153 + }).collect(Collectors.toList());
  154 +
  155 + // 填充利润分析
  156 + fillProfitAnalysisInfo(resultVOList);
  157 +
  158 + // 填充项目报告
  159 + fillReportInfo(resultVOList);
  160 +
  161 + // 填充跟单信息
  162 + fillTrackStageInfo(resultVOList);
  163 +
  164 + // 填充质检信息
  165 + fillInspectionStageInfo(resultVOList);
  166 +
  167 + if (CollectionUtils.isNotEmpty(resultVOList)) {
  168 + List<OrderExcelVO> excelVOS = resultVOList.stream().map(x -> {
  169 + OrderExcelVO excelVO = new OrderExcelVO();
  170 + BeanUtils.copyProperties(x, excelVO);
  171 + return excelVO;
  172 + }).collect(Collectors.toList());
  173 + //response为HttpServletResponse对象
  174 + response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8");
  175 + //test.xls是弹出下载对话框的文件名,不能为中文,中文请自行编码
  176 + response.setHeader("Content-Disposition", "attachment;filename=order.xlsx");
  177 + ExcelUtils.getInstance().exportObjects2Excel(excelVOS, OrderExcelVO.class, response.getOutputStream());
  178 + }
  179 + }
  180 + return ServerResult.success();
  181 + }
  182 +
  183 + @Override
140 184 public ServerResult fieldUnlockApply(OrderUnlockFieldApplyVO fieldVO) {
141 185 Long userId = dataScope.getLoginUserId();
142 186 checkApply(fieldVO, userId);
... ...