From bb4a6285d5578752a9d96ed6bec41144ff032e4a Mon Sep 17 00:00:00 2001 From: Lucky0829 <641787296@qq.com> Date: Tue, 21 May 2019 14:20:16 +0800 Subject: [PATCH 1/7] =?UTF-8?q?:sparkles:=20=E6=B7=BB=E5=8A=A0=E6=96=B0?= =?UTF-8?q?=E7=89=B9=E6=80=A7=E3=80=82pigxAutoPoi=20=E5=AF=BC=E5=85=A5?= =?UTF-8?q?=E5=AF=BC=E5=87=BA=E5=85=AC=E5=85=B1=E6=A0=B8=E5=BF=83=E5=8C=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pigx-common/pigx-common-autopoi/pom.xml | 86 ++++ .../core/util/ApplicationContextUtil.java | 43 ++ .../dict/service/AutoPoiDictServiceI.java | 36 ++ .../pigx/common/poi/cache/ExcelCache.java | 67 +++ .../pigx/common/poi/cache/WordCache.java | 52 ++ .../common/poi/cache/manager/FileLoade.java | 73 +++ .../poi/cache/manager/POICacheManager.java | 61 +++ .../pigx/common/poi/cache/package-info.java | 9 + .../common/poi/excel/ExcelExportUtil.java | 114 +++++ .../common/poi/excel/ExcelImportUtil.java | 153 ++++++ .../common/poi/excel/ExcelToHtmlUtil.java | 60 +++ .../common/poi/excel/annotation/Excel.java | 205 ++++++++ .../poi/excel/annotation/ExcelCollection.java | 56 +++ .../poi/excel/annotation/ExcelEntity.java | 44 ++ .../poi/excel/annotation/ExcelIgnore.java | 34 ++ .../poi/excel/annotation/ExcelTarget.java | 37 ++ .../poi/excel/annotation/ExcelVerify.java | 96 ++++ .../poi/excel/def/BasePOIConstants.java | 24 + .../poi/excel/def/MapExcelConstants.java | 24 + .../poi/excel/def/NormalExcelConstants.java | 23 + .../poi/excel/def/TemplateExcelConstants.java | 23 + .../poi/excel/def/TemplateWordConstants.java | 23 + .../poi/excel/entity/ExcelBaseParams.java | 26 + .../common/poi/excel/entity/ExportParams.java | 106 ++++ .../common/poi/excel/entity/ImportParams.java | 52 ++ .../excel/entity/TemplateExportParams.java | 107 ++++ .../poi/excel/entity/enmus/CellValueType.java | 13 + .../excel/entity/enmus/ExcelStyleType.java | 35 ++ .../poi/excel/entity/enmus/ExcelType.java | 13 + .../excel/entity/params/ExcelBaseEntity.java | 49 ++ .../entity/params/ExcelCollectionParams.java | 33 ++ .../entity/params/ExcelExportEntity.java | 180 +++++++ .../entity/params/ExcelImportEntity.java | 45 ++ .../entity/params/ExcelTemplateParams.java | 66 +++ .../entity/params/ExcelVerifyEntity.java | 75 +++ .../poi/excel/entity/params/MergeEntity.java | 70 +++ .../entity/result/ExcelImportResult.java | 64 +++ .../result/ExcelVerifyHanlderResult.java | 48 ++ .../excel/entity/sax/SaxReadCellEntity.java | 47 ++ .../poi/excel/entity/vo/PoiBaseConstants.java | 31 ++ .../poi/excel/export/ExcelExportServer.java | 285 +++++++++++ .../excel/export/base/ExcelExportBase.java | 386 +++++++++++++++ .../poi/excel/export/base/ExportBase.java | 366 ++++++++++++++ .../styler/AbstractExcelExportStyler.java | 56 +++ .../styler/ExcelExportStylerBorderImpl.java | 68 +++ .../styler/ExcelExportStylerColorImpl.java | 76 +++ .../styler/ExcelExportStylerDefaultImpl.java | 63 +++ .../export/styler/IExcelExportStyler.java | 39 ++ .../template/ExcelExportOfTemplateUtil.java | 444 +++++++++++++++++ .../poi/excel/html/ExcelToHtmlServer.java | 191 ++++++++ .../excel/html/helper/CellValueHelper.java | 134 +++++ .../excel/html/helper/MergedRegionHelper.java | 95 ++++ .../poi/excel/html/helper/StylerHelper.java | 271 +++++++++++ .../poi/excel/html/helper/excelStyle.css | 45 ++ .../poi/excel/imports/CellValueServer.java | 278 +++++++++++ .../poi/excel/imports/ExcelImportServer.java | 410 ++++++++++++++++ .../excel/imports/base/ImportBaseService.java | 282 +++++++++++ .../poi/excel/imports/package-info.java | 7 + .../poi/excel/imports/sax/SaxReadExcel.java | 75 +++ .../poi/excel/imports/sax/SheetHandler.java | 122 +++++ .../excel/imports/sax/parse/ISaxRowRead.java | 30 ++ .../excel/imports/sax/parse/SaxRowRead.java | 192 ++++++++ .../imports/verifys/BaseVerifyHandler.java | 131 +++++ .../imports/verifys/VerifyHandlerServer.java | 68 +++ .../poi/excel/view/MiniAbstractExcelView.java | 29 ++ .../poi/excel/view/PigxEntityExcelView.java | 68 +++ .../poi/excel/view/PigxMapExcelView.java | 57 +++ .../poi/excel/view/PigxTemplateExcelView.java | 55 +++ .../poi/excel/view/PigxTemplateWordView.java | 53 ++ .../exception/excel/ExcelExportException.java | 48 ++ .../exception/excel/ExcelImportException.java | 48 ++ .../excel/enums/ExcelExportEnum.java | 29 ++ .../excel/enums/ExcelImportEnum.java | 29 ++ .../exception/word/WordExportException.java | 28 ++ .../exception/word/enmus/WordExportEnum.java | 30 ++ .../impl/ExcelDataHandlerDefaultImpl.java | 45 ++ .../common/poi/handler/impl/package-info.java | 7 + .../poi/handler/inter/IExcelDataHandler.java | 57 +++ .../handler/inter/IExcelReadRowHanlder.java | 18 + .../handler/inter/IExcelVerifyHandler.java | 38 ++ .../pigx/common/poi/handler/package-info.java | 7 + .../pigx/common/poi/package-info.java | 13 + .../pigx/common/poi/util/ExcelUtil.java | 292 +++++++++++ .../pigx/common/poi/util/PoiElUtil.java | 229 +++++++++ .../pigx/common/poi/util/PoiFunctionUtil.java | 153 ++++++ .../common/poi/util/PoiMergeCellUtil.java | 182 +++++++ .../pigx/common/poi/util/PoiPublicUtil.java | 459 ++++++++++++++++++ .../pigx/common/poi/util/PoiSheetUtility.java | 94 ++++ .../pigx/common/poi/word/WordExportUtil.java | 43 ++ .../poi/word/entity/MyXWPFDocument.java | 107 ++++ .../poi/word/entity/WordImageEntity.java | 60 +++ .../word/entity/params/ExcelListEntity.java | 83 ++++ .../word/entity/params/ListParamEntity.java | 55 +++ .../common/poi/word/parse/ParseWord07.java | 259 ++++++++++ .../word/parse/excel/ExcelEntityParse.java | 217 +++++++++ .../poi/word/parse/excel/ExcelMapParse.java | 61 +++ pigx-common/pigx-common-bom/pom.xml | 5 + pigx-common/pom.xml | 1 + pom.xml | 18 + 99 files changed, 9494 insertions(+) create mode 100644 pigx-common/pigx-common-autopoi/pom.xml create mode 100644 pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/core/util/ApplicationContextUtil.java create mode 100644 pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/dict/service/AutoPoiDictServiceI.java create mode 100644 pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/cache/ExcelCache.java create mode 100644 pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/cache/WordCache.java create mode 100644 pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/cache/manager/FileLoade.java create mode 100644 pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/cache/manager/POICacheManager.java create mode 100644 pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/cache/package-info.java create mode 100644 pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/ExcelExportUtil.java create mode 100644 pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/ExcelImportUtil.java create mode 100644 pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/ExcelToHtmlUtil.java create mode 100644 pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/annotation/Excel.java create mode 100644 pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/annotation/ExcelCollection.java create mode 100644 pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/annotation/ExcelEntity.java create mode 100644 pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/annotation/ExcelIgnore.java create mode 100644 pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/annotation/ExcelTarget.java create mode 100644 pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/annotation/ExcelVerify.java create mode 100644 pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/def/BasePOIConstants.java create mode 100644 pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/def/MapExcelConstants.java create mode 100644 pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/def/NormalExcelConstants.java create mode 100644 pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/def/TemplateExcelConstants.java create mode 100644 pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/def/TemplateWordConstants.java create mode 100644 pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/entity/ExcelBaseParams.java create mode 100644 pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/entity/ExportParams.java create mode 100644 pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/entity/ImportParams.java create mode 100644 pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/entity/TemplateExportParams.java create mode 100644 pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/entity/enmus/CellValueType.java create mode 100644 pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/entity/enmus/ExcelStyleType.java create mode 100644 pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/entity/enmus/ExcelType.java create mode 100644 pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/entity/params/ExcelBaseEntity.java create mode 100644 pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/entity/params/ExcelCollectionParams.java create mode 100644 pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/entity/params/ExcelExportEntity.java create mode 100644 pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/entity/params/ExcelImportEntity.java create mode 100644 pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/entity/params/ExcelTemplateParams.java create mode 100644 pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/entity/params/ExcelVerifyEntity.java create mode 100644 pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/entity/params/MergeEntity.java create mode 100644 pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/entity/result/ExcelImportResult.java create mode 100644 pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/entity/result/ExcelVerifyHanlderResult.java create mode 100644 pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/entity/sax/SaxReadCellEntity.java create mode 100644 pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/entity/vo/PoiBaseConstants.java create mode 100644 pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/export/ExcelExportServer.java create mode 100644 pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/export/base/ExcelExportBase.java create mode 100644 pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/export/base/ExportBase.java create mode 100644 pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/export/styler/AbstractExcelExportStyler.java create mode 100644 pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/export/styler/ExcelExportStylerBorderImpl.java create mode 100644 pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/export/styler/ExcelExportStylerColorImpl.java create mode 100644 pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/export/styler/ExcelExportStylerDefaultImpl.java create mode 100644 pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/export/styler/IExcelExportStyler.java create mode 100644 pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/export/template/ExcelExportOfTemplateUtil.java create mode 100644 pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/html/ExcelToHtmlServer.java create mode 100644 pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/html/helper/CellValueHelper.java create mode 100644 pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/html/helper/MergedRegionHelper.java create mode 100644 pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/html/helper/StylerHelper.java create mode 100644 pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/html/helper/excelStyle.css create mode 100644 pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/imports/CellValueServer.java create mode 100644 pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/imports/ExcelImportServer.java create mode 100644 pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/imports/base/ImportBaseService.java create mode 100644 pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/imports/package-info.java create mode 100644 pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/imports/sax/SaxReadExcel.java create mode 100644 pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/imports/sax/SheetHandler.java create mode 100644 pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/imports/sax/parse/ISaxRowRead.java create mode 100644 pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/imports/sax/parse/SaxRowRead.java create mode 100644 pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/imports/verifys/BaseVerifyHandler.java create mode 100644 pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/imports/verifys/VerifyHandlerServer.java create mode 100644 pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/view/MiniAbstractExcelView.java create mode 100644 pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/view/PigxEntityExcelView.java create mode 100644 pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/view/PigxMapExcelView.java create mode 100644 pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/view/PigxTemplateExcelView.java create mode 100644 pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/view/PigxTemplateWordView.java create mode 100644 pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/exception/excel/ExcelExportException.java create mode 100644 pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/exception/excel/ExcelImportException.java create mode 100644 pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/exception/excel/enums/ExcelExportEnum.java create mode 100644 pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/exception/excel/enums/ExcelImportEnum.java create mode 100644 pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/exception/word/WordExportException.java create mode 100644 pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/exception/word/enmus/WordExportEnum.java create mode 100644 pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/handler/impl/ExcelDataHandlerDefaultImpl.java create mode 100644 pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/handler/impl/package-info.java create mode 100644 pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/handler/inter/IExcelDataHandler.java create mode 100644 pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/handler/inter/IExcelReadRowHanlder.java create mode 100644 pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/handler/inter/IExcelVerifyHandler.java create mode 100644 pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/handler/package-info.java create mode 100644 pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/package-info.java create mode 100644 pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/util/ExcelUtil.java create mode 100644 pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/util/PoiElUtil.java create mode 100644 pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/util/PoiFunctionUtil.java create mode 100644 pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/util/PoiMergeCellUtil.java create mode 100644 pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/util/PoiPublicUtil.java create mode 100644 pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/util/PoiSheetUtility.java create mode 100644 pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/word/WordExportUtil.java create mode 100644 pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/word/entity/MyXWPFDocument.java create mode 100644 pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/word/entity/WordImageEntity.java create mode 100644 pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/word/entity/params/ExcelListEntity.java create mode 100644 pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/word/entity/params/ListParamEntity.java create mode 100644 pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/word/parse/ParseWord07.java create mode 100644 pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/word/parse/excel/ExcelEntityParse.java create mode 100644 pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/word/parse/excel/ExcelMapParse.java diff --git a/pigx-common/pigx-common-autopoi/pom.xml b/pigx-common/pigx-common-autopoi/pom.xml new file mode 100644 index 000000000..4db9d23b2 --- /dev/null +++ b/pigx-common/pigx-common-autopoi/pom.xml @@ -0,0 +1,86 @@ + + + + pigx-common + com.pig4cloud + 3.0.0 + + 4.0.0 + + pigx-common-autopoi + jar + + pigx AutoPoi 导入导出公共核心包 + + + 1.8 + UTF-8 + UTF-8 + + 2.9.1 + 20.0 + 3.2.1 + 1.7.16 + + + + + + javax.servlet + javax.servlet-api + + + + com.baomidou + mybatis-plus-boot-starter + + + + + org.apache.poi + poi + + + org.apache.poi + poi-ooxml + + + org.apache.poi + poi-ooxml-schemas + + + + xerces + xercesImpl + ${xerces.version} + + + + org.apache.poi + poi-scratchpad + ${poi.version} + + + + + com.google.guava + guava + ${guava.version} + + + + org.apache.commons + commons-lang3 + + + + + org.springframework + spring-webmvc + true + + + + \ No newline at end of file diff --git a/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/core/util/ApplicationContextUtil.java b/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/core/util/ApplicationContextUtil.java new file mode 100644 index 000000000..82bfcd7a8 --- /dev/null +++ b/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/core/util/ApplicationContextUtil.java @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2018-2025, lengleng All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * Neither the name of the pig4cloud.com developer nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * Author: lengleng (wangiegie@gmail.com) + */ +package com.pig4cloud.pigx.common.core.util; + +import org.springframework.beans.BeansException; +import org.springframework.context.ApplicationContext; +import org.springframework.context.ApplicationContextAware; + +/** + * + * @author: Luckly + * @date: 2019-05-20 + *

+ * 应用上下文工具 + */ +public class ApplicationContextUtil implements ApplicationContextAware { + + private static ApplicationContext context; + + + public void setApplicationContext(ApplicationContext context) + throws BeansException { + this.context = context; + } + + public static ApplicationContext getContext() { + return context; + } +} diff --git a/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/dict/service/AutoPoiDictServiceI.java b/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/dict/service/AutoPoiDictServiceI.java new file mode 100644 index 000000000..cf98a0997 --- /dev/null +++ b/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/dict/service/AutoPoiDictServiceI.java @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2018-2025, lengleng All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * Neither the name of the pig4cloud.com developer nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * Author: lengleng (wangiegie@gmail.com) + */ +package com.pig4cloud.pigx.common.dict.service; + + +/** + * @author: Luckly + * @date: 2019-05-20 + *

+ * 查询数据字典 + */ +public interface AutoPoiDictServiceI{ + /** + * 查询数据字典 + * @param dicTable + * @param dicCode + * @param dicText + * @return + */ + String[] queryDict(String dicTable, String dicCode, String dicText); + +} diff --git a/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/cache/ExcelCache.java b/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/cache/ExcelCache.java new file mode 100644 index 000000000..cc6741e1d --- /dev/null +++ b/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/cache/ExcelCache.java @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2018-2025, lengleng All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * Neither the name of the pig4cloud.com developer nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * Author: lengleng (wangiegie@gmail.com) + */ +package com.pig4cloud.pigx.common.poi.cache; + +import com.pig4cloud.pigx.common.poi.cache.manager.POICacheManager; +import lombok.extern.slf4j.Slf4j; +import org.apache.poi.openxml4j.exceptions.InvalidFormatException; +import org.apache.poi.ss.usermodel.Workbook; +import org.apache.poi.ss.usermodel.WorkbookFactory; + +import java.io.InputStream; +import java.util.Arrays; +import java.util.List; + +/** + * @author: Luckly + * @date: 2019-05-20 + *

+ * Excel类型的缓存 + */ +@Slf4j +public final class ExcelCache { + + public static Workbook getWorkbook(String url, Integer[] sheetNums, boolean needAll) { + InputStream is = null; + List sheetList = Arrays.asList(sheetNums); + try { + is = POICacheManager.getFile(url); + Workbook wb = WorkbookFactory.create(is); + // 删除其他的sheet + if (!needAll) { + for (int i = wb.getNumberOfSheets() - 1; i >= 0; i--) { + if (!sheetList.contains(i)) { + wb.removeSheetAt(i); + } + } + } + return wb; + } catch (InvalidFormatException e) { + log.error(e.getMessage(), e); + } catch (Exception e) { + log.error(e.getMessage(), e); + } finally { + try { + is.close(); + } catch (Exception e) { + log.error(e.getMessage(), e); + } + } + return null; + } + +} diff --git a/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/cache/WordCache.java b/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/cache/WordCache.java new file mode 100644 index 000000000..591f3bcd7 --- /dev/null +++ b/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/cache/WordCache.java @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2018-2025, lengleng All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * Neither the name of the pig4cloud.com developer nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * Author: lengleng (wangiegie@gmail.com) + */ +package com.pig4cloud.pigx.common.poi.cache; + +import com.pig4cloud.pigx.common.poi.cache.manager.POICacheManager; +import com.pig4cloud.pigx.common.poi.word.entity.MyXWPFDocument; +import lombok.extern.slf4j.Slf4j; + +import java.io.InputStream; + +/** + * @author: Luckly + * @date: 2019-05-20 + *

+ * word 缓存中心 + */ +@Slf4j +public class WordCache { + + public static MyXWPFDocument getXWPFDocumen(String url) { + InputStream is = null; + try { + is = POICacheManager.getFile(url); + MyXWPFDocument doc = new MyXWPFDocument(is); + return doc; + } catch (Exception e) { + log.error(e.getMessage(), e); + } finally { + try { + is.close(); + } catch (Exception e) { + log.error(e.getMessage(), e); + } + } + return null; + } + +} diff --git a/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/cache/manager/FileLoade.java b/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/cache/manager/FileLoade.java new file mode 100644 index 000000000..8014f40a5 --- /dev/null +++ b/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/cache/manager/FileLoade.java @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2018-2025, lengleng All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * Neither the name of the pig4cloud.com developer nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * Author: lengleng (wangiegie@gmail.com) + */ +package com.pig4cloud.pigx.common.poi.cache.manager; + +import com.pig4cloud.pigx.common.poi.util.PoiPublicUtil; +import lombok.extern.slf4j.Slf4j; + +import java.io.ByteArrayOutputStream; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; + +/** + * @author: Luckly + * @date: 2019-05-20 + *

+ * 文件加载类,根据路径加载指定文件 + */ +@Slf4j +class FileLoade { + + public byte[] getFile(String url) { + FileInputStream fileis = null; + ByteArrayOutputStream baos = null; + try { + // 先用绝对路径查询,再查询相对路径 + try { + fileis = new FileInputStream(url); + } catch (FileNotFoundException e) { + String path = PoiPublicUtil.getWebRootPath(url); + fileis = new FileInputStream(path); + } + baos = new ByteArrayOutputStream(); + byte[] buffer = new byte[1024]; + int len; + while ((len = fileis.read(buffer)) > -1) { + baos.write(buffer, 0, len); + } + baos.flush(); + return baos.toByteArray(); + } catch (FileNotFoundException e) { + log.error(e.getMessage(), e); + } catch (IOException e) { + log.error(e.getMessage(), e); + } finally { + try { + if (fileis != null) + fileis.close(); + if (fileis != null) + baos.close(); + } catch (IOException e) { + log.error(e.getMessage(), e); + } + } + log.error(fileis + "这个路径文件没有找到,请查询"); + return null; + } + +} diff --git a/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/cache/manager/POICacheManager.java b/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/cache/manager/POICacheManager.java new file mode 100644 index 000000000..217741ce7 --- /dev/null +++ b/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/cache/manager/POICacheManager.java @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2018-2025, lengleng All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * Neither the name of the pig4cloud.com developer nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * Author: lengleng (wangiegie@gmail.com) + */ +package com.pig4cloud.pigx.common.poi.cache.manager; + +import com.google.common.cache.CacheBuilder; +import com.google.common.cache.CacheLoader; +import com.google.common.cache.LoadingCache; +import lombok.extern.slf4j.Slf4j; + +import java.io.ByteArrayInputStream; +import java.io.InputStream; +import java.util.Arrays; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeUnit; + +/** + * @author: Luckly + * @date: 2019-05-20 + *

+ * 缓存管理 + */ +@Slf4j +public final class POICacheManager { + + private static LoadingCache loadingCache; + + static { + loadingCache = CacheBuilder.newBuilder().expireAfterWrite(7, TimeUnit.DAYS).maximumSize(50).build(new CacheLoader() { + @Override + public byte[] load(String url) throws Exception { + return new FileLoade().getFile(url); + } + }); + } + + public static InputStream getFile(String id) { + try { + // 复杂数据,防止操作原数据 + byte[] result = Arrays.copyOf(loadingCache.get(id), loadingCache.get(id).length); + return new ByteArrayInputStream(result); + } catch (ExecutionException e) { + log.error(e.getMessage(), e); + } + return null; + } + +} diff --git a/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/cache/package-info.java b/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/cache/package-info.java new file mode 100644 index 000000000..a3c6a7095 --- /dev/null +++ b/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/cache/package-info.java @@ -0,0 +1,9 @@ +/** + * @author: Luckly + * @date: 2019-05-20 + *

+ * 对POI用到的模板进行缓存,进行统一管理,缓存工具暂时使用guava(脱离配置文件) + * 缓存方式统一为byte[] 屏蔽文件类型的差异 + * 缓存获取方式,URL或者URL+index(EXcel的) + */ +package com.pig4cloud.pigx.common.poi.cache; \ No newline at end of file diff --git a/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/ExcelExportUtil.java b/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/ExcelExportUtil.java new file mode 100644 index 000000000..930248e10 --- /dev/null +++ b/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/ExcelExportUtil.java @@ -0,0 +1,114 @@ +package com.pig4cloud.pigx.common.poi.excel; + +import java.util.Collection; +import java.util.List; +import java.util.Map; + +import org.apache.poi.hssf.usermodel.HSSFWorkbook; +import org.apache.poi.ss.usermodel.Workbook; +import org.apache.poi.xssf.streaming.SXSSFWorkbook; +import org.apache.poi.xssf.usermodel.XSSFWorkbook; +import com.pig4cloud.pigx.common.poi.excel.entity.ExportParams; +import com.pig4cloud.pigx.common.poi.excel.entity.TemplateExportParams; +import com.pig4cloud.pigx.common.poi.excel.entity.enmus.ExcelType; +import com.pig4cloud.pigx.common.poi.excel.entity.params.ExcelExportEntity; +import com.pig4cloud.pigx.common.poi.excel.export.ExcelExportServer; +import com.pig4cloud.pigx.common.poi.excel.export.template.ExcelExportOfTemplateUtil; + +/** + * @author: Luckly + * @date: 2019-05-20 + *

+ * excel 导出工具类 + */ +public final class ExcelExportUtil { + + private ExcelExportUtil() { + } + + /** + * 根据Entity创建对应的Excel + * + * @param entity 表格标题属性 + * @param pojoClass Excel对象Class + * @param dataSet Excel对象数据List + */ + public static Workbook exportExcel(ExportParams entity, Class pojoClass, Collection dataSet) { + Workbook workbook; + if (ExcelType.HSSF.equals(entity.getType())) { + workbook = new HSSFWorkbook(); + } else if (dataSet.size() < 1000) { + workbook = new XSSFWorkbook(); + } else { + workbook = new SXSSFWorkbook(); + } + new ExcelExportServer().createSheet(workbook, entity, pojoClass, dataSet); + return workbook; + } + + /** + * 根据Map创建对应的Excel + * + * @param entity 表格标题属性 + * @param dataSet Excel对象Class + * @param entityList Excel对象数据List + */ + public static Workbook exportExcel(ExportParams entity, List entityList, Collection> dataSet) { + Workbook workbook; + if (ExcelType.HSSF.equals(entity.getType())) { + workbook = new HSSFWorkbook(); + } else if (dataSet.size() < 1000) { + workbook = new XSSFWorkbook(); + } else { + workbook = new SXSSFWorkbook(); + } + new ExcelExportServer().createSheetForMap(workbook, entity, entityList, dataSet); + return workbook; + } + + /** + * 一个excel 创建多个sheet + * + * @param list 多个Map key title 对应表格Title key entity 对应表格对应实体 key data + * Collection 数据 + * @return + */ + public static Workbook exportExcel(List> list, String type) { + Workbook workbook; + if (ExcelType.HSSF.equals(type)) { + workbook = new HSSFWorkbook(); + } else { + workbook = new XSSFWorkbook(); + } + for (Map map : list) { + ExcelExportServer server = new ExcelExportServer(); + server.createSheet(workbook, (ExportParams) map.get("title"), (Class) map.get("entity"), (Collection) map.get("data")); + } + return workbook; + } + + /** + * 导出文件通过模板解析,不推荐这个了,推荐全部通过模板来执行处理 + * + * @param params 导出参数类 + * @param pojoClass 对应实体 + * @param dataSet 实体集合 + * @param map 模板集合 + * @return + */ + public static Workbook exportExcel(TemplateExportParams params, Class pojoClass, Collection dataSet, Map map) { + return new ExcelExportOfTemplateUtil().createExcleByTemplate(params, pojoClass, dataSet, map); + } + + /** + * 导出文件通过模板解析只有模板,没有集合 + * + * @param params 导出参数类 + * @param map 模板集合 + * @return + */ + public static Workbook exportExcel(TemplateExportParams params, Map map) { + return new ExcelExportOfTemplateUtil().createExcleByTemplate(params, null, null, map); + } + +} diff --git a/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/ExcelImportUtil.java b/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/ExcelImportUtil.java new file mode 100644 index 000000000..a9d5fefbe --- /dev/null +++ b/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/ExcelImportUtil.java @@ -0,0 +1,153 @@ +package com.pig4cloud.pigx.common.poi.excel; + +import com.pig4cloud.pigx.common.poi.excel.entity.ImportParams; +import com.pig4cloud.pigx.common.poi.excel.entity.result.ExcelImportResult; +import com.pig4cloud.pigx.common.poi.excel.imports.ExcelImportServer; +import com.pig4cloud.pigx.common.poi.excel.imports.sax.SaxReadExcel; +import com.pig4cloud.pigx.common.poi.excel.imports.sax.parse.ISaxRowRead; +import com.pig4cloud.pigx.common.poi.handler.inter.IExcelReadRowHanlder; +import lombok.extern.slf4j.Slf4j; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.List; + +/** + * Excel 导入工具 + * + * @author: Luckly + * @date: 2019-05-20 + *

+ */ +@Slf4j +@SuppressWarnings({"unchecked"}) +public final class ExcelImportUtil { + + private ExcelImportUtil() { + } + + /** + * Excel 导入 数据源本地文件,不返回校验结果 导入 字 段类型 Integer,Long,Double,Date,String,Boolean + * + * @param file + * @param pojoClass + * @param params + * @return + * @throws Exception + */ + public static List importExcel(File file, Class pojoClass, ImportParams params) { + FileInputStream in = null; + List result = null; + try { + in = new FileInputStream(file); + result = new ExcelImportServer().importExcelByIs(in, pojoClass, params).getList(); + } catch (Exception e) { + log.error(e.getMessage(), e); + } finally { + try { + in.close(); + } catch (IOException e) { + log.error(e.getMessage(), e); + } + } + return result; + } + + /** + * Excel 导入 数据源IO流,不返回校验结果 导入 字段类型 Integer,Long,Double,Date,String,Boolean + * + * @param inputstream + * @param pojoClass + * @param params + * @param + * @return + * @throws Exception + */ + public static List importExcel(InputStream inputstream, Class pojoClass, ImportParams params) throws Exception { + return new ExcelImportServer().importExcelByIs(inputstream, pojoClass, params).getList(); + } + + /** + * Excel 导入 数据源IO流,返回校验结果 字段类型 Integer,Long,Double,Date,String,Boolean + * + * @param inputstream + * @param pojoClass + * @param params + * @param + * @return + * @throws Exception + */ + public static ExcelImportResult importExcelVerify(InputStream inputstream, Class pojoClass, ImportParams params) throws Exception { + return new ExcelImportServer().importExcelByIs(inputstream, pojoClass, params); + } + + /** + * Excel 导入 数据源本地文件,返回校验结果 字段类型 Integer,Long,Double,Date,String,Boolean + * + * @param file + * @param pojoClass + * @param params + * @return + * @throws Exception + */ + public static ExcelImportResult importExcelVerify(File file, Class pojoClass, ImportParams params) { + FileInputStream in = null; + try { + in = new FileInputStream(file); + return new ExcelImportServer().importExcelByIs(in, pojoClass, params); + } catch (Exception e) { + log.error(e.getMessage(), e); + } finally { + try { + in.close(); + } catch (IOException e) { + log.error(e.getMessage(), e); + } + } + return null; + } + + /** + * Excel 通过SAX解析方法,适合大数据导入,不支持图片 导入 数据源IO流,不返回校验结果 导入 字段类型 + * Integer,Long,Double,Date,String,Boolean + * + * @param inputstream + * @param pojoClass + * @param params + * @return + * @throws Exception + */ + public static List importExcelBySax(InputStream inputstream, Class pojoClass, ImportParams params) { + return new SaxReadExcel().readExcel(inputstream, pojoClass, params, null, null); + } + + /** + * Excel 通过SAX解析方法,适合大数据导入,不支持图片 导入 数据源本地文件,不返回校验结果 导入 字 段类型 + * Integer,Long,Double,Date,String,Boolean + * + * @param inputstream + * @param pojoClass + * @param params + * @param hanlder + */ + @SuppressWarnings("rawtypes") + public static void importExcelBySax(InputStream inputstream, Class pojoClass, ImportParams params, IExcelReadRowHanlder hanlder) { + new SaxReadExcel().readExcel(inputstream, pojoClass, params, null, hanlder); + } + + /** + * Excel 通过SAX解析方法,适合大数据导入,不支持图片 导入 数据源IO流,不返回校验结果 导入 字段类型 + * Integer,Long,Double,Date,String,Boolean + * + * @param inputstream + * @param rowRead + * @param + * @return + */ + public static List importExcelBySax(InputStream inputstream, ISaxRowRead rowRead) { + return new SaxReadExcel().readExcel(inputstream, null, null, rowRead, null); + } + +} diff --git a/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/ExcelToHtmlUtil.java b/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/ExcelToHtmlUtil.java new file mode 100644 index 000000000..d449d2dbe --- /dev/null +++ b/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/ExcelToHtmlUtil.java @@ -0,0 +1,60 @@ +package com.pig4cloud.pigx.common.poi.excel; + +import com.pig4cloud.pigx.common.poi.excel.html.ExcelToHtmlServer; +import org.apache.poi.ss.usermodel.Workbook; + +/** + * + * @author: Luckly + * @date: 2019-05-20 + *

+ * Excel 变成界面 + */ +public final class ExcelToHtmlUtil { + + private ExcelToHtmlUtil() { + } + + /** + * 转换成为Table + * + * @param wb Excel + * @return + */ + public static String toTableHtml(Workbook wb) { + return new ExcelToHtmlServer(wb, false, 0).printPage(); + } + + /** + * 转换成为Table + * + * @param wb Excel + * @param sheetNum sheetNum + * @return + */ + public static String toTableHtml(Workbook wb, int sheetNum) { + return new ExcelToHtmlServer(wb, false, sheetNum).printPage(); + } + + /** + * 转换成为完整界面 + * + * @param wb Excel + * @return + */ + public static String toAllHtml(Workbook wb) { + return new ExcelToHtmlServer(wb, true, 0).printPage(); + } + + /** + * 转换成为完整界面 + * + * @param wb Excel + * @param sheetNum sheetNum + * @return + */ + public static String toAllHtml(Workbook wb, int sheetNum) { + return new ExcelToHtmlServer(wb, true, sheetNum).printPage(); + } + +} diff --git a/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/annotation/Excel.java b/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/annotation/Excel.java new file mode 100644 index 000000000..e343a68de --- /dev/null +++ b/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/annotation/Excel.java @@ -0,0 +1,205 @@ +/* + * Copyright (c) 2018-2025, lengleng All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * Neither the name of the pig4cloud.com developer nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * Author: lengleng (wangiegie@gmail.com) + */ +package com.pig4cloud.pigx.common.poi.excel.annotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * @author: Luckly + * @date: 2019-05-20 + *

+ * Excel 导出基本注释 + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.FIELD) +public @interface Excel { + + /** + * 导出时间设置,如果字段是Date类型则不需要设置 数据库如果是string 类型,这个需要设置这个数据库格式 + * + * @return 返回类型: String + */ + String databaseFormat() default "yyyyMMddHHmmss"; + + /** + * 导出的时间格式,以这个是否为空来判断是否需要格式化日期 + * + * @return 返回类型: String + */ + String exportFormat() default ""; + + /** + * 时间格式,相当于同时设置了exportFormat 和 importFormat + * + * @return 返回类型: String + */ + String format() default ""; + + /** + * 导出时在excel中每个列的高度 单位为字符,一个汉字=2个字符 + * + * @return 返回类型: double + */ + double height() default 10; + + /** + * 导出类型 1 从file读取 2 是从数据库中读取 默认是文件 同样导入也是一样的 + * + * @return 返回类型: int + */ + int imageType() default 1; + + /** + * 导入的时间格式,以这个是否为空来判断是否需要格式化日期 + * + * @return 返回类型: String + */ + String importFormat() default ""; + + /** + * 文字后缀,如% 90 变成90% + * + * @return 返回类型: String + */ + String suffix() default ""; + + /** + * 是否换行 即支持\n + * + * @return 返回类型: boolean + */ + boolean isWrap() default true; + + /** + * 合并单元格依赖关系,比如第二列合并是基于第一列 则{1}就可以了 + * + * @return 返回类型: int[] + */ + int[] mergeRely() default {}; + + /** + * 纵向合并内容相同的单元格 + * + * @return 返回类型: boolean + */ + boolean mergeVertical() default false; + + /** + * 导出时,对应数据库的字段 主要是用户区分每个字段, 不能有annocation重名的 导出时的列名 + * 导出排序跟定义了annotation的字段的顺序有关 可以使用a_id,b_id来确实是否使用 + * + * @return 返回类型: String + */ + String name(); + + /** + * 是否需要纵向合并单元格(用于含有list中,单个的单元格,合并list创建的多个row) + * + * @return 返回类型: boolean + */ + boolean needMerge() default false; + + /** + * 展示到第几个可以使用a_id,b_id来确定不同排序 + * + * @return 返回类型: String + */ + String orderNum() default "0"; + + /** + * 值得替换 导出是{"男_1","女_0"} 导入反过来,所以只用写一个 + * + * @return 返回类型: String[] + */ + String[] replace() default {}; + + /** + * 导入路径,如果是图片可以填写,默认是upload/className/ IconEntity这个类对应的就是upload/Icon/ + * + * @return 返回类型: String + */ + String savePath() default "upload"; + + /** + * 导出类型 1 是文本 2 是图片,3是函数,4是数字 默认是文本 + * + * @return 返回类型: int + */ + int type() default 1; + + /** + * 导出时在excel中每个列的宽 单位为字符,一个汉字=2个字符 如 以列名列内容中较合适的长度 例如姓名列6 【姓名一般三个字】 + * 性别列4【男女占1,但是列标题两个汉字】 限制1-255 + * + * @return 返回类型: double + */ + double width() default 10; + + /** + * 是否自动统计数据,如果是统计,true的话在最后追加一行统计,把所有数据都和 这个处理会吞没异常,请注意这一点 + * + * @return 返回类型: boolean + */ + boolean isStatistics() default false; + + /** + * 数据字典表 + * + * @return 返回类型: String + */ + String dictTable() default ""; + + /** + * 数据code + * + * @return 返回类型: String + */ + String dicCode() default ""; + + /** + * 数据Text + * + * @return 返回类型: String + */ + String dicText() default ""; + + /** + * 导入数据是否需要转化 + * 若是为true,则需要在pojo中加入 方法:convertset字段名(String text) + * + * @return 返回类型: boolean + */ + boolean importConvert() default false; + + /** + * 导出数据是否需要转化 + * 若是为true,则需要在pojo中加入方法:convertget字段名() + * + * @return 返回类型: boolean + */ + boolean exportConvert() default false; + + /** + * 值的替换是否支持替换多个(默认true,若数据库值本来就包含逗号则需要配置该值为false) + * + * @return 返回类型: boolean + */ + boolean multiReplace() default true; +} diff --git a/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/annotation/ExcelCollection.java b/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/annotation/ExcelCollection.java new file mode 100644 index 000000000..fafb22771 --- /dev/null +++ b/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/annotation/ExcelCollection.java @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2018-2025, lengleng All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * Neither the name of the pig4cloud.com developer nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * Author: lengleng (wangiegie@gmail.com) + */ +package com.pig4cloud.pigx.common.poi.excel.annotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import java.util.ArrayList; + +/** + * @author: Luckly + * @date: 2019-05-20 + *

+ * 导出的集合 + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.FIELD) +public @interface ExcelCollection { + + /** + * 定义excel导出ID 来限定导出字段,处理一个类对应多个不同名称的情况 + */ + String id() default ""; + + /** + * 导出时,对应数据库的字段 主要是用户区分每个字段, 不能有annocation重名的 导出时的列名 + * 导出排序跟定义了annotation的字段的顺序有关 可以使用a_id,b_id来确实是否使用 + */ + String name(); + + /** + * 展示到第几个同样可以使用a_id,b_id + * + */ + String orderNum() default "0"; + + /** + * 创建时创建的类型 默认值是 arrayList + */ + Class type() default ArrayList.class; +} diff --git a/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/annotation/ExcelEntity.java b/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/annotation/ExcelEntity.java new file mode 100644 index 000000000..1fdebb09e --- /dev/null +++ b/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/annotation/ExcelEntity.java @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2018-2025, lengleng All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * Neither the name of the pig4cloud.com developer nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * Author: lengleng (wangiegie@gmail.com) + */ +package com.pig4cloud.pigx.common.poi.excel.annotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * @author: Luckly + * @date: 2019-05-20 + *

+ * 标记是不是导出excel 标记为实体类 + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.FIELD) +public @interface ExcelEntity { + + /** + * 定义excel导出ID 来限定导出字段,处理一个类对应多个不同名称的情况 + */ + String id() default ""; + + /** + * 导出时,对应数据库的字段 主要是用户区分每个字段, 不能有annocation重名的 导出时的列名 + * 导出排序跟定义了annotation的字段的顺序有关 可以使用a_id,b_id来确实是否使用 + */ + String name() default ""; +} diff --git a/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/annotation/ExcelIgnore.java b/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/annotation/ExcelIgnore.java new file mode 100644 index 000000000..923c520c7 --- /dev/null +++ b/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/annotation/ExcelIgnore.java @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2018-2025, lengleng All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * Neither the name of the pig4cloud.com developer nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * Author: lengleng (wangiegie@gmail.com) + */ +package com.pig4cloud.pigx.common.poi.excel.annotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * @author: Luckly + * @date: 2019-05-20 + *

+ * 标记为excel 创建实体忽略 + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.FIELD) +public @interface ExcelIgnore { + +} diff --git a/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/annotation/ExcelTarget.java b/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/annotation/ExcelTarget.java new file mode 100644 index 000000000..3740495aa --- /dev/null +++ b/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/annotation/ExcelTarget.java @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2018-2025, lengleng All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * Neither the name of the pig4cloud.com developer nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * Author: lengleng (wangiegie@gmail.com) + */ +package com.pig4cloud.pigx.common.poi.excel.annotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * @author: Luckly + * @date: 2019-05-20 + *

+ * excel 导出是用于标记id的 + */ +@Retention(RetentionPolicy.RUNTIME) +@Target({ ElementType.TYPE }) +public @interface ExcelTarget { + /** + * 定义excel导出ID 来限定导出字段 + */ + String value(); +} diff --git a/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/annotation/ExcelVerify.java b/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/annotation/ExcelVerify.java new file mode 100644 index 000000000..56e35e8a5 --- /dev/null +++ b/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/annotation/ExcelVerify.java @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2018-2025, lengleng All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * Neither the name of the pig4cloud.com developer nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * Author: lengleng (wangiegie@gmail.com) + */ +package com.pig4cloud.pigx.common.poi.excel.annotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * @author: Luckly + * @date: 2019-05-20 + *

+ * Excel 导入校验 + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.FIELD) +public @interface ExcelVerify { + /** + * 接口校验 + * + * @return + */ + boolean interHandler() default false; + + /** + * 是电子邮件 + * + * @return + */ + boolean isEmail() default false; + + /** + * 是13位移动电话 + * + * @return + */ + boolean isMobile() default false; + + /** + * 是座机号码 + * + * @return + */ + boolean isTel() default false; + + /** + * 最大长度 + * + * @return + */ + int maxLength() default -1; + + /** + * 最小长度 + * + * @return + */ + int minLength() default -1; + + /** + * 不允许空 + * + * @return + */ + boolean notNull() default false; + + /** + * 正在表达式 + * + * @return + */ + String regex() default ""; + + /** + * 正在表达式,错误提示信息 + * + * @return + */ + String regexTip() default "数据不符合规范"; + +} diff --git a/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/def/BasePOIConstants.java b/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/def/BasePOIConstants.java new file mode 100644 index 000000000..d9631cec2 --- /dev/null +++ b/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/def/BasePOIConstants.java @@ -0,0 +1,24 @@ +package com.pig4cloud.pigx.common.poi.excel.def; + +/** + * @author: Luckly + * @date: 2019-05-20 + *

+ * 基础POI常量 + */ +interface BasePOIConstants { + + /** + * 注解对象 + */ + String CLASS = "entity"; + /** + * 表格参数 + */ + String PARAMS = "params"; + /** + * 下载文件名称 + */ + String FILE_NAME = "fileName"; + +} diff --git a/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/def/MapExcelConstants.java b/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/def/MapExcelConstants.java new file mode 100644 index 000000000..b49258c05 --- /dev/null +++ b/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/def/MapExcelConstants.java @@ -0,0 +1,24 @@ +package com.pig4cloud.pigx.common.poi.excel.def; + +/** + * + * @author: Luckly + * @date: 2019-05-20 + *

+ * 正常导出Excel + */ +public interface MapExcelConstants extends BasePOIConstants { + /** + * 单Sheet导出 + */ + String PIGX_MAP_EXCEL_VIEW = "pigxMapExcelView"; + /** + * Entity List + */ + String ENTITY_LIST = "data"; + /** + * 数据列表 + */ + String MAP_LIST = "mapList"; + +} diff --git a/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/def/NormalExcelConstants.java b/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/def/NormalExcelConstants.java new file mode 100644 index 000000000..676afae9f --- /dev/null +++ b/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/def/NormalExcelConstants.java @@ -0,0 +1,23 @@ +package com.pig4cloud.pigx.common.poi.excel.def; + +/** + * @author: Luckly + * @date: 2019-05-20 + *

+ * 正常导出Excel + */ +public interface NormalExcelConstants extends BasePOIConstants { + /** + * 单Sheet导出 + */ + String PIGX_ENTITY_EXCEL_VIEW = "pigxEntityExcelView"; + /** + * 数据列表 + */ + String DATA_LIST = "data"; + /** + * 多Sheet 对象 + */ + String MAP_LIST = "mapList"; + +} diff --git a/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/def/TemplateExcelConstants.java b/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/def/TemplateExcelConstants.java new file mode 100644 index 000000000..d816f5997 --- /dev/null +++ b/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/def/TemplateExcelConstants.java @@ -0,0 +1,23 @@ +package com.pig4cloud.pigx.common.poi.excel.def; + +/** + * @author: Luckly + * @date: 2019-05-20 + *

+ * 模板Excel导出常量 + */ +public interface TemplateExcelConstants extends BasePOIConstants { + /** + * 模板导出 + */ + String PIGX_TEMPLATE_EXCEL_VIEW = "pigxTemplateExcelView"; + /** + * 数据列表 + */ + String LIST_DATA = "list"; + /** + * 模板参数 + */ + String MAP_DATA = "map"; + +} diff --git a/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/def/TemplateWordConstants.java b/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/def/TemplateWordConstants.java new file mode 100644 index 000000000..3278a029f --- /dev/null +++ b/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/def/TemplateWordConstants.java @@ -0,0 +1,23 @@ +package com.pig4cloud.pigx.common.poi.excel.def; + +/** + * @author: Luckly + * @date: 2019-05-20 + *

+ * Word 导出模板常量 + */ +public interface TemplateWordConstants extends BasePOIConstants { + /** + * 模板导出 + */ + String PIGX_TEMPLATE_WORD_VIEW = "pigxTemplateWordView"; + /** + * 数据列表 + */ + String URL = "url"; + /** + * 模板参数 + */ + String MAP_DATA = "map"; + +} diff --git a/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/entity/ExcelBaseParams.java b/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/entity/ExcelBaseParams.java new file mode 100644 index 000000000..f0f794ee2 --- /dev/null +++ b/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/entity/ExcelBaseParams.java @@ -0,0 +1,26 @@ +package com.pig4cloud.pigx.common.poi.excel.entity; + +import com.pig4cloud.pigx.common.poi.handler.inter.IExcelDataHandler; + +/** + * @author: Luckly + * @date: 2019-05-20 + *

+ * 基础参数 + */ +public class ExcelBaseParams { + + /** + * 数据处理接口,以此为主,replace,format都在这后面 + */ + private IExcelDataHandler dataHanlder; + + public IExcelDataHandler getDataHanlder() { + return dataHanlder; + } + + public void setDataHanlder(IExcelDataHandler dataHanlder) { + this.dataHanlder = dataHanlder; + } + +} diff --git a/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/entity/ExportParams.java b/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/entity/ExportParams.java new file mode 100644 index 000000000..0f286b84d --- /dev/null +++ b/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/entity/ExportParams.java @@ -0,0 +1,106 @@ +package com.pig4cloud.pigx.common.poi.excel.entity; + +import lombok.Data; +import org.apache.poi.hssf.util.HSSFColor; +import com.pig4cloud.pigx.common.poi.excel.entity.enmus.ExcelType; +import com.pig4cloud.pigx.common.poi.excel.export.styler.ExcelExportStylerDefaultImpl; + +/** + * @author: Luckly + * @date: 2019-05-20 + *

+ * Excel 导出参数 + */ +@Data +public class ExportParams extends ExcelBaseParams { + + /** + * 表格名称 + */ + private String title; + + /** + * 表格名称 + */ + private short titleHeight = 10; + + /** + * 第二行名称 + */ + private String secondTitle; + + /** + * 表格名称 + */ + private short secondTitleHeight = 8; + /** + * sheetName + */ + private String sheetName; + /** + * 过滤的属性 + */ + private String[] exclusions; + /** + * 是否添加需要需要 + */ + private boolean addIndex; + /** + * 是否添加需要需要 + */ + private String indexName = "序号"; + /** + * 冰冻列 + */ + private int freezeCol; + /** + * 表头颜色 + */ + private short color = HSSFColor.WHITE.index; + /** + * 属性说明行的颜色 例如:HSSFColor.SKY_BLUE.index 默认 + */ + private short headerColor = HSSFColor.SKY_BLUE.index; + /** + * Excel 导出版本 + */ + private ExcelType type = ExcelType.HSSF; + /** + * Excel 导出style + */ + private Class style = ExcelExportStylerDefaultImpl.class; + /** + * 是否创建表头 + */ + private boolean isCreateHeadRows = true; + + public ExportParams() { + + } + + public ExportParams(String title, String sheetName) { + this.title = title; + this.sheetName = sheetName; + } + + public ExportParams(String title, String sheetName, ExcelType type) { + this.title = title; + this.sheetName = sheetName; + this.type = type; + } + + public ExportParams(String title, String secondTitle, String sheetName) { + this.title = title; + this.secondTitle = secondTitle; + this.sheetName = sheetName; + } + + public short getSecondTitleHeight() { + return (short) (secondTitleHeight * 50); + } + + public short getTitleHeight() { + return (short) (titleHeight * 50); + } + +} diff --git a/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/entity/ImportParams.java b/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/entity/ImportParams.java new file mode 100644 index 000000000..b59125847 --- /dev/null +++ b/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/entity/ImportParams.java @@ -0,0 +1,52 @@ +package com.pig4cloud.pigx.common.poi.excel.entity; + +import com.pig4cloud.pigx.common.poi.handler.inter.IExcelVerifyHandler; +import lombok.Data; + +/** + * @author: Luckly + * @date: 2019-05-20 + *

+ * 导入参数设置 + */ +@Data +public class ImportParams extends ExcelBaseParams { + /** + * 表格标题行数,默认0 + */ + private int titleRows = 0; + /** + * 表头行数,默认1 + */ + private int headRows = 1; + /** + * 字段真正值和列标题之间的距离 默认0 + */ + private int startRows = 0; + /** + * 主键设置,如何这个cell没有值,就跳过 或者认为这个是list的下面的值 + */ + private int keyIndex = 0; + /** + * 上传表格需要读取的sheet 数量,默认为1 + */ + private int sheetNum = 1; + /** + * 是否需要保存上传的Excel,默认为false + */ + private boolean needSave = false; + /** + * 保存上传的Excel目录,默认是 如 TestEntity这个类保存路径就是 + * upload/excelUpload/Test/yyyyMMddHHmss_***** 保存名称上传时间_五位随机数 + */ + private String saveUrl = "upload/excelUpload"; + /** + * 校验处理接口 + */ + private IExcelVerifyHandler verifyHanlder; + /** + * 最后的无效行数 + */ + private int lastOfInvalidRow = 0; + +} diff --git a/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/entity/TemplateExportParams.java b/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/entity/TemplateExportParams.java new file mode 100644 index 000000000..8b61a3c88 --- /dev/null +++ b/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/entity/TemplateExportParams.java @@ -0,0 +1,107 @@ +package com.pig4cloud.pigx.common.poi.excel.entity; + +import com.pig4cloud.pigx.common.poi.excel.export.styler.ExcelExportStylerDefaultImpl; +import lombok.Data; + +/** + * @author: Luckly + * @date: 2019-05-20 + *

+ * 模板导出参数设置 + */ +@Data +public class TemplateExportParams extends ExcelBaseParams { + + /** + * 输出全部的sheet + */ + private boolean scanAllsheet = false; + /** + * 模板的路径 + */ + private String templateUrl; + + /** + * 需要导出的第几个 sheetNum,默认是第0个 + */ + private Integer[] sheetNum = new Integer[]{0}; + + /** + * 这只sheetName 不填就使用原来的 + */ + private String[] sheetName; + + /** + * 表格列标题行数,默认1 + */ + private int headingRows = 1; + + /** + * 表格列标题开始行,默认1 + */ + private int headingStartRow = 1; + /** + * 设置数据源的NUM + */ + private int dataSheetNum = 0; + /** + * Excel 导出style + */ + private Class style = ExcelExportStylerDefaultImpl.class; + /** + * FOR EACH 用到的局部变量 + */ + private String tempParams = "t"; + + /** + * 默认构造器 + */ + public TemplateExportParams() { + + } + + /** + * 构造器 + * + * @param templateUrl 模板路径 + * @param scanAllsheet 是否输出全部的sheet + * @param sheetName sheet的名称,可不填 + */ + public TemplateExportParams(String templateUrl, boolean scanAllsheet, String... sheetName) { + this.templateUrl = templateUrl; + this.scanAllsheet = scanAllsheet; + if (sheetName != null && sheetName.length > 0) { + this.sheetName = sheetName; + + } + } + + /** + * 构造器 + * + * @param templateUrl 模板路径 + * @param sheetNum sheet 的位置,可不填 + */ + public TemplateExportParams(String templateUrl, Integer... sheetNum) { + this.templateUrl = templateUrl; + if (sheetNum != null && sheetNum.length > 0) { + this.sheetNum = sheetNum; + } + } + + /** + * 单个sheet输出构造器 + * + * @param templateUrl 模板路径 + * @param sheetName sheet的名称 + * @param sheetNum sheet的位置,可不填 + */ + public TemplateExportParams(String templateUrl, String sheetName, Integer... sheetNum) { + this.templateUrl = templateUrl; + this.sheetName = new String[]{sheetName}; + if (sheetNum != null && sheetNum.length > 0) { + this.sheetNum = sheetNum; + } + } + +} diff --git a/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/entity/enmus/CellValueType.java b/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/entity/enmus/CellValueType.java new file mode 100644 index 000000000..337e93d00 --- /dev/null +++ b/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/entity/enmus/CellValueType.java @@ -0,0 +1,13 @@ +package com.pig4cloud.pigx.common.poi.excel.entity.enmus; + +/** + * Cell 值得类型 + * @author: Luckly + * @date: 2019-05-20 + *

+ */ +public enum CellValueType { + + String, Number, Boolean, Date, TElement, Null, None; + +} diff --git a/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/entity/enmus/ExcelStyleType.java b/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/entity/enmus/ExcelStyleType.java new file mode 100644 index 000000000..2d0f81b25 --- /dev/null +++ b/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/entity/enmus/ExcelStyleType.java @@ -0,0 +1,35 @@ +package com.pig4cloud.pigx.common.poi.excel.entity.enmus; + +import com.pig4cloud.pigx.common.poi.excel.export.styler.ExcelExportStylerBorderImpl; +import com.pig4cloud.pigx.common.poi.excel.export.styler.ExcelExportStylerColorImpl; +import com.pig4cloud.pigx.common.poi.excel.export.styler.ExcelExportStylerDefaultImpl; + +/** + * @author: Luckly + * @date: 2019-05-20 + *

+ * 插件提供的几个默认样式 + */ +public enum ExcelStyleType { + + NONE("默认样式", ExcelExportStylerDefaultImpl.class), + BORDER("边框样式", ExcelExportStylerBorderImpl.class), + COLOR("间隔行样式", ExcelExportStylerColorImpl.class); + + private String name; + private Class clazz; + + ExcelStyleType(String name, Class clazz) { + this.name = name; + this.clazz = clazz; + } + + public Class getClazz() { + return clazz; + } + + public String getName() { + return name; + } + +} diff --git a/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/entity/enmus/ExcelType.java b/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/entity/enmus/ExcelType.java new file mode 100644 index 000000000..7370566e7 --- /dev/null +++ b/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/entity/enmus/ExcelType.java @@ -0,0 +1,13 @@ +package com.pig4cloud.pigx.common.poi.excel.entity.enmus; + +/** + * Excel Type + * @author: Luckly + * @date: 2019-05-20 + *

+ */ +public enum ExcelType { + + HSSF, XSSF; + +} diff --git a/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/entity/params/ExcelBaseEntity.java b/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/entity/params/ExcelBaseEntity.java new file mode 100644 index 000000000..887a75387 --- /dev/null +++ b/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/entity/params/ExcelBaseEntity.java @@ -0,0 +1,49 @@ +package com.pig4cloud.pigx.common.poi.excel.entity.params; + +import lombok.Data; + +import java.lang.reflect.Method; +import java.util.List; + +/** + * @author: Luckly + * @date: 2019-05-20 + *

+ * Excel 导入导出基础对象类 + */ +@Data +public class ExcelBaseEntity { + /** + * 对应name + */ + protected String name; + /** + * 对应type + */ + private int type = 1; + /** + * 数据库格式 + */ + private String databaseFormat; + /** + * 导出日期格式 + */ + private String format; + /** + * 替换值表达式 :"男_1","女_0" + */ + private String[] replace; + /** + * 替换是否是替换多个值 + */ + private boolean multiReplace; + /** + * set/get方法 + */ + private Method method; + /** + * set/get方法 + */ + private List methods; + +} diff --git a/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/entity/params/ExcelCollectionParams.java b/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/entity/params/ExcelCollectionParams.java new file mode 100644 index 000000000..005d12cc5 --- /dev/null +++ b/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/entity/params/ExcelCollectionParams.java @@ -0,0 +1,33 @@ +package com.pig4cloud.pigx.common.poi.excel.entity.params; + +import lombok.Data; + +import java.util.Map; + +/** + * Excel 对于的 Collection + * @author: Luckly + * @date: 2019-05-20 + *

+ */ +@Data +public class ExcelCollectionParams { + + /** + * 集合对应的名称 + */ + private String name; + /** + * Excel 列名称 + */ + private String excelName; + /** + * 实体对象 + */ + private Class type; + /** + * 这个list下面的参数集合实体对象 + */ + private Map excelParams; + +} diff --git a/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/entity/params/ExcelExportEntity.java b/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/entity/params/ExcelExportEntity.java new file mode 100644 index 000000000..fb0ef8141 --- /dev/null +++ b/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/entity/params/ExcelExportEntity.java @@ -0,0 +1,180 @@ +package com.pig4cloud.pigx.common.poi.excel.entity.params; + +import java.util.List; + +/** + * excel 导出工具类,对cell类型做映射 + * @author: Luckly + * @date: 2019-05-20 + *

+ */ +public class ExcelExportEntity extends ExcelBaseEntity implements Comparable { + + /** + * 如果是MAP导出,这个是map的key + */ + private Object key; + + private double width = 10; + + private double height = 10; + + /** + * 图片的类型,1是文件,2是数据库 + */ + private int exportImageType = 0; + + /** + * 排序顺序 + */ + private int orderNum = 0; + + /** + * 是否支持换行 + */ + private boolean isWrap; + + /** + * 是否需要合并 + */ + private boolean needMerge; + /** + * 单元格纵向合并 + */ + private boolean mergeVertical; + /** + * 合并依赖 + */ + private int[] mergeRely; + /** + * 后缀 + */ + private String suffix; + /** + * 统计 + */ + private boolean isStatistics; + + private List list; + + public ExcelExportEntity() { + + } + + public ExcelExportEntity(String name) { + super.name = name; + } + + public ExcelExportEntity(String name, Object key) { + super.name = name; + this.key = key; + } + + public ExcelExportEntity(String name, Object key, int width) { + super.name = name; + this.width = width; + this.key = key; + } + + public int getExportImageType() { + return exportImageType; + } + + public double getHeight() { + return height; + } + + public Object getKey() { + return key; + } + + public List getList() { + return list; + } + + public int[] getMergeRely() { + return mergeRely == null ? new int[0] : mergeRely; + } + + public int getOrderNum() { + return orderNum; + } + + public double getWidth() { + return width; + } + + public boolean isMergeVertical() { + return mergeVertical; + } + + public boolean isNeedMerge() { + return needMerge; + } + + public boolean isWrap() { + return isWrap; + } + + public void setExportImageType(int exportImageType) { + this.exportImageType = exportImageType; + } + + public void setHeight(double height) { + this.height = height; + } + + public void setKey(Object key) { + this.key = key; + } + + public void setList(List list) { + this.list = list; + } + + public void setMergeRely(int[] mergeRely) { + this.mergeRely = mergeRely; + } + + public void setMergeVertical(boolean mergeVertical) { + this.mergeVertical = mergeVertical; + } + + public void setNeedMerge(boolean needMerge) { + this.needMerge = needMerge; + } + + public void setOrderNum(int orderNum) { + this.orderNum = orderNum; + } + + public void setWidth(double width) { + this.width = width; + } + + public void setWrap(boolean isWrap) { + this.isWrap = isWrap; + } + + public String getSuffix() { + return suffix; + } + + public void setSuffix(String suffix) { + this.suffix = suffix; + } + + public boolean isStatistics() { + return isStatistics; + } + + public void setStatistics(boolean isStatistics) { + this.isStatistics = isStatistics; + } + + @Override + public int compareTo(ExcelExportEntity prev) { + return this.getOrderNum() - prev.getOrderNum(); + } + +} diff --git a/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/entity/params/ExcelImportEntity.java b/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/entity/params/ExcelImportEntity.java new file mode 100644 index 000000000..d419ba577 --- /dev/null +++ b/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/entity/params/ExcelImportEntity.java @@ -0,0 +1,45 @@ +package com.pig4cloud.pigx.common.poi.excel.entity.params; + +import lombok.Data; + +import java.util.List; + +/** + * excel 导入工具类,对cell类型做映射 + * @author: Luckly + * @date: 2019-05-20 + *

+ */ +@Data +public class ExcelImportEntity extends ExcelBaseEntity { + /** + * 对应 Collection NAME + */ + private String collectionName; + /** + * 保存图片的地址 + */ + private String saveUrl; + /** + * 保存图片的类型,1是文件,2是数据库 + */ + private int saveType; + /** + * 对应exportType + */ + private String classType; + /** + * 校驗參數 + */ + private ExcelVerifyEntity verify; + /** + * 后缀 + */ + private String suffix; + /** + * list + */ + private List list; + + +} diff --git a/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/entity/params/ExcelTemplateParams.java b/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/entity/params/ExcelTemplateParams.java new file mode 100644 index 000000000..f163fab08 --- /dev/null +++ b/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/entity/params/ExcelTemplateParams.java @@ -0,0 +1,66 @@ +package com.pig4cloud.pigx.common.poi.excel.entity.params; + +import java.io.Serializable; + +import org.apache.poi.ss.usermodel.CellStyle; + +/** + * 模板便利是的参数 + * @author: Luckly + * @date: 2019-05-20 + *

+ */ +public class ExcelTemplateParams implements Serializable { + + /** + * + */ + private static final long serialVersionUID = 1L; + /** + * key + */ + private String name; + /** + * 模板的cellStyle + */ + private CellStyle cellStyle; + /** + * 行高 + */ + private short height; + + public ExcelTemplateParams() { + + } + + public ExcelTemplateParams(String name, CellStyle cellStyle, short height) { + this.name = name; + this.cellStyle = cellStyle; + this.height = height; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public CellStyle getCellStyle() { + return cellStyle; + } + + public void setCellStyle(CellStyle cellStyle) { + this.cellStyle = cellStyle; + } + + public short getHeight() { + return height; + } + + public void setHeight(short height) { + this.height = height; + } + +} diff --git a/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/entity/params/ExcelVerifyEntity.java b/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/entity/params/ExcelVerifyEntity.java new file mode 100644 index 000000000..91b955a6a --- /dev/null +++ b/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/entity/params/ExcelVerifyEntity.java @@ -0,0 +1,75 @@ +package com.pig4cloud.pigx.common.poi.excel.entity.params; + +import lombok.Data; + +/** + * Excel 校验对象 + * @author: Luckly + * @date: 2019-05-20 + *

+ */ +@Data +public class ExcelVerifyEntity { + + /** + * 接口校验 + * + * @return + */ + private boolean interHandler; + + /** + * 不允许空 + * + * @return + */ + private boolean notNull; + + /** + * 是13位移动电话 + * + * @return + */ + private boolean isMobile; + /** + * 是座机号码 + * + * @return + */ + private boolean isTel; + + /** + * 是电子邮件 + * + * @return + */ + private boolean isEmail; + + /** + * 最小长度 + * + * @return + */ + private int minLength; + + /** + * 最大长度 + * + * @return + */ + private int maxLength; + + /** + * 正在表达式 + * + * @return + */ + private String regex; + /** + * 正在表达式,错误提示信息 + * + * @return + */ + private String regexTip; + +} diff --git a/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/entity/params/MergeEntity.java b/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/entity/params/MergeEntity.java new file mode 100644 index 000000000..54d0901a9 --- /dev/null +++ b/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/entity/params/MergeEntity.java @@ -0,0 +1,70 @@ +package com.pig4cloud.pigx.common.poi.excel.entity.params; + +import java.util.List; + +/** + * 合并单元格使用对象 + * @author: Luckly + * @date: 2019-05-20 + *

+ */ +public class MergeEntity { + /** + * 合并开始行 + */ + private int startRow; + /** + * 合并结束行 + */ + private int endRow; + /** + * 文字 + */ + private String text; + /** + * 依赖关系文本 + */ + private List relyList; + + public MergeEntity() { + + } + + public MergeEntity(String text, int startRow, int endRow) { + this.text = text; + this.endRow = endRow; + this.startRow = startRow; + } + + public int getEndRow() { + return endRow; + } + + public List getRelyList() { + return relyList; + } + + public int getStartRow() { + return startRow; + } + + public String getText() { + return text; + } + + public void setEndRow(int endRow) { + this.endRow = endRow; + } + + public void setRelyList(List relyList) { + this.relyList = relyList; + } + + public void setStartRow(int startRow) { + this.startRow = startRow; + } + + public void setText(String text) { + this.text = text; + } +} diff --git a/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/entity/result/ExcelImportResult.java b/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/entity/result/ExcelImportResult.java new file mode 100644 index 000000000..ca7ff4465 --- /dev/null +++ b/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/entity/result/ExcelImportResult.java @@ -0,0 +1,64 @@ +package com.pig4cloud.pigx.common.poi.excel.entity.result; + +import java.util.List; + +import org.apache.poi.ss.usermodel.Workbook; + +/** + * 导入返回类 + * @author: Luckly + * @date: 2019-05-20 + *

+ */ +public class ExcelImportResult { + + /** + * 结果集 + */ + private List list; + + /** + * 是否存在校验失败 + */ + private boolean verfiyFail; + + /** + * 数据源 + */ + private Workbook workbook; + + public ExcelImportResult() { + + } + + public ExcelImportResult(List list, boolean verfiyFail, Workbook workbook) { + this.list = list; + this.verfiyFail = verfiyFail; + this.workbook = workbook; + } + + public List getList() { + return list; + } + + public Workbook getWorkbook() { + return workbook; + } + + public boolean isVerfiyFail() { + return verfiyFail; + } + + public void setList(List list) { + this.list = list; + } + + public void setVerfiyFail(boolean verfiyFail) { + this.verfiyFail = verfiyFail; + } + + public void setWorkbook(Workbook workbook) { + this.workbook = workbook; + } + +} diff --git a/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/entity/result/ExcelVerifyHanlderResult.java b/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/entity/result/ExcelVerifyHanlderResult.java new file mode 100644 index 000000000..8d5bccd6f --- /dev/null +++ b/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/entity/result/ExcelVerifyHanlderResult.java @@ -0,0 +1,48 @@ +package com.pig4cloud.pigx.common.poi.excel.entity.result; + +/** + * Excel导入处理返回结果 + * @author: Luckly + * @date: 2019-05-20 + *

+ */ +public class ExcelVerifyHanlderResult { + /** + * 是否正确 + */ + private boolean success; + /** + * 错误信息 + */ + private String msg; + + public ExcelVerifyHanlderResult() { + + } + + public ExcelVerifyHanlderResult(boolean success) { + this.success = success; + } + + public ExcelVerifyHanlderResult(boolean success, String msg) { + this.success = success; + this.msg = msg; + } + + public String getMsg() { + return msg; + } + + public boolean isSuccess() { + return success; + } + + public void setMsg(String msg) { + this.msg = msg; + } + + public void setSuccess(boolean success) { + this.success = success; + } + +} diff --git a/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/entity/sax/SaxReadCellEntity.java b/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/entity/sax/SaxReadCellEntity.java new file mode 100644 index 000000000..980db74a1 --- /dev/null +++ b/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/entity/sax/SaxReadCellEntity.java @@ -0,0 +1,47 @@ +package com.pig4cloud.pigx.common.poi.excel.entity.sax; + +import com.pig4cloud.pigx.common.poi.excel.entity.enmus.CellValueType; + +/** + * Cell 对象 + * @author: Luckly + * @date: 2019-05-20 + *

+ */ +public class SaxReadCellEntity { + /** + * 值类型 + */ + private CellValueType cellType; + /** + * 值 + */ + private Object value; + + public SaxReadCellEntity(CellValueType cellType, Object value) { + this.cellType = cellType; + this.value = value; + } + + public CellValueType getCellType() { + return cellType; + } + + public void setCellType(CellValueType cellType) { + this.cellType = cellType; + } + + public Object getValue() { + return value; + } + + public void setValue(Object value) { + this.value = value; + } + + @Override + public String toString() { + return "[type=" + cellType.toString() + ",value=" + value + "]"; + } + +} diff --git a/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/entity/vo/PoiBaseConstants.java b/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/entity/vo/PoiBaseConstants.java new file mode 100644 index 000000000..d7b61443f --- /dev/null +++ b/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/entity/vo/PoiBaseConstants.java @@ -0,0 +1,31 @@ +package com.pig4cloud.pigx.common.poi.excel.entity.vo; + +/** + * 基础常量 + * @author: Luckly + * @date: 2019-05-20 + *

+ */ +public interface PoiBaseConstants { + /** + * 字段属性对应方法 + */ + String GET = "get"; + /** + * 字段属性对应方法 + */ + String SET = "set"; + /** + * 字段属性对应方法 + */ + String IS = "is"; + /** + * 是否增加属性列 + */ + String IS_ADD_INDEX = "isAddIndex"; + /** + * 字段属性对应convert方法 + */ + String CONVERT = "convert"; + +} diff --git a/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/export/ExcelExportServer.java b/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/export/ExcelExportServer.java new file mode 100644 index 000000000..8e68d5a7d --- /dev/null +++ b/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/export/ExcelExportServer.java @@ -0,0 +1,285 @@ +package com.pig4cloud.pigx.common.poi.excel.export; + +import com.pig4cloud.pigx.common.poi.excel.annotation.ExcelTarget; +import com.pig4cloud.pigx.common.poi.excel.entity.ExportParams; +import com.pig4cloud.pigx.common.poi.excel.entity.enmus.ExcelType; +import com.pig4cloud.pigx.common.poi.excel.entity.params.ExcelExportEntity; +import com.pig4cloud.pigx.common.poi.excel.entity.vo.PoiBaseConstants; +import com.pig4cloud.pigx.common.poi.excel.export.base.ExcelExportBase; +import com.pig4cloud.pigx.common.poi.excel.export.styler.IExcelExportStyler; +import com.pig4cloud.pigx.common.poi.exception.excel.ExcelExportException; +import com.pig4cloud.pigx.common.poi.exception.excel.enums.ExcelExportEnum; +import com.pig4cloud.pigx.common.poi.util.PoiPublicUtil; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.apache.poi.ss.usermodel.*; +import org.apache.poi.ss.util.CellRangeAddress; + +import java.lang.reflect.Field; +import java.util.*; + +/** + * @author: Luckly + * @date: 2019-05-20 + *

+ * Excel导出服务 + */ +@Slf4j +public class ExcelExportServer extends ExcelExportBase { + + // 最大行数,超过自动多Sheet + private int MAX_NUM = 60000; + + private int createHeaderAndTitle(ExportParams entity, Sheet sheet, Workbook workbook, List excelParams) { + int rows = 0, feildWidth = getFieldWidth(excelParams); + if (entity.getTitle() != null) { + rows += createHeaderRow(entity, sheet, workbook, feildWidth); + } + rows += createTitleRow(entity, sheet, workbook, rows, excelParams); + sheet.createFreezePane(0, rows, 0, rows); + return rows; + } + + /** + * 创建 表头改变 + * + * @param entity + * @param sheet + * @param workbook + * @param feildWidth + */ + public int createHeaderRow(ExportParams entity, Sheet sheet, Workbook workbook, int feildWidth) { + Row row = sheet.createRow(0); + row.setHeight(entity.getTitleHeight()); + createStringCell(row, 0, entity.getTitle(), getExcelExportStyler().getHeaderStyle(entity.getHeaderColor()), null); + for (int i = 1; i <= feildWidth; i++) { + createStringCell(row, i, "", getExcelExportStyler().getHeaderStyle(entity.getHeaderColor()), null); + } + sheet.addMergedRegion(new CellRangeAddress(0, 0, 0, feildWidth)); + if (entity.getSecondTitle() != null) { + row = sheet.createRow(1); + row.setHeight(entity.getSecondTitleHeight()); + CellStyle style = workbook.createCellStyle(); + style.setAlignment(CellStyle.ALIGN_RIGHT); + createStringCell(row, 0, entity.getSecondTitle(), style, null); + for (int i = 1; i <= feildWidth; i++) { + createStringCell(row, i, "", getExcelExportStyler().getHeaderStyle(entity.getHeaderColor()), null); + } + sheet.addMergedRegion(new CellRangeAddress(1, 1, 0, feildWidth)); + return 2; + } + return 1; + } + + public void createSheet(Workbook workbook, ExportParams entity, Class pojoClass, Collection dataSet) { + if (log.isDebugEnabled()) { + log.debug("Excel export start ,class is {}", pojoClass); + log.debug("Excel version is {}", entity.getType().equals(ExcelType.HSSF) ? "03" : "07"); + } + if (workbook == null || entity == null || pojoClass == null || dataSet == null) { + throw new ExcelExportException(ExcelExportEnum.PARAMETER_ERROR); + } + super.type = entity.getType(); + if (type.equals(ExcelType.XSSF)) { + MAX_NUM = 1000000; + } + Sheet sheet = null; + try { + sheet = workbook.createSheet(entity.getSheetName()); + } catch (Exception e) { + // 重复遍历,出现了重名现象,创建非指定的名称Sheet + sheet = workbook.createSheet(); + } + try { + dataHanlder = entity.getDataHanlder(); + if (dataHanlder != null) { + needHanlderList = Arrays.asList(dataHanlder.getNeedHandlerFields()); + } + // 创建表格样式 TODO 出错 + setExcelExportStyler((IExcelExportStyler) entity.getStyle().getConstructor(Workbook.class).newInstance(workbook)); + Drawing patriarch = sheet.createDrawingPatriarch(); + List excelParams = new ArrayList(); + if (entity.isAddIndex()) { + excelParams.add(indexExcelEntity(entity)); + } + // 得到所有字段 + Field fileds[] = PoiPublicUtil.getClassFields(pojoClass); + ExcelTarget etarget = pojoClass.getAnnotation(ExcelTarget.class); + String targetId = etarget == null ? null : etarget.value(); + getAllExcelField(entity.getExclusions(), targetId, fileds, excelParams, pojoClass, null); + sortAllParams(excelParams); + int index = entity.isCreateHeadRows() ? createHeaderAndTitle(entity, sheet, workbook, excelParams) : 0; + int titleHeight = index; + setCellWith(excelParams, sheet); + short rowHeight = getRowHeight(excelParams); + setCurrentIndex(1); + Iterator its = dataSet.iterator(); + List tempList = new ArrayList(); + while (its.hasNext()) { + Object t = its.next(); + index += createCells(patriarch, index, t, excelParams, sheet, workbook, rowHeight); + tempList.add(t); + if (index >= MAX_NUM) + break; + } + mergeCells(sheet, excelParams, titleHeight); + + if (entity.getFreezeCol() != 0) { + sheet.createFreezePane(entity.getFreezeCol(), 0, entity.getFreezeCol(), 0); + } + + its = dataSet.iterator(); + for (int i = 0, le = tempList.size(); i < le; i++) { + its.next(); + its.remove(); + } + // 创建合计信息 + addStatisticsRow(getExcelExportStyler().getStyles(true, null), sheet); + + // 发现还有剩余list 继续循环创建Sheet + if (dataSet.size() > 0) { + createSheet(workbook, entity, pojoClass, dataSet); + } + + } catch (Exception e) { + log.error(e.getMessage(), e); + log.error(e.getMessage(), e); + throw new ExcelExportException(ExcelExportEnum.EXPORT_ERROR, e.getCause()); + } + } + + public void createSheetForMap(Workbook workbook, ExportParams entity, List entityList, Collection> dataSet) { + if (log.isDebugEnabled()) { + log.debug("Excel version is {}", entity.getType().equals(ExcelType.HSSF) ? "03" : "07"); + } + if (workbook == null || entity == null || entityList == null || dataSet == null) { + throw new ExcelExportException(ExcelExportEnum.PARAMETER_ERROR); + } + super.type = entity.getType(); + if (type.equals(ExcelType.XSSF)) { + MAX_NUM = 1000000; + } + Sheet sheet = null; + try { + sheet = workbook.createSheet(entity.getSheetName()); + } catch (Exception e) { + // 重复遍历,出现了重名现象,创建非指定的名称Sheet + sheet = workbook.createSheet(); + } + try { + dataHanlder = entity.getDataHanlder(); + if (dataHanlder != null) { + needHanlderList = Arrays.asList(dataHanlder.getNeedHandlerFields()); + } + // 创建表格样式 + setExcelExportStyler((IExcelExportStyler) entity.getStyle().getConstructor(Workbook.class).newInstance(workbook)); + Drawing patriarch = sheet.createDrawingPatriarch(); + List excelParams = new ArrayList(); + if (entity.isAddIndex()) { + excelParams.add(indexExcelEntity(entity)); + } + excelParams.addAll(entityList); + sortAllParams(excelParams); + int index = entity.isCreateHeadRows() ? createHeaderAndTitle(entity, sheet, workbook, excelParams) : 0; + int titleHeight = index; + setCellWith(excelParams, sheet); + short rowHeight = getRowHeight(excelParams); + setCurrentIndex(1); + Iterator its = dataSet.iterator(); + List tempList = new ArrayList(); + while (its.hasNext()) { + Object t = its.next(); + index += createCells(patriarch, index, t, excelParams, sheet, workbook, rowHeight); + tempList.add(t); + if (index >= MAX_NUM) + break; + } + if (entity.getFreezeCol() != 0) { + sheet.createFreezePane(entity.getFreezeCol(), 0, entity.getFreezeCol(), 0); + } + + mergeCells(sheet, excelParams, titleHeight); + + its = dataSet.iterator(); + for (int i = 0, le = tempList.size(); i < le; i++) { + its.next(); + its.remove(); + } + // 发现还有剩余list 继续循环创建Sheet + if (dataSet.size() > 0) { + createSheetForMap(workbook, entity, entityList, dataSet); + } + + } catch (Exception e) { + log.error(e.getMessage(), e); + throw new ExcelExportException(ExcelExportEnum.EXPORT_ERROR, e.getCause()); + } + } + + /** + * 创建表头 + * + * @param title + * @param index + */ + private int createTitleRow(ExportParams title, Sheet sheet, Workbook workbook, int index, List excelParams) { + Row row = sheet.createRow(index); + int rows = getRowNums(excelParams); + row.setHeight((short) 450); + Row listRow = null; + if (rows == 2) { + listRow = sheet.createRow(index + 1); + listRow.setHeight((short) 450); + } + int cellIndex = 0; + CellStyle titleStyle = getExcelExportStyler().getTitleStyle(title.getColor()); + for (int i = 0, exportFieldTitleSize = excelParams.size(); i < exportFieldTitleSize; i++) { + ExcelExportEntity entity = excelParams.get(i); + if (StringUtils.isNotBlank(entity.getName())) { + createStringCell(row, cellIndex, entity.getName(), titleStyle, entity); + } + if (entity.getList() != null) { + List sTitel = entity.getList(); + if (StringUtils.isNotBlank(entity.getName())) { + sheet.addMergedRegion(new CellRangeAddress(index, index, cellIndex, cellIndex + sTitel.size() - 1)); + } + for (int j = 0, size = sTitel.size(); j < size; j++) { + createStringCell(rows == 2 ? listRow : row, cellIndex, sTitel.get(j).getName(), titleStyle, entity); + cellIndex++; + } + cellIndex--; + } else if (rows == 2) { + createStringCell(listRow, cellIndex, "", titleStyle, entity); + sheet.addMergedRegion(new CellRangeAddress(index, index + 1, cellIndex, cellIndex)); + } + cellIndex++; + } + return rows; + + } + + /** + * 判断表头是只有一行还是两行 + * + * @param excelParams + * @return + */ + private int getRowNums(List excelParams) { + for (int i = 0; i < excelParams.size(); i++) { + if (excelParams.get(i).getList() != null && StringUtils.isNotBlank(excelParams.get(i).getName())) { + return 2; + } + } + return 1; + } + + private ExcelExportEntity indexExcelEntity(ExportParams entity) { + ExcelExportEntity exportEntity = new ExcelExportEntity(); + exportEntity.setOrderNum(0); + exportEntity.setName(entity.getIndexName()); + exportEntity.setWidth(10); + exportEntity.setFormat(PoiBaseConstants.IS_ADD_INDEX); + return exportEntity; + } + +} diff --git a/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/export/base/ExcelExportBase.java b/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/export/base/ExcelExportBase.java new file mode 100644 index 000000000..cd713a238 --- /dev/null +++ b/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/export/base/ExcelExportBase.java @@ -0,0 +1,386 @@ +package com.pig4cloud.pigx.common.poi.excel.export.base; + +import com.pig4cloud.pigx.common.poi.excel.entity.enmus.ExcelType; +import com.pig4cloud.pigx.common.poi.excel.entity.params.ExcelExportEntity; +import com.pig4cloud.pigx.common.poi.excel.entity.vo.PoiBaseConstants; +import com.pig4cloud.pigx.common.poi.excel.export.styler.IExcelExportStyler; +import com.pig4cloud.pigx.common.poi.util.PoiMergeCellUtil; +import com.pig4cloud.pigx.common.poi.util.PoiPublicUtil; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.apache.poi.hssf.usermodel.HSSFClientAnchor; +import org.apache.poi.hssf.usermodel.HSSFRichTextString; +import org.apache.poi.ss.usermodel.*; +import org.apache.poi.ss.util.CellRangeAddress; +import org.apache.poi.xssf.usermodel.XSSFClientAnchor; +import org.apache.poi.xssf.usermodel.XSSFRichTextString; + +import javax.imageio.ImageIO; +import java.awt.image.BufferedImage; +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.IOException; +import java.text.DecimalFormat; +import java.util.*; + +/** + * @author: Luckly + * @date: 2019-05-20 + *

+ * 提供POI基础操作服务 + */ +@Slf4j +public abstract class ExcelExportBase extends ExportBase { + + private int currentIndex = 0; + + protected ExcelType type = ExcelType.HSSF; + + private Map statistics = new HashMap(); + + private static final DecimalFormat DOUBLE_FORMAT = new DecimalFormat("######0.00"); + + private IExcelExportStyler excelExportStyler; + + /** + * 创建 最主要的 Cells + * + * @param patriarch + * @param index + * @param t + * @param excelParams + * @param sheet + * @param workbook + * @param rowHeight + * @return + * @throws Exception + */ + public int createCells(Drawing patriarch, int index, Object t, List excelParams, Sheet sheet, Workbook workbook, short rowHeight) throws Exception { + ExcelExportEntity entity; + Row row = sheet.createRow(index); + row.setHeight(rowHeight); + int maxHeight = 1, cellNum = 0; + int indexKey = createIndexCell(row, index, excelParams.get(0)); + cellNum += indexKey; + for (int k = indexKey, paramSize = excelParams.size(); k < paramSize; k++) { + entity = excelParams.get(k); + if (entity.getList() != null) { + Collection list = getListCellValue(entity, t); + int listC = 0; + for (Object obj : list) { + createListCells(patriarch, index + listC, cellNum, obj, entity.getList(), sheet, workbook); + listC++; + } + cellNum += entity.getList().size(); + if (list != null && list.size() > maxHeight) { + maxHeight = list.size(); + } + } else { + Object value = getCellValue(entity, t); + if (entity.getType() == 1) { + createStringCell(row, cellNum++, value == null ? "" : value.toString(), index % 2 == 0 ? getStyles(false, entity) : getStyles(true, entity), entity); + } else if (entity.getType() == 4){ + createNumericCell(row, cellNum++, value == null ? "" : value.toString(), index % 2 == 0 ? getStyles(false, entity) : getStyles(true, entity), entity); + } else { + createImageCell(patriarch, entity, row, cellNum++, value == null ? "" : value.toString(), t); + } + } + } + // 合并需要合并的单元格 + cellNum = 0; + for (int k = indexKey, paramSize = excelParams.size(); k < paramSize; k++) { + entity = excelParams.get(k); + if (entity.getList() != null) { + cellNum += entity.getList().size(); + } else if (entity.isNeedMerge()) { + for (int i = index + 1; i < index + maxHeight; i++) { + sheet.getRow(i).createCell(cellNum); + sheet.getRow(i).getCell(cellNum).setCellStyle(getStyles(false, entity)); + } + sheet.addMergedRegion(new CellRangeAddress(index, index + maxHeight - 1, cellNum, cellNum)); + cellNum++; + } + } + return maxHeight; + + } + + /** + * 图片类型的Cell + * + * @param patriarch + * @param entity + * @param row + * @param i + * @param imagePath + * @param obj + * @throws Exception + */ + public void createImageCell(Drawing patriarch, ExcelExportEntity entity, Row row, int i, String imagePath, Object obj) throws Exception { + row.setHeight((short) (50 * entity.getHeight())); + row.createCell(i); + ClientAnchor anchor; + if (type.equals(ExcelType.HSSF)) { + anchor = new HSSFClientAnchor(0, 0, 0, 0, (short) i, row.getRowNum(), (short) (i + 1), row.getRowNum() + 1); + } else { + anchor = new XSSFClientAnchor(0, 0, 0, 0, (short) i, row.getRowNum(), (short) (i + 1), row.getRowNum() + 1); + } + + if (StringUtils.isEmpty(imagePath)) { + return; + } + if (entity.getExportImageType() == 1) { + ByteArrayOutputStream byteArrayOut = new ByteArrayOutputStream(); + BufferedImage bufferImg; + try { + String path = PoiPublicUtil.getWebRootPath(imagePath); + log.debug("--- createImageCell getWebRootPath ----filePath--- "+ path); + path = path.replace("WEB-INF/classes/", ""); + path = path.replace("file:/", ""); + bufferImg = ImageIO.read(new File(path)); + ImageIO.write(bufferImg, imagePath.substring(imagePath.indexOf(".") + 1, imagePath.length()), byteArrayOut); + byte[] value = byteArrayOut.toByteArray(); + patriarch.createPicture(anchor, row.getSheet().getWorkbook().addPicture(value, getImageType(value))); + } catch (IOException e) { + log.error(e.getMessage(), e); + } + } else { + byte[] value = (byte[]) (entity.getMethods() != null ? getFieldBySomeMethod(entity.getMethods(), obj) : entity.getMethod().invoke(obj, new Object[] {})); + if (value != null) { + patriarch.createPicture(anchor, row.getSheet().getWorkbook().addPicture(value, getImageType(value))); + } + } + + } + + private int createIndexCell(Row row, int index, ExcelExportEntity excelExportEntity) { + if (excelExportEntity.getName().equals("序号") && excelExportEntity.getFormat().equals(PoiBaseConstants.IS_ADD_INDEX)) { + createStringCell(row, 0, currentIndex + "", index % 2 == 0 ? getStyles(false, null) : getStyles(true, null), null); + currentIndex = currentIndex + 1; + return 1; + } + return 0; + } + + /** + * 创建List之后的各个Cells + * + * @param patriarch + * @param index + * @param cellNum + * @param obj + * @param excelParams + * @param sheet + * @param workbook + * @throws Exception + */ + public void createListCells(Drawing patriarch, int index, int cellNum, Object obj, List excelParams, Sheet sheet, Workbook workbook) throws Exception { + ExcelExportEntity entity; + Row row; + if (sheet.getRow(index) == null) { + row = sheet.createRow(index); + row.setHeight(getRowHeight(excelParams)); + } else { + row = sheet.getRow(index); + } + for (int k = 0, paramSize = excelParams.size(); k < paramSize; k++) { + entity = excelParams.get(k); + Object value = getCellValue(entity, obj); + if (entity.getType() == 1) { + createStringCell(row, cellNum++, value == null ? "" : value.toString(), row.getRowNum() % 2 == 0 ? getStyles(false, entity) : getStyles(true, entity), entity); + } else if (entity.getType() == 4){ + createNumericCell(row, cellNum++, value == null ? "" : value.toString(), index % 2 == 0 ? getStyles(false, entity) : getStyles(true, entity), entity); + } else{ + createImageCell(patriarch, entity, row, cellNum++, value == null ? "" : value.toString(), obj); + } + } + } + + public void createNumericCell (Row row, int index, String text, CellStyle style, ExcelExportEntity entity) { + Cell cell = row.createCell(index); + if(StringUtils.isEmpty(text)){ + cell.setCellValue(""); + cell.setCellType(Cell.CELL_TYPE_BLANK); + }else{ + cell.setCellValue(Double.parseDouble(text)); + cell.setCellType(Cell.CELL_TYPE_NUMERIC); + } + if (style != null) { + cell.setCellStyle(style); + } + addStatisticsData(index, text, entity); + } + + /** + * 创建文本类型的Cell + * + * @param row + * @param index + * @param text + * @param style + * @param entity + */ + public void createStringCell(Row row, int index, String text, CellStyle style, ExcelExportEntity entity) { + Cell cell = row.createCell(index); + if (style != null && style.getDataFormat() > 0 && style.getDataFormat() < 12) { + cell.setCellValue(Double.parseDouble(text)); + cell.setCellType(Cell.CELL_TYPE_NUMERIC); + }else{ + RichTextString Rtext; + if (type.equals(ExcelType.HSSF)) { + Rtext = new HSSFRichTextString(text); + } else { + Rtext = new XSSFRichTextString(text); + } + cell.setCellValue(Rtext); + } + if (style != null) { + cell.setCellStyle(style); + } + addStatisticsData(index, text, entity); + } + + /** + * 创建统计行 + * + * @param styles + * @param sheet + */ + public void addStatisticsRow(CellStyle styles, Sheet sheet) { + if (statistics.size() > 0) { + Row row = sheet.createRow(sheet.getLastRowNum() + 1); + Set keys = statistics.keySet(); + createStringCell(row, 0, "合计", styles, null); + for (Integer key : keys) { + createStringCell(row, key, DOUBLE_FORMAT.format(statistics.get(key)), styles, null); + } + statistics.clear(); + } + + } + + /** + * 合计统计信息 + * + * @param index + * @param text + * @param entity + */ + private void addStatisticsData(Integer index, String text, ExcelExportEntity entity) { + if (entity != null && entity.isStatistics()) { + Double temp = 0D; + if (!statistics.containsKey(index)) { + statistics.put(index, temp); + } + try { + temp = Double.valueOf(text); + } catch (NumberFormatException e) { + } + statistics.put(index, statistics.get(index) + temp); + } + } + + /** + * 获取导出报表的字段总长度 + * + * @param excelParams + * @return + */ + public int getFieldWidth(List excelParams) { + int length = -1;// 从0开始计算单元格的 + for (ExcelExportEntity entity : excelParams) { + length += entity.getList() != null ? entity.getList().size() : 1; + } + return length; + } + + /** + * 获取图片类型,设置图片插入类型 + * + * @param value + * @return + */ + public int getImageType(byte[] value) { + String type = PoiPublicUtil.getFileExtendName(value); + if (type.equalsIgnoreCase("JPG")) { + return Workbook.PICTURE_TYPE_JPEG; + } else if (type.equalsIgnoreCase("PNG")) { + return Workbook.PICTURE_TYPE_PNG; + } + return Workbook.PICTURE_TYPE_JPEG; + } + + private Map getMergeDataMap(List excelParams) { + Map mergeMap = new HashMap(); + // 设置参数顺序,为之后合并单元格做准备 + int i = 0; + for (ExcelExportEntity entity : excelParams) { + if (entity.isMergeVertical()) { + mergeMap.put(i, entity.getMergeRely()); + } + if (entity.getList() != null) { + for (ExcelExportEntity inner : entity.getList()) { + if (inner.isMergeVertical()) { + mergeMap.put(i, inner.getMergeRely()); + } + i++; + } + } else { + i++; + } + } + return mergeMap; + } + + /** + * 获取样式 + * + * @param entity + * @param needOne + * @return + */ + public CellStyle getStyles(boolean needOne, ExcelExportEntity entity) { + return excelExportStyler.getStyles(needOne, entity); + } + + /** + * 合并单元格 + * + * @param sheet + * @param excelParams + * @param titleHeight + */ + public void mergeCells(Sheet sheet, List excelParams, int titleHeight) { + Map mergeMap = getMergeDataMap(excelParams); + PoiMergeCellUtil.mergeCells(sheet, mergeMap, titleHeight); + } + + public void setCellWith(List excelParams, Sheet sheet) { + int index = 0; + for (int i = 0; i < excelParams.size(); i++) { + if (excelParams.get(i).getList() != null) { + List list = excelParams.get(i).getList(); + for (int j = 0; j < list.size(); j++) { + sheet.setColumnWidth(index, (int) (256 * list.get(j).getWidth())); + index++; + } + } else { + sheet.setColumnWidth(index, (int) (256 * excelParams.get(i).getWidth())); + index++; + } + } + } + + public void setCurrentIndex(int currentIndex) { + this.currentIndex = currentIndex; + } + + public void setExcelExportStyler(IExcelExportStyler excelExportStyler) { + this.excelExportStyler = excelExportStyler; + } + + public IExcelExportStyler getExcelExportStyler() { + return excelExportStyler; + } + +} diff --git a/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/export/base/ExportBase.java b/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/export/base/ExportBase.java new file mode 100644 index 000000000..ade0a58f5 --- /dev/null +++ b/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/export/base/ExportBase.java @@ -0,0 +1,366 @@ +package com.pig4cloud.pigx.common.poi.excel.export.base; + +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.lang.reflect.ParameterizedType; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.Date; +import java.util.List; +import java.util.Map; + +import com.pig4cloud.pigx.common.core.util.ApplicationContextUtil; +import com.pig4cloud.pigx.common.dict.service.AutoPoiDictServiceI; +import org.apache.commons.lang3.StringUtils; +import com.pig4cloud.pigx.common.poi.excel.annotation.Excel; +import com.pig4cloud.pigx.common.poi.excel.annotation.ExcelCollection; +import com.pig4cloud.pigx.common.poi.excel.annotation.ExcelEntity; +import com.pig4cloud.pigx.common.poi.excel.entity.params.ExcelExportEntity; +import com.pig4cloud.pigx.common.poi.handler.inter.IExcelDataHandler; +import com.pig4cloud.pigx.common.poi.util.PoiPublicUtil; + +/** + * @author: Luckly + * @date: 2019-05-20 + *

+ * 导出基础处理,不设计POI,只设计对象,保证复用性 + */ +public class ExportBase { + + protected IExcelDataHandler dataHanlder; + + protected List needHanlderList; + + /** + * 创建导出实体对象 + * + * @param field + * @param targetId + * @param pojoClass + * @param getMethods + * @return + * @throws Exception + */ + private ExcelExportEntity createExcelExportEntity(Field field, String targetId, Class pojoClass, List getMethods) throws Exception { + Excel excel = field.getAnnotation(Excel.class); + ExcelExportEntity excelEntity = new ExcelExportEntity(); + excelEntity.setType(excel.type()); + getExcelField(targetId, field, excelEntity, excel, pojoClass); + if (getMethods != null) { + List newMethods = new ArrayList(); + newMethods.addAll(getMethods); + newMethods.add(excelEntity.getMethod()); + excelEntity.setMethods(newMethods); + } + return excelEntity; + } + + private Object formatValue(Object value, ExcelExportEntity entity) throws Exception { + Date temp = null; + if (value instanceof String) { + SimpleDateFormat format = new SimpleDateFormat(entity.getDatabaseFormat()); + temp = format.parse(value.toString()); + } else if (value instanceof Date) { + temp = (Date) value; + } + if (temp != null) { + SimpleDateFormat format = new SimpleDateFormat(entity.getFormat()); + value = format.format(temp); + } + return value; + } + + /** + * 获取需要导出的全部字段 + * + * @param exclusions + * @param targetId + * 目标ID + * @param fields + * @throws Exception + */ + public void getAllExcelField(String[] exclusions, String targetId, Field[] fields, List excelParams, Class pojoClass, List getMethods) throws Exception { + List exclusionsList = exclusions != null ? Arrays.asList(exclusions) : null; + ExcelExportEntity excelEntity; + // 遍历整个filed + for (int i = 0; i < fields.length; i++) { + Field field = fields[i]; + // 先判断是不是collection,在判断是不是java自带对象,之后就是我们自己的对象了 + if (PoiPublicUtil.isNotUserExcelUserThis(exclusionsList, field, targetId)) { + continue; + } + // 首先判断Excel 可能一下特殊数据用户回自定义处理 + if (field.getAnnotation(Excel.class) != null) { + excelParams.add(createExcelExportEntity(field, targetId, pojoClass, getMethods)); + } else if (PoiPublicUtil.isCollection(field.getType())) { + ExcelCollection excel = field.getAnnotation(ExcelCollection.class); + ParameterizedType pt = (ParameterizedType) field.getGenericType(); + Class clz = (Class) pt.getActualTypeArguments()[0]; + List list = new ArrayList(); + getAllExcelField(exclusions, StringUtils.isNotEmpty(excel.id()) ? excel.id() : targetId, PoiPublicUtil.getClassFields(clz), list, clz, null); + excelEntity = new ExcelExportEntity(); + excelEntity.setName(getExcelName(excel.name(), targetId)); + excelEntity.setOrderNum(getCellOrder(excel.orderNum(), targetId)); + excelEntity.setMethod(PoiPublicUtil.getMethod(field.getName(), pojoClass)); + excelEntity.setList(list); + excelParams.add(excelEntity); + } else { + List newMethods = new ArrayList(); + if (getMethods != null) { + newMethods.addAll(getMethods); + } + newMethods.add(PoiPublicUtil.getMethod(field.getName(), pojoClass)); + ExcelEntity excel = field.getAnnotation(ExcelEntity.class); + getAllExcelField(exclusions, StringUtils.isNotEmpty(excel.id()) ? excel.id() : targetId, PoiPublicUtil.getClassFields(field.getType()), excelParams, field.getType(), newMethods); + } + } + } + + /** + * 获取这个字段的顺序 + * + * @param orderNum + * @param targetId + * @return + */ + public int getCellOrder(String orderNum, String targetId) { + if (isInteger(orderNum) || targetId == null) { + return Integer.valueOf(orderNum); + } + String[] arr = orderNum.split(","); + String[] temp; + for (String str : arr) { + temp = str.split("_"); + if (targetId.equals(temp[1])) { + return Integer.valueOf(temp[0]); + } + } + return 0; + } + + /** + * 获取填如这个cell的值,提供一些附加功能 + * + * @param entity + * @param obj + * @return + * @throws Exception + */ + public Object getCellValue(ExcelExportEntity entity, Object obj) throws Exception { + Object value; + if (obj instanceof Map) { + value = ((Map) obj).get(entity.getKey()); + } else { + value = entity.getMethods() != null ? getFieldBySomeMethod(entity.getMethods(), obj) : entity.getMethod().invoke(obj, new Object[] {}); + } + if (StringUtils.isNotEmpty(entity.getFormat())) { + value = formatValue(value, entity); + } + if (entity.getReplace() != null && entity.getReplace().length > 0) { + if(value == null){ + //String.valueOf(value) 如果value为null 则返回"null" + value = ""; + } + if(entity.isMultiReplace()){ + value = multiReplaceValue(entity.getReplace(), String.valueOf(value)); + }else{ + value = replaceValue(entity.getReplace(), String.valueOf(value)); + } + } + if (needHanlderList != null && needHanlderList.contains(entity.getName())) { + value = dataHanlder.exportHandler(obj, entity.getName(), value); + } + if (StringUtils.isNotEmpty(entity.getSuffix()) && value != null) { + value = value + entity.getSuffix(); + } + return value == null ? "" : value.toString(); + } + + /** + * 获取集合的值 + * + * @param entity + * @param obj + * @return + * @throws Exception + */ + public Collection getListCellValue(ExcelExportEntity entity, Object obj) throws Exception { + Object value; + if (obj instanceof Map) { + value = ((Map) obj).get(entity.getKey()); + } else { + value = (Collection) entity.getMethod().invoke(obj, new Object[] {}); + } + return (Collection) value; + } + + /** + * 注解到导出对象的转换 + * + * @param targetId + * @param field + * @param excelEntity + * @param excel + * @param pojoClass + * @throws Exception + */ + private void getExcelField(String targetId, Field field, ExcelExportEntity excelEntity, Excel excel, Class pojoClass) throws Exception { + excelEntity.setName(getExcelName(excel.name(), targetId)); + excelEntity.setWidth(excel.width()); + excelEntity.setHeight(excel.height()); + excelEntity.setNeedMerge(excel.needMerge()); + excelEntity.setMergeVertical(excel.mergeVertical()); + excelEntity.setMergeRely(excel.mergeRely()); + excelEntity.setReplace(excel.replace()); + if(StringUtils.isNotEmpty(excel.dicCode())){ + AutoPoiDictServiceI bossDictService = null; + try { + bossDictService = ApplicationContextUtil.getContext().getBean(AutoPoiDictServiceI.class); + } catch (Exception e) { + } + if(bossDictService!=null){ + String[] dictReplace = bossDictService.queryDict(excel.dictTable(), excel.dicCode(), excel.dicText()); + if(excelEntity.getReplace()!=null && dictReplace!=null && dictReplace.length!=0){ + excelEntity.setReplace(dictReplace); + } + } + } + excelEntity.setOrderNum(getCellOrder(excel.orderNum(), targetId)); + excelEntity.setWrap(excel.isWrap()); + excelEntity.setExportImageType(excel.imageType()); + excelEntity.setSuffix(excel.suffix()); + excelEntity.setDatabaseFormat(excel.databaseFormat()); + excelEntity.setFormat(StringUtils.isNotEmpty(excel.exportFormat()) ? excel.exportFormat() : excel.format()); + excelEntity.setStatistics(excel.isStatistics()); + String fieldname = field.getName(); + excelEntity.setMethod(PoiPublicUtil.getMethod(fieldname, pojoClass,excel.exportConvert())); + excelEntity.setMultiReplace(excel.multiReplace()); + } + + /** + * 判断在这个单元格显示的名称 + * + * @param exportName + * @param targetId + * @return + */ + public String getExcelName(String exportName, String targetId) { + if (exportName.indexOf(",") < 0 || targetId==null) { + return exportName; + } + String[] arr = exportName.split(","); + for (String str : arr) { + if (str.indexOf(targetId) != -1) { + return str.split("_")[0]; + } + } + return null; + } + + /** + * 多个反射获取值 + * + * @param list + * @param t + * @return + * @throws Exception + */ + public Object getFieldBySomeMethod(List list, Object t) throws Exception { + for (Method m : list) { + if (t == null) { + t = ""; + break; + } + t = m.invoke(t, new Object[] {}); + } + return t; + } + + /** + * 根据注解获取行高 + * + * @param excelParams + * @return + */ + public short getRowHeight(List excelParams) { + double maxHeight = 0; + for (int i = 0; i < excelParams.size(); i++) { + maxHeight = maxHeight > excelParams.get(i).getHeight() ? maxHeight : excelParams.get(i).getHeight(); + if (excelParams.get(i).getList() != null) { + for (int j = 0; j < excelParams.get(i).getList().size(); j++) { + maxHeight = maxHeight > excelParams.get(i).getList().get(j).getHeight() ? maxHeight : excelParams.get(i).getList().get(j).getHeight(); + } + } + } + return (short) (maxHeight * 50); + } + + /** + * 判断字符串是否是整数 + */ + public boolean isInteger(String value) { + try { + Integer.parseInt(value); + return true; + } catch (NumberFormatException e) { + return false; + } + } + + private Object replaceValue(String[] replace, String value) { + String[] temp; + for (String str : replace) { + temp = str.split("_"); + if (value.equals(temp[1])) { + value = temp[0]; + break; + } + } + return value; + } + + /** + * 如果需要被替换的值是多选项,则每一项之间有逗号隔开,走以下方法 + */ + private Object multiReplaceValue(String[] replace, String value) { + if(value.indexOf(",")>0){ + String[] radioVals = value.split(","); + String[] temp; + String result = ""; + for(int i =0;i excelParams) { + Collections.sort(excelParams); + for (ExcelExportEntity entity : excelParams) { + if (entity.getList() != null) { + Collections.sort(entity.getList()); + } + } + } + +} diff --git a/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/export/styler/AbstractExcelExportStyler.java b/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/export/styler/AbstractExcelExportStyler.java new file mode 100644 index 000000000..25ab9ac0b --- /dev/null +++ b/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/export/styler/AbstractExcelExportStyler.java @@ -0,0 +1,56 @@ +package com.pig4cloud.pigx.common.poi.excel.export.styler; + +import org.apache.poi.ss.usermodel.BuiltinFormats; +import org.apache.poi.ss.usermodel.CellStyle; +import org.apache.poi.ss.usermodel.Workbook; +import com.pig4cloud.pigx.common.poi.excel.entity.params.ExcelExportEntity; + +/** + * @author: Luckly + * @date: 2019-05-20 + *

+ * 抽象接口提供两个公共方法 + */ +public abstract class AbstractExcelExportStyler implements IExcelExportStyler { + // 单行 + protected CellStyle stringNoneStyle; + protected CellStyle stringNoneWrapStyle; + // 间隔行 + protected CellStyle stringSeptailStyle; + protected CellStyle stringSeptailWrapStyle; + + protected Workbook workbook; + + protected static final short STRING_FORMAT = (short) BuiltinFormats.getBuiltinFormat("TEXT"); + + protected void createStyles(Workbook workbook) { + this.stringNoneStyle = stringNoneStyle(workbook, false); + this.stringNoneWrapStyle = stringNoneStyle(workbook, true); + this.stringSeptailStyle = stringSeptailStyle(workbook, false); + this.stringSeptailWrapStyle = stringSeptailStyle(workbook, true); + this.workbook = workbook; + } + + @Override + public CellStyle getStyles(boolean noneStyler, ExcelExportEntity entity) { + if (noneStyler && (entity == null || entity.isWrap())) { + return stringNoneWrapStyle; + } + if (noneStyler) { + return stringNoneStyle; + } + if (noneStyler == false && (entity == null || entity.isWrap())) { + return stringSeptailWrapStyle; + } + return stringSeptailStyle; + } + + public CellStyle stringNoneStyle(Workbook workbook, boolean isWarp) { + return null; + } + + public CellStyle stringSeptailStyle(Workbook workbook, boolean isWarp) { + return null; + } + +} diff --git a/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/export/styler/ExcelExportStylerBorderImpl.java b/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/export/styler/ExcelExportStylerBorderImpl.java new file mode 100644 index 000000000..05d9dfa8d --- /dev/null +++ b/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/export/styler/ExcelExportStylerBorderImpl.java @@ -0,0 +1,68 @@ +package com.pig4cloud.pigx.common.poi.excel.export.styler; + +import org.apache.poi.ss.usermodel.CellStyle; +import org.apache.poi.ss.usermodel.Font; +import org.apache.poi.ss.usermodel.Workbook; + +/** + * @author: Luckly + * @date: 2019-05-20 + *

+ * 带有边框的Excel样式 + */ +public class ExcelExportStylerBorderImpl extends AbstractExcelExportStyler implements IExcelExportStyler { + + public ExcelExportStylerBorderImpl(Workbook workbook) { + super.createStyles(workbook); + } + + @Override + public CellStyle getHeaderStyle(short color) { + CellStyle titleStyle = workbook.createCellStyle(); + Font font = workbook.createFont(); + font.setFontHeightInPoints((short) 12); + titleStyle.setFont(font); + titleStyle.setBorderLeft((short) 1); // 左边框 + titleStyle.setBorderRight((short) 1); // 右边框 + titleStyle.setBorderBottom((short) 1); + titleStyle.setBorderTop((short) 1); + titleStyle.setAlignment(CellStyle.ALIGN_CENTER); + titleStyle.setVerticalAlignment(CellStyle.VERTICAL_CENTER); + return titleStyle; + } + + @Override + public CellStyle stringNoneStyle(Workbook workbook, boolean isWarp) { + CellStyle style = workbook.createCellStyle(); + style.setBorderLeft((short) 1); // 左边框 + style.setBorderRight((short) 1); // 右边框 + style.setBorderBottom((short) 1); + style.setBorderTop((short) 1); + style.setAlignment(CellStyle.ALIGN_CENTER); + style.setVerticalAlignment(CellStyle.VERTICAL_CENTER); + style.setDataFormat(STRING_FORMAT); + if (isWarp) { + style.setWrapText(true); + } + return style; + } + + @Override + public CellStyle getTitleStyle(short color) { + CellStyle titleStyle = workbook.createCellStyle(); + titleStyle.setBorderLeft((short) 1); // 左边框 + titleStyle.setBorderRight((short) 1); // 右边框 + titleStyle.setBorderBottom((short) 1); + titleStyle.setBorderTop((short) 1); + titleStyle.setAlignment(CellStyle.ALIGN_CENTER); + titleStyle.setVerticalAlignment(CellStyle.VERTICAL_CENTER); + titleStyle.setWrapText(true); + return titleStyle; + } + + @Override + public CellStyle stringSeptailStyle(Workbook workbook, boolean isWarp) { + return isWarp ? stringNoneWrapStyle : stringNoneStyle; + } + +} diff --git a/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/export/styler/ExcelExportStylerColorImpl.java b/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/export/styler/ExcelExportStylerColorImpl.java new file mode 100644 index 000000000..072f00acf --- /dev/null +++ b/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/export/styler/ExcelExportStylerColorImpl.java @@ -0,0 +1,76 @@ +package com.pig4cloud.pigx.common.poi.excel.export.styler; + +import org.apache.poi.ss.usermodel.CellStyle; +import org.apache.poi.ss.usermodel.Font; +import org.apache.poi.ss.usermodel.Workbook; + +/** + * @author: Luckly + * @date: 2019-05-20 + *

+ * 带有样式的导出服务 + */ +public class ExcelExportStylerColorImpl extends AbstractExcelExportStyler implements IExcelExportStyler { + + public ExcelExportStylerColorImpl(Workbook workbook) { + super.createStyles(workbook); + } + + @Override + public CellStyle getHeaderStyle(short headerColor) { + CellStyle titleStyle = workbook.createCellStyle(); + Font font = workbook.createFont(); + font.setFontHeightInPoints((short) 24); + titleStyle.setFont(font); + titleStyle.setFillForegroundColor(headerColor); + titleStyle.setAlignment(CellStyle.ALIGN_CENTER); + titleStyle.setVerticalAlignment(CellStyle.VERTICAL_CENTER); + return titleStyle; + } + + @Override + public CellStyle stringNoneStyle(Workbook workbook, boolean isWarp) { + CellStyle style = workbook.createCellStyle(); + style.setBorderLeft((short) 1); // 左边框 + style.setBorderRight((short) 1); // 右边框 + style.setBorderBottom((short) 1); + style.setBorderTop((short) 1); + style.setAlignment(CellStyle.ALIGN_CENTER); + style.setVerticalAlignment(CellStyle.VERTICAL_CENTER); + style.setDataFormat(STRING_FORMAT); + if (isWarp) { + style.setWrapText(true); + } + return style; + } + + @Override + public CellStyle getTitleStyle(short color) { + CellStyle titleStyle = workbook.createCellStyle(); + titleStyle.setFillForegroundColor(color); // 填充的背景颜色 + titleStyle.setAlignment(CellStyle.ALIGN_CENTER); + titleStyle.setVerticalAlignment(CellStyle.VERTICAL_CENTER); + titleStyle.setFillPattern(CellStyle.SOLID_FOREGROUND); // 填充图案 + titleStyle.setWrapText(true); + return titleStyle; + } + + @Override + public CellStyle stringSeptailStyle(Workbook workbook, boolean isWarp) { + CellStyle style = workbook.createCellStyle(); + style.setBorderLeft((short) 1); // 左边框 + style.setBorderRight((short) 1); // 右边框 + style.setBorderBottom((short) 1); + style.setBorderTop((short) 1); + style.setFillForegroundColor((short) 41); // 填充的背景颜色 + style.setFillPattern(CellStyle.SOLID_FOREGROUND); // 填充图案 + style.setAlignment(CellStyle.ALIGN_CENTER); + style.setVerticalAlignment(CellStyle.VERTICAL_CENTER); + style.setDataFormat(STRING_FORMAT); + if (isWarp) { + style.setWrapText(true); + } + return style; + } + +} diff --git a/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/export/styler/ExcelExportStylerDefaultImpl.java b/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/export/styler/ExcelExportStylerDefaultImpl.java new file mode 100644 index 000000000..0720dc5ea --- /dev/null +++ b/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/export/styler/ExcelExportStylerDefaultImpl.java @@ -0,0 +1,63 @@ +package com.pig4cloud.pigx.common.poi.excel.export.styler; + +import org.apache.poi.ss.usermodel.CellStyle; +import org.apache.poi.ss.usermodel.Font; +import org.apache.poi.ss.usermodel.Workbook; + +/** + * @author: Luckly + * @date: 2019-05-20 + *

+ * 样式的默认实现 + */ +public class ExcelExportStylerDefaultImpl extends AbstractExcelExportStyler implements IExcelExportStyler { + + public ExcelExportStylerDefaultImpl(Workbook workbook) { + super.createStyles(workbook); + } + + @Override + public CellStyle getTitleStyle(short color) { + CellStyle titleStyle = workbook.createCellStyle(); + titleStyle.setAlignment(CellStyle.ALIGN_CENTER); + titleStyle.setVerticalAlignment(CellStyle.VERTICAL_CENTER); + titleStyle.setWrapText(true); + return titleStyle; + } + + @Override + public CellStyle stringSeptailStyle(Workbook workbook, boolean isWarp) { + CellStyle style = workbook.createCellStyle(); + style.setAlignment(CellStyle.ALIGN_CENTER); + style.setVerticalAlignment(CellStyle.VERTICAL_CENTER); + style.setDataFormat(STRING_FORMAT); + if (isWarp) { + style.setWrapText(true); + } + return style; + } + + @Override + public CellStyle getHeaderStyle(short color) { + CellStyle titleStyle = workbook.createCellStyle(); + Font font = workbook.createFont(); + font.setFontHeightInPoints((short) 12); + titleStyle.setFont(font); + titleStyle.setAlignment(CellStyle.ALIGN_CENTER); + titleStyle.setVerticalAlignment(CellStyle.VERTICAL_CENTER); + return titleStyle; + } + + @Override + public CellStyle stringNoneStyle(Workbook workbook, boolean isWarp) { + CellStyle style = workbook.createCellStyle(); + style.setAlignment(CellStyle.ALIGN_CENTER); + style.setVerticalAlignment(CellStyle.VERTICAL_CENTER); + style.setDataFormat(STRING_FORMAT); + if (isWarp) { + style.setWrapText(true); + } + return style; + } + +} diff --git a/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/export/styler/IExcelExportStyler.java b/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/export/styler/IExcelExportStyler.java new file mode 100644 index 000000000..9a0bb7ef8 --- /dev/null +++ b/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/export/styler/IExcelExportStyler.java @@ -0,0 +1,39 @@ +package com.pig4cloud.pigx.common.poi.excel.export.styler; + +import org.apache.poi.ss.usermodel.CellStyle; +import com.pig4cloud.pigx.common.poi.excel.entity.params.ExcelExportEntity; + +/** + * @author: Luckly + * @date: 2019-05-20 + *

+ * Excel导出样式接口 + */ +public interface IExcelExportStyler { + + /** + * 列表头样式 + * + * @param headerColor + * @return + */ + public CellStyle getHeaderStyle(short headerColor); + + /** + * 标题样式 + * + * @param color + * @return + */ + public CellStyle getTitleStyle(short color); + + /** + * 获取样式方法 + * + * @param noneStyler + * @param entity + * @return + */ + public CellStyle getStyles(boolean noneStyler, ExcelExportEntity entity); + +} diff --git a/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/export/template/ExcelExportOfTemplateUtil.java b/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/export/template/ExcelExportOfTemplateUtil.java new file mode 100644 index 000000000..6bcb5208f --- /dev/null +++ b/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/export/template/ExcelExportOfTemplateUtil.java @@ -0,0 +1,444 @@ +package com.pig4cloud.pigx.common.poi.excel.export.template; + +import com.pig4cloud.pigx.common.poi.cache.ExcelCache; +import com.pig4cloud.pigx.common.poi.excel.annotation.ExcelTarget; +import com.pig4cloud.pigx.common.poi.excel.entity.TemplateExportParams; +import com.pig4cloud.pigx.common.poi.excel.entity.enmus.ExcelType; +import com.pig4cloud.pigx.common.poi.excel.entity.params.ExcelExportEntity; +import com.pig4cloud.pigx.common.poi.excel.entity.params.ExcelTemplateParams; +import com.pig4cloud.pigx.common.poi.excel.export.base.ExcelExportBase; +import com.pig4cloud.pigx.common.poi.excel.export.styler.IExcelExportStyler; +import com.pig4cloud.pigx.common.poi.exception.excel.ExcelExportException; +import com.pig4cloud.pigx.common.poi.exception.excel.enums.ExcelExportEnum; +import com.pig4cloud.pigx.common.poi.util.PoiPublicUtil; +import com.pig4cloud.pigx.common.poi.util.PoiSheetUtility; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.apache.poi.ss.usermodel.*; +import org.apache.poi.xssf.usermodel.XSSFWorkbook; + +import java.lang.reflect.Field; +import java.util.*; + +import static com.pig4cloud.pigx.common.poi.util.PoiElUtil.*; + +/** + * @author: Luckly + * @date: 2019-05-20 + *

+ * Excel 导出根据模板导出 + */ +@Slf4j +public final class ExcelExportOfTemplateUtil extends ExcelExportBase { + + /** + * 缓存TEMP 的for each创建的cell ,跳过这个cell的模板语法查找,提高效率 + */ + private Set tempCreateCellSet = new HashSet(); + /** + * 模板参数,全局都用到 + */ + private TemplateExportParams teplateParams; + + /** + * 往Sheet 填充正常数据,根据表头信息 使用导入的部分逻辑,坐对象映射 + * @param pojoClass + * @param dataSet + * @param sheet + * @param workbook + * @throws Exception + */ + private void addDataToSheet(Class pojoClass, Collection dataSet, Sheet sheet, Workbook workbook) throws Exception { + + if (workbook instanceof XSSFWorkbook) { + super.type = ExcelType.XSSF; + } + // 获取表头数据 + Map titlemap = getTitleMap(sheet); + Drawing patriarch = sheet.createDrawingPatriarch(); + // 得到所有字段 + Field[] fileds = PoiPublicUtil.getClassFields(pojoClass); + ExcelTarget etarget = pojoClass.getAnnotation(ExcelTarget.class); + String targetId = null; + if (etarget != null) { + targetId = etarget.value(); + } + // 获取实体对象的导出数据 + List excelParams = new ArrayList(); + getAllExcelField(null, targetId, fileds, excelParams, pojoClass, null); + // 根据表头进行筛选排序 + sortAndFilterExportField(excelParams, titlemap); + short rowHeight = getRowHeight(excelParams); + int index = teplateParams.getHeadingRows() + teplateParams.getHeadingStartRow(), titleHeight = index; + // 下移数据,模拟插入 + sheet.shiftRows(teplateParams.getHeadingRows() + teplateParams.getHeadingStartRow(), sheet.getLastRowNum(), getShiftRows(dataSet, excelParams), true, true); + if (excelParams.size() == 0) { + return; + } + Iterator its = dataSet.iterator(); + while (its.hasNext()) { + Object t = its.next(); + index += createCells(patriarch, index, t, excelParams, sheet, workbook, rowHeight); + } + // 合并同类项 + mergeCells(sheet, excelParams, titleHeight); + } + + /** + * 下移数据 + * + * @param dataSet + * @param excelParams + * @return + * @throws Exception + */ + private int getShiftRows(Collection dataSet, List excelParams) throws Exception { + int size = 0; + Iterator its = dataSet.iterator(); + while (its.hasNext()) { + Object t = its.next(); + size += getOneObjectSize(t, excelParams); + } + return size; + } + + /** + * 获取单个对象的高度,主要是处理一堆多的情况 + * + * @param t + * @param excelParams + * @return + * @throws Exception + */ + public int getOneObjectSize(Object t, List excelParams) throws Exception { + ExcelExportEntity entity; + int maxHeight = 1; + for (int k = 0, paramSize = excelParams.size(); k < paramSize; k++) { + entity = excelParams.get(k); + if (entity.getList() != null) { + Collection list = (Collection) entity.getMethod().invoke(t, new Object[] {}); + if (list != null && list.size() > maxHeight) { + maxHeight = list.size(); + } + } + } + return maxHeight; + + } + + public Workbook createExcleByTemplate(TemplateExportParams params, Class pojoClass, Collection dataSet, Map map) { + // step 1. 判断模板的地址 + if (params == null || map == null || StringUtils.isEmpty(params.getTemplateUrl())) { + throw new ExcelExportException(ExcelExportEnum.PARAMETER_ERROR); + } + Workbook wb = null; + // step 2. 判断模板的Excel类型,解析模板 + try { + this.teplateParams = params; + wb = getCloneWorkBook(); + // 创建表格样式 + setExcelExportStyler((IExcelExportStyler) teplateParams.getStyle().getConstructor(Workbook.class).newInstance(wb)); + // step 3. 解析模板 + for (int i = 0, le = params.isScanAllsheet() ? wb.getNumberOfSheets() : params.getSheetNum().length; i < le; i++) { + if (params.getSheetName() != null && params.getSheetName().length > i && StringUtils.isNotEmpty(params.getSheetName()[i])) { + wb.setSheetName(i, params.getSheetName()[i]); + } + tempCreateCellSet.clear(); + parseTemplate(wb.getSheetAt(i), map); + } + if (dataSet != null) { + // step 4. 正常的数据填充 + dataHanlder = params.getDataHanlder(); + if (dataHanlder != null) { + needHanlderList = Arrays.asList(dataHanlder.getNeedHandlerFields()); + } + addDataToSheet(pojoClass, dataSet, wb.getSheetAt(params.getDataSheetNum()), wb); + } + } catch (Exception e) { + log.error(e.getMessage(), e); + return null; + } + return wb; + } + + /** + * 克隆excel防止操作原对象,workbook无法克隆,只能对excel进行克隆 + * + * @return + * @throws Exception + */ + private Workbook getCloneWorkBook() throws Exception { + return ExcelCache.getWorkbook(teplateParams.getTemplateUrl(), teplateParams.getSheetNum(), teplateParams.isScanAllsheet()); + + } + + /** + * 获取表头数据,设置表头的序号 + * + * @param sheet + * @return + */ + private Map getTitleMap(Sheet sheet) { + Row row = null; + Iterator cellTitle; + Map titlemap = new HashMap(); + for (int j = 0; j < teplateParams.getHeadingRows(); j++) { + row = sheet.getRow(j + teplateParams.getHeadingStartRow()); + cellTitle = row.cellIterator(); + int i = row.getFirstCellNum(); + while (cellTitle.hasNext()) { + Cell cell = cellTitle.next(); + String value = cell.getStringCellValue(); + if (!StringUtils.isEmpty(value)) { + titlemap.put(value, i); + } + i = i + 1; + } + } + return titlemap; + + } + + private void parseTemplate(Sheet sheet, Map map) throws Exception { + deleteCell(sheet, map); + Row row = null; + int index = 0; + while (index <= sheet.getLastRowNum()) { + row = sheet.getRow(index++); + if (row == null) { + continue; + } + for (int i = row.getFirstCellNum(); i < row.getLastCellNum(); i++) { + if (row.getCell(i) != null && !tempCreateCellSet.contains(row.getRowNum() + "_" + row.getCell(i).getColumnIndex())) { + setValueForCellByMap(row.getCell(i), map); + } + } + } + } + + /** + * 先判断删除,省得影响效率 + * + * @param sheet + * @param map + * @throws Exception + */ + private void deleteCell(Sheet sheet, Map map) throws Exception { + Row row = null; + Cell cell = null; + int index = 0; + while (index <= sheet.getLastRowNum()) { + row = sheet.getRow(index++); + if (row == null) { + continue; + } + for (int i = row.getFirstCellNum(); i < row.getLastCellNum(); i++) { + cell = row.getCell(i); + if (row.getCell(i) != null && (cell.getCellType() == Cell.CELL_TYPE_STRING || cell.getCellType() == Cell.CELL_TYPE_NUMERIC)) { + cell.setCellType(Cell.CELL_TYPE_STRING); + String text = cell.getStringCellValue(); + if (text.contains(IF_DELETE)) { + if (Boolean.valueOf(eval(text.substring(text.indexOf(START_STR) + 2, text.indexOf(END_STR)).trim(), map).toString())) { + PoiSheetUtility.deleteColumn(sheet, i); + } + cell.setCellValue(""); + } + } + } + } + } + + /** + * 给每个Cell通过解析方式set值 + * + * @param cell + * @param map + */ + private void setValueForCellByMap(Cell cell, Map map) throws Exception { + int cellType = cell.getCellType(); + if (cellType != Cell.CELL_TYPE_STRING && cellType != Cell.CELL_TYPE_NUMERIC) { + return; + } + String oldString; + cell.setCellType(Cell.CELL_TYPE_STRING); + oldString = cell.getStringCellValue(); + if (oldString != null && oldString.indexOf(START_STR) != -1 && !oldString.contains(FOREACH)) { + // step 2. 判断是否含有解析函数 + String params = null; + boolean isNumber = false; + if (isNumber(oldString)) { + isNumber = true; + oldString = oldString.replace(NUMBER_SYMBOL, ""); + } + while (oldString.indexOf(START_STR) != -1) { + params = oldString.substring(oldString.indexOf(START_STR) + 2, oldString.indexOf(END_STR)); + + oldString = oldString.replace(START_STR + params + END_STR, eval(params, map).toString()); + } + // 如何是数值 类型,就按照数值类型进行设置 + if (isNumber && StringUtils.isNotBlank(oldString)) { + cell.setCellValue(Double.parseDouble(oldString)); + cell.setCellType(Cell.CELL_TYPE_NUMERIC); + } else { + cell.setCellValue(oldString); + } + } + // 判断foreach 这种方法 + if (oldString != null && oldString.contains(FOREACH)) { + addListDataToExcel(cell, map, oldString.trim()); + } + + } + + private boolean isNumber(String text) { + return text.startsWith(NUMBER_SYMBOL) || text.contains("{" + NUMBER_SYMBOL) || text.contains(" " + NUMBER_SYMBOL); + } + + /** + * 利用foreach循环输出数据 + * + * @param cell + * @param map + * @param name + * @throws Exception + */ + private void addListDataToExcel(Cell cell, Map map, String name) throws Exception { + boolean isCreate = !name.contains(FOREACH_NOT_CREATE); + boolean isShift = name.contains(FOREACH_AND_SHIFT); + name = name.replace(FOREACH_NOT_CREATE, EMPTY).replace(FOREACH_AND_SHIFT, EMPTY).replace(FOREACH, EMPTY).replace(START_STR, EMPTY); + String[] keys = name.replaceAll("\\s{1,}", " ").trim().split(" "); + Collection datas = (Collection) PoiPublicUtil.getParamsValue(keys[0], map); + List columns = getAllDataColumns(cell, name.replace(keys[0], EMPTY)); + if (datas == null) { + return; + } + Iterator its = datas.iterator(); + Row row; + int rowIndex = cell.getRow().getRowNum() + 1; + // 处理当前行 + if (its.hasNext()) { + Object t = its.next(); + cell.getRow().setHeight(columns.get(0).getHeight()); + setForEeachCellValue(isCreate, cell.getRow(), cell.getColumnIndex(), t, columns, map); + } + if (isShift) { + cell.getRow().getSheet().shiftRows(cell.getRowIndex() + 1, cell.getRow().getSheet().getLastRowNum(), datas.size() - 1, true, true); + } + while (its.hasNext()) { + Object t = its.next(); + if (isCreate) { + row = cell.getRow().getSheet().createRow(rowIndex++); + } else { + row = cell.getRow().getSheet().getRow(rowIndex++); + if (row == null) { + row = cell.getRow().getSheet().createRow(rowIndex - 1); + } + } + row.setHeight(columns.get(0).getHeight()); + setForEeachCellValue(isCreate, row, cell.getColumnIndex(), t, columns, map); + } + } + + private void setForEeachCellValue(boolean isCreate, Row row, int columnIndex, Object t, List columns, Map map) throws Exception { + for (int i = 0, max = columnIndex + columns.size(); i < max; i++) { + if (row.getCell(i) == null) + row.createCell(i); + } + for (int i = 0, max = columns.size(); i < max; i++) { + boolean isNumber = false; + String tempStr = new String(columns.get(i).getName()); + if (isNumber(tempStr)) { + isNumber = true; + tempStr = tempStr.replace(NUMBER_SYMBOL, ""); + } + map.put(teplateParams.getTempParams(), t); + String val = eval(tempStr, map).toString(); + if (isNumber && StringUtils.isNotEmpty(val)) { + row.getCell(i + columnIndex).setCellValue(Double.parseDouble(val)); + row.getCell(i + columnIndex).setCellType(Cell.CELL_TYPE_NUMERIC); + } else { + row.getCell(i + columnIndex).setCellValue(val); + } + row.getCell(i + columnIndex).setCellStyle(columns.get(i).getCellStyle()); + tempCreateCellSet.add(row.getRowNum() + "_" + (i + columnIndex)); + } + + } + + /** + * 获取迭代的数据的值 + * + * @param cell + * @param name + * @return + */ + private List getAllDataColumns(Cell cell, String name) { + List columns = new ArrayList(); + cell.setCellValue(""); + if (name.contains(END_STR)) { + columns.add(new ExcelTemplateParams(name.replace(END_STR, EMPTY).trim(), cell.getCellStyle(), cell.getRow().getHeight())); + return columns; + } + columns.add(new ExcelTemplateParams(name.trim(), cell.getCellStyle(), cell.getRow().getHeight())); + int index = cell.getColumnIndex(); + Cell tempCell; + while (true) { + tempCell = cell.getRow().getCell(++index); + if (tempCell == null) { + break; + } + String cellStringString; + try {// 允许为空,单表示已经完结了,因为可能被删除了 + cellStringString = tempCell.getStringCellValue(); + if (StringUtils.isBlank(cellStringString)) { + break; + } + } catch (Exception e) { + throw new ExcelExportException("for each 当中存在空字符串,请检查模板"); + } + // 把读取过的cell 置为空 + tempCell.setCellValue(""); + if (cellStringString.contains(END_STR)) { + columns.add(new ExcelTemplateParams(cellStringString.trim().replace(END_STR, ""), tempCell.getCellStyle(), tempCell.getRow().getHeight())); + break; + } else { + if (cellStringString.trim().contains(teplateParams.getTempParams())) { + columns.add(new ExcelTemplateParams(cellStringString.trim(), tempCell.getCellStyle(), tempCell.getRow().getHeight())); + } else { + // 最后一行被删除了 + break; + } + } + + } + return columns; + } + + /** + * 对导出序列进行排序和塞选 + * + * @param excelParams + * @param titlemap + * @return + */ + private void sortAndFilterExportField(List excelParams, Map titlemap) { + for (int i = excelParams.size() - 1; i >= 0; i--) { + if (excelParams.get(i).getList() != null && excelParams.get(i).getList().size() > 0) { + sortAndFilterExportField(excelParams.get(i).getList(), titlemap); + if (excelParams.get(i).getList().size() == 0) { + excelParams.remove(i); + } else { + excelParams.get(i).setOrderNum(i); + } + } else { + if (titlemap.containsKey(excelParams.get(i).getName())) { + excelParams.get(i).setOrderNum(i); + } else { + excelParams.remove(i); + } + } + } + sortAllParams(excelParams); + } + +} diff --git a/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/html/ExcelToHtmlServer.java b/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/html/ExcelToHtmlServer.java new file mode 100644 index 000000000..223792d8c --- /dev/null +++ b/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/html/ExcelToHtmlServer.java @@ -0,0 +1,191 @@ +package com.pig4cloud.pigx.common.poi.excel.html; + +import java.util.Formatter; +import java.util.Iterator; + +import org.apache.poi.ss.usermodel.Cell; +import org.apache.poi.ss.usermodel.CellStyle; +import org.apache.poi.ss.usermodel.Row; +import org.apache.poi.ss.usermodel.Sheet; +import org.apache.poi.ss.usermodel.Workbook; +import com.pig4cloud.pigx.common.poi.excel.html.helper.CellValueHelper; +import com.pig4cloud.pigx.common.poi.excel.html.helper.MergedRegionHelper; +import com.pig4cloud.pigx.common.poi.excel.html.helper.StylerHelper; + +/** + * @author: Luckly + * @date: 2019-05-20 + *

+ * Excel转换成Html 服务 + */ +public class ExcelToHtmlServer { + + private Workbook wb; + private int sheetNum; + private int cssRandom; + + /* 是不是完成界面 */ + private boolean completeHTML; + private Formatter out; + /* 已经完成范围处理 */ + private boolean gotBounds; + private int firstColumn; + private int endColumn; + private static final String COL_HEAD_CLASS = "colHeader"; + // private static final String ROW_HEAD_CLASS = "rowHeader"; + + private static final String DEFAULTS_CLASS = "excelDefaults"; + + public ExcelToHtmlServer(Workbook wb, boolean completeHTML, int sheetNum) { + this.wb = wb; + this.completeHTML = completeHTML; + this.sheetNum = sheetNum; + cssRandom = (int) Math.ceil(Math.random() * 1000); + } + + public String printPage() { + try { + ensureOut(); + if (completeHTML) { + out.format("%n"); + out.format("%n"); + out.format("%n"); + out.format("%n"); + } + new StylerHelper(wb, out, sheetNum, cssRandom); + if (completeHTML) { + out.format("%n"); + out.format("%n"); + } + print(); + if (completeHTML) { + out.format("%n"); + out.format("%n"); + } + return out.toString(); + } finally { + if (out != null) + out.close(); + } + } + + private void print() { + printSheets(); + } + + private void ensureOut() { + if (out == null) + out = new Formatter(new StringBuilder()); + } + + private void printSheets() { + Sheet sheet = wb.getSheetAt(sheetNum); + printSheet(sheet); + } + + private void printSheet(Sheet sheet) { + out.format("%n", DEFAULTS_CLASS, getTableWidth(sheet)); + printCols(sheet); + printSheetContent(sheet); + out.format("
%n"); + } + + private void printCols(Sheet sheet) { + // out.format("%n"); + ensureColumnBounds(sheet); + for (int i = firstColumn; i < endColumn; i++) { + out.format("%n", sheet.getColumnWidth(i) / 32); + } + } + + private int getTableWidth(Sheet sheet) { + ensureColumnBounds(sheet); + int width = 0; + for (int i = firstColumn; i < endColumn; i++) { + width = width + (sheet.getColumnWidth(i) / 32); + } + return width; + } + + private void ensureColumnBounds(Sheet sheet) { + if (gotBounds) + return; + + Iterator iter = sheet.rowIterator(); + firstColumn = (iter.hasNext() ? Integer.MAX_VALUE : 0); + endColumn = 0; + while (iter.hasNext()) { + Row row = iter.next(); + short firstCell = row.getFirstCellNum(); + if (firstCell >= 0) { + firstColumn = Math.min(firstColumn, firstCell); + endColumn = Math.max(endColumn, row.getLastCellNum()); + } + } + gotBounds = true; + } + + @SuppressWarnings("unused") + /**本来是用来生成 A,B 那个列名称的**/ + private void printColumnHeads(Sheet sheet) { + out.format("%n"); + out.format(" %n", COL_HEAD_CLASS); + out.format(" ◊%n", COL_HEAD_CLASS); + StringBuilder colName = new StringBuilder(); + for (int i = firstColumn; i < endColumn; i++) { + colName.setLength(0); + int cnum = i; + do { + colName.insert(0, (char) ('A' + cnum % 26)); + cnum /= 26; + } while (cnum > 0); + out.format(" %s%n", COL_HEAD_CLASS, colName); + } + out.format(" %n"); + out.format("%n"); + } + + private void printSheetContent(Sheet sheet) { + // printColumnHeads(sheet); + MergedRegionHelper mergedRegionHelper = new MergedRegionHelper(sheet); + CellValueHelper cellValueHelper = new CellValueHelper(wb, cssRandom); + out.format("%n"); + Iterator rows = sheet.rowIterator(); + int rowIndex = 1; + while (rows.hasNext()) { + Row row = rows.next(); + out.format(" %n", row.getHeight() / 15); + // out.format(" %d%n", ROW_HEAD_CLASS, + // row.getRowNum() + 1); + for (int i = firstColumn; i < endColumn; i++) { + if (mergedRegionHelper.isNeedCreate(rowIndex, i)) { + String content = " "; + CellStyle style = null; + if (i >= row.getFirstCellNum() && i < row.getLastCellNum()) { + Cell cell = row.getCell(i); + if (cell != null) { + style = cell.getCellStyle(); + content = cellValueHelper.getHtmlValue(cell); + } + } + if (mergedRegionHelper.isMergedRegion(rowIndex, i)) { + Integer[] rowAndColSpan = mergedRegionHelper.getRowAndColSpan(rowIndex, i); + out.format(" %s%n", rowAndColSpan[0], rowAndColSpan[1], styleName(style), content); + } else { + out.format(" %s%n", styleName(style), content); + } + } + + } + out.format(" %n"); + rowIndex++; + } + out.format("%n"); + } + + private String styleName(CellStyle style) { + if (style == null) + return ""; + return String.format("style_%02x_%s font_%s_%s", style.getIndex(), cssRandom, style.getFontIndex(), cssRandom); + } +} diff --git a/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/html/helper/CellValueHelper.java b/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/html/helper/CellValueHelper.java new file mode 100644 index 000000000..a47261fa3 --- /dev/null +++ b/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/html/helper/CellValueHelper.java @@ -0,0 +1,134 @@ +package com.pig4cloud.pigx.common.poi.excel.html.helper; + +import java.util.HashMap; +import java.util.Map; + +import org.apache.poi.hssf.usermodel.HSSFRichTextString; +import org.apache.poi.hssf.usermodel.HSSFWorkbook; +import org.apache.poi.ss.usermodel.Cell; +import org.apache.poi.ss.usermodel.Font; +import org.apache.poi.ss.usermodel.Workbook; +import org.apache.poi.xssf.usermodel.XSSFFont; +import org.apache.poi.xssf.usermodel.XSSFRichTextString; +import org.apache.poi.xssf.usermodel.XSSFWorkbook; + +import com.google.common.xml.XmlEscapers; + +/** + * @author: Luckly + * @date: 2019-05-20 + *

+ * Cell值帮助类 + */ +public class CellValueHelper { + /** + * Excel 格式 + */ + private boolean is07; + + private int cssRandom; + + private Map fontCache = new HashMap(); + + public CellValueHelper(Workbook wb, int cssRandom) { + this.cssRandom = cssRandom; + if (wb instanceof HSSFWorkbook) + is07 = false; + else if (wb instanceof XSSFWorkbook) { + is07 = true; + cacheFontInfo(wb); + } else + throw new IllegalArgumentException("unknown workbook type: " + wb.getClass().getSimpleName()); + } + + /** + * O7 版本坑爹bug + * + * @param wb + */ + private void cacheFontInfo(Workbook wb) { + for (short i = 0, le = wb.getNumberOfFonts(); i < le; i++) { + Font font = wb.getFontAt(i); + fontCache.put(font.getBoldweight() + "_" + font.getItalic() + "_" + font.getFontName() + "_" + font.getFontHeightInPoints() + "_" + font.getColor(), font.getIndex() + ""); + } + + } + + public String getHtmlValue(Cell cell) { + if (Cell.CELL_TYPE_BOOLEAN == cell.getCellType() || Cell.CELL_TYPE_NUMERIC == cell.getCellType()) { + cell.setCellType(Cell.CELL_TYPE_STRING); + return cell.getStringCellValue(); + } else if (Cell.CELL_TYPE_STRING == cell.getCellType()) { + if (cell.getRichStringCellValue().numFormattingRuns() == 0) { + return XmlEscapers.xmlContentEscaper().escape(cell.getStringCellValue()); + } else if (is07) { + return getXSSFRichString((XSSFRichTextString) cell.getRichStringCellValue()); + } else { + return getHSSFRichString((HSSFRichTextString) cell.getRichStringCellValue()); + } + } + return ""; + } + + /** + * 03版本复杂数据 + * + * @param rich + * @return + */ + private String getHSSFRichString(HSSFRichTextString rich) { + int nums = rich.numFormattingRuns(); + StringBuilder sb = new StringBuilder(); + String text = rich.toString(); + int currentIndex = 0; + sb.append(text.substring(0, rich.getIndexOfFormattingRun(0))); + for (int i = 0; i < nums; i++) { + sb.append(""); + currentIndex = rich.getIndexOfFormattingRun(i); + if (i < nums - 1) { + sb.append(XmlEscapers.xmlContentEscaper().escape(text.substring(currentIndex, rich.getIndexOfFormattingRun(i + 1)))); + } else { + sb.append(XmlEscapers.xmlContentEscaper().escape(text.substring(currentIndex, text.length()))); + } + sb.append(""); + } + return sb.toString(); + } + + /** + * 07版本复杂数据 + * + * @param rich + * @return + */ + private String getXSSFRichString(XSSFRichTextString rich) { + int nums = rich.numFormattingRuns(); + StringBuilder sb = new StringBuilder(); + String text = rich.toString(); + int currentIndex = 0, lastIndex = 0; + for (int i = 1; i <= nums; i++) { + sb.append(""); + currentIndex = rich.getIndexOfFormattingRun(i) == -1 ? text.length() : rich.getIndexOfFormattingRun(i); + sb.append(XmlEscapers.xmlContentEscaper().escape(text.substring(lastIndex, currentIndex))); + sb.append(""); + lastIndex = currentIndex; + } + return sb.toString(); + } + + private String getFontIndex(XSSFFont font) { + return fontCache.get(font.getBoldweight() + "_" + font.getItalic() + "_" + font.getFontName() + "_" + font.getFontHeightInPoints() + "_" + font.getColor()); + } +} diff --git a/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/html/helper/MergedRegionHelper.java b/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/html/helper/MergedRegionHelper.java new file mode 100644 index 000000000..08af642d6 --- /dev/null +++ b/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/html/helper/MergedRegionHelper.java @@ -0,0 +1,95 @@ +package com.pig4cloud.pigx.common.poi.excel.html.helper; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +import org.apache.poi.ss.usermodel.Sheet; + +/** + * 合并单元格帮助类 + * @author: Luckly + * @date: 2019-05-20 + *

+ */ +public class MergedRegionHelper { + + private Map mergedCache = new HashMap(); + + private Set notNeedCread = new HashSet(); + + public MergedRegionHelper(Sheet sheet) { + getAllMergedRegion(sheet); + } + + private void getAllMergedRegion(Sheet sheet) { + int nums = sheet.getNumMergedRegions(); + for (int i = 0; i < nums; i++) { + handerMergedString(sheet.getMergedRegion(i).formatAsString()); + } + } + + /** + * 根据合并输出内容,处理合并单元格事情 + * + * @param formatAsString + */ + private void handerMergedString(String formatAsString) { + String[] strArr = formatAsString.split(":"); + if (strArr.length == 2) { + int startCol = strArr[0].charAt(0) - 65; + if (strArr[0].charAt(1) >= 65) { + startCol = (startCol + 1) * 26 + (strArr[0].charAt(1) - 65); + } + int startRol = Integer.valueOf(strArr[0].substring(strArr[0].charAt(1) >= 65 ? 2 : 1)); + int endCol = strArr[1].charAt(0) - 65; + if (strArr[1].charAt(1) >= 65) { + endCol = (endCol + 1) * 26 + (strArr[1].charAt(1) - 65); + } + int endRol = Integer.valueOf(strArr[1].substring(strArr[1].charAt(1) >= 65 ? 2 : 1)); + mergedCache.put(startRol + "_" + startCol, new Integer[] { endRol - startRol + 1, endCol - startCol + 1 }); + for (int i = startRol; i <= endRol; i++) { + for (int j = startCol; j <= endCol; j++) { + notNeedCread.add(i + "_" + j); + } + } + notNeedCread.remove(startRol + "_" + startCol); + } + + } + + /** + * 是不是需要创建这个TD + * + * @param row + * @param col + * @return + */ + public boolean isNeedCreate(int row, int col) { + return !notNeedCread.contains(row + "_" + col); + } + + /** + * 是不是合并区域 + * + * @param row + * @param col + * @return + */ + public boolean isMergedRegion(int row, int col) { + return mergedCache.containsKey(row + "_" + col); + } + + /** + * 获取合并区域 + * + * @param row + * @param col + * @return + */ + public Integer[] getRowAndColSpan(int row, int col) { + return mergedCache.get(row + "_" + col); + } + +} diff --git a/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/html/helper/StylerHelper.java b/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/html/helper/StylerHelper.java new file mode 100644 index 000000000..ff033b8cc --- /dev/null +++ b/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/html/helper/StylerHelper.java @@ -0,0 +1,271 @@ +package com.pig4cloud.pigx.common.poi.excel.html.helper; + +import static org.apache.poi.ss.usermodel.CellStyle.ALIGN_CENTER; +import static org.apache.poi.ss.usermodel.CellStyle.ALIGN_CENTER_SELECTION; +import static org.apache.poi.ss.usermodel.CellStyle.ALIGN_FILL; +import static org.apache.poi.ss.usermodel.CellStyle.ALIGN_JUSTIFY; +import static org.apache.poi.ss.usermodel.CellStyle.ALIGN_LEFT; +import static org.apache.poi.ss.usermodel.CellStyle.ALIGN_RIGHT; +import static org.apache.poi.ss.usermodel.CellStyle.VERTICAL_BOTTOM; +import static org.apache.poi.ss.usermodel.CellStyle.VERTICAL_CENTER; +import static org.apache.poi.ss.usermodel.CellStyle.VERTICAL_TOP; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.util.Formatter; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Map; +import java.util.Set; + +import org.apache.poi.hssf.usermodel.HSSFCellStyle; +import org.apache.poi.hssf.usermodel.HSSFPalette; +import org.apache.poi.hssf.usermodel.HSSFWorkbook; +import org.apache.poi.hssf.util.HSSFColor; +import org.apache.poi.ss.usermodel.Cell; +import org.apache.poi.ss.usermodel.CellStyle; +import org.apache.poi.ss.usermodel.Color; +import org.apache.poi.ss.usermodel.Font; +import org.apache.poi.ss.usermodel.Row; +import org.apache.poi.ss.usermodel.Sheet; +import org.apache.poi.ss.usermodel.Workbook; +import org.apache.poi.xssf.usermodel.XSSFCellStyle; +import org.apache.poi.xssf.usermodel.XSSFColor; +import org.apache.poi.xssf.usermodel.XSSFFont; +import org.apache.poi.xssf.usermodel.XSSFWorkbook; +import com.pig4cloud.pigx.common.poi.util.PoiPublicUtil; + +/** + * 样式帮助类 + * @author: Luckly + * @date: 2019-05-20 + *

+ */ +public class StylerHelper { + + private static String DEFAULTS_CLASS_CSS = ".excelDefaults {background-color: white;color: black;text-decoration: none;direction: ltr;text-transform: none;text-indent: 0;letter-spacing: 0;word-spacing: 0;white-space: normal;unicode-bidi: normal;vertical-align: 0;text-shadow: none;padding: 0;margin: 0;border-collapse: collapse;white-space: pre-wrap;word-wrap: break-word;word-break: break-all;}.excelDefaults td {padding: 1px 5px;border: 1px solid silver;border-color: #000000;text-align: center;vertical-align: middle;font-size: 12pt;}.excelDefaults .colHeader {background-color: silver;font-weight: bold;border: 1px solid black;text-align: center;padding: 1px 5px;}.excelDefaults .rowHeader {background-color: silver;font-weight: bold;border: 1px solid black;text-align: right;padding: 1px 5px;}"; + + private static final String DEFAULTS_CLASS = "excelDefaults"; + + private static final Map ALIGN = PoiPublicUtil.mapFor(ALIGN_LEFT, "left", ALIGN_CENTER, "center", ALIGN_RIGHT, "right", ALIGN_FILL, "left", ALIGN_JUSTIFY, "left", ALIGN_CENTER_SELECTION, "center"); + + private static final Map VERTICAL_ALIGN = PoiPublicUtil.mapFor(VERTICAL_BOTTOM, "bottom", VERTICAL_CENTER, "middle", VERTICAL_TOP, "top"); + + private Formatter out; + + private Sheet sheet; + + private HtmlHelper helper; + + private int sheetNum; + + private int cssRandom; + + public StylerHelper(Workbook wb, Formatter out, int sheetNum, int cssRandom) { + this.out = out; + this.sheetNum = sheetNum; + this.cssRandom = cssRandom; + if (wb instanceof HSSFWorkbook) + helper = new HSSFHtmlHelper((HSSFWorkbook) wb); + else if (wb instanceof XSSFWorkbook) + helper = new XSSFHtmlHelper((XSSFWorkbook) wb); + else + throw new IllegalArgumentException("unknown workbook type: " + wb.getClass().getSimpleName()); + printInlineStyle(wb); + } + + private void printInlineStyle(Workbook wb) { + out.format("%n"); + } + + private void prontFonts(Workbook wb) { + for (short i = 0, le = wb.getNumberOfFonts(); i <= le; i++) { + Font font = wb.getFontAt(i); + out.format(".%s .%s {%n", DEFAULTS_CLASS, "font_" + i + "_" + cssRandom); + fontStyle(font); + out.format("}%n"); + } + + } + + public void printStyles(Workbook wb) { + if (DEFAULTS_CLASS_CSS == null) { + DEFAULTS_CLASS_CSS = getDefaultsClassCss(); + } + out.format(DEFAULTS_CLASS_CSS); + Set seen = new HashSet(); + sheet = wb.getSheetAt(sheetNum); + Iterator rows = sheet.rowIterator(); + while (rows.hasNext()) { + Row row = rows.next(); + for (Cell cell : row) { + CellStyle style = cell.getCellStyle(); + if (!seen.contains(style)) { + printStyle(style); + seen.add(style); + } + } + } + } + + private String getDefaultsClassCss() { + BufferedReader in = null; + StringBuilder sb = new StringBuilder(); + Formatter formatter = new Formatter(sb); + try { + in = new BufferedReader(new InputStreamReader(StylerHelper.class.getResourceAsStream("excelStyle.css"))); + String line; + while ((line = in.readLine()) != null) { + formatter.format("%s%n", line); + } + return formatter.toString(); + } catch (IOException e) { + throw new IllegalStateException("Reading standard css", e); + } finally { + if (in != null) { + try { + in.close(); + } catch (IOException e) { + throw new IllegalStateException("Reading standard css", e); + } + } + formatter.close(); + } + } + + private void printStyle(CellStyle style) { + out.format(".%s .%s {%n", DEFAULTS_CLASS, styleName(style)); + styleContents(style); + out.format("}%n"); + } + + private void styleContents(CellStyle style) { + if (style.getAlignment() != 2) { + styleOut("text-align", style.getAlignment(), ALIGN); + styleOut("vertical-align", style.getAlignment(), VERTICAL_ALIGN); + } + helper.colorStyles(style, out); + } + + private void fontStyle(Font font) { + if (font.getBoldweight() >= Font.BOLDWEIGHT_BOLD) + out.format(" font-weight: bold;%n"); + if (font.getItalic()) + out.format(" font-style: italic;%n"); + out.format(" font-family: %s;%n", font.getFontName()); + + int fontheight = font.getFontHeightInPoints(); + if (fontheight == 9) { + fontheight = 10; + } + out.format(" font-size: %dpt;%n", fontheight); + helper.styleColor(out, "color", getColor(font)); + } + + private Color getColor(Font font) { + if (helper instanceof HSSFHtmlHelper) { + return ((HSSFWorkbook) sheet.getWorkbook()).getCustomPalette().getColor(font.getColor()); + } else { + return ((XSSFFont) font).getXSSFColor(); + } + } + + private String styleName(CellStyle style) { + if (style == null) + return ""; + return String.format("style_%02x_%s", style.getIndex(), cssRandom); + } + + private void styleOut(String attr, K key, Map mapping) { + String value = mapping.get(key); + if (value != null) { + out.format(" %s: %s;%n", attr, value); + } + } + + private interface HtmlHelper { + /** + * Outputs the appropriate CSS style for the given cell style. + * + * @param style + * The cell style. + * @param out + * The place to write the output. + */ + void colorStyles(CellStyle style, Formatter out); + + void styleColor(Formatter out, String attr, Color color); + } + + private class HSSFHtmlHelper implements HtmlHelper { + private final HSSFWorkbook wb; + private final HSSFPalette colors; + + private HSSFColor HSSF_AUTO = new HSSFColor.AUTOMATIC(); + + public HSSFHtmlHelper(HSSFWorkbook wb) { + this.wb = wb; + colors = wb.getCustomPalette(); + } + + public void colorStyles(CellStyle style, Formatter out) { + HSSFCellStyle cs = (HSSFCellStyle) style; + out.format(" /* fill pattern = %d */%n", cs.getFillPattern()); + styleColor(out, "background-color", cs.getFillForegroundColor()); + styleColor(out, "color", colors.getColor(cs.getFont(wb).getColor())); + } + + private void styleColor(Formatter out, String attr, short index) { + HSSFColor color = colors.getColor(index); + if (index == HSSF_AUTO.getIndex() || color == null) { + out.format(" /* %s: index = %d */%n", attr, index); + } else { + short[] rgb = color.getTriplet(); + out.format(" %s: #%02x%02x%02x; /* index = %d */%n", attr, rgb[0], rgb[1], rgb[2], index); + } + } + + public void styleColor(Formatter out, String attr, Color color) { + if (color == null) { + return; + } + HSSFColor hSSFColor = (HSSFColor) color; + short[] rgb = hSSFColor.getTriplet(); + out.format(" %s: #%02x%02x%02x; %n", attr, rgb[0], rgb[1], rgb[2]); + } + } + + /** + * Implementation of {@link HtmlHelper} for XSSF files. + * + * @author Ken Arnold, Industrious Media LLC + */ + private class XSSFHtmlHelper implements HtmlHelper { + + public XSSFHtmlHelper(XSSFWorkbook wb) { + } + + public void colorStyles(CellStyle style, Formatter out) { + XSSFCellStyle cs = (XSSFCellStyle) style; + styleColor(out, "background-color", cs.getFillForegroundXSSFColor()); + styleColor(out, "color", cs.getFont().getXSSFColor()); + } + + public void styleColor(Formatter out, String attr, Color color) { + XSSFColor xSSFColor = (XSSFColor) color; + if (color == null || xSSFColor.isAuto()) + return; + + byte[] rgb = xSSFColor.getRGB(); + if (rgb == null) { + return; + } + out.format(" %s: #%02x%02x%02x;%n", attr, rgb[0], rgb[1], rgb[2]); + } + } + +} diff --git a/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/html/helper/excelStyle.css b/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/html/helper/excelStyle.css new file mode 100644 index 000000000..93fdbe215 --- /dev/null +++ b/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/html/helper/excelStyle.css @@ -0,0 +1,45 @@ +.excelDefaults { + background-color: white; + color: black; + text-decoration: none; + direction: ltr; + text-transform: none; + text-indent: 0; + letter-spacing: 0; + word-spacing: 0; + white-space: normal; + unicode-bidi: normal; + vertical-align: 0; + text-shadow: none; + padding: 0; + margin: 0; + border-collapse: collapse; + white-space: pre-wrap; + word-wrap: break-word; + word-break: break-all; +} + +.excelDefaults td { + padding: 1px 5px; + border: 1px solid silver; + border-color: #000000; + text-align: center; + vertical-align: middle; + font-size: 12pt; +} + +.excelDefaults .colHeader { + background-color: silver; + font-weight: bold; + border: 1px solid black; + text-align: center; + padding: 1px 5px; +} + +.excelDefaults .rowHeader { + background-color: silver; + font-weight: bold; + border: 1px solid black; + text-align: right; + padding: 1px 5px; +} \ No newline at end of file diff --git a/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/imports/CellValueServer.java b/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/imports/CellValueServer.java new file mode 100644 index 000000000..de21688d9 --- /dev/null +++ b/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/imports/CellValueServer.java @@ -0,0 +1,278 @@ +package com.pig4cloud.pigx.common.poi.excel.imports; + +import com.pig4cloud.pigx.common.poi.excel.entity.params.ExcelImportEntity; +import com.pig4cloud.pigx.common.poi.excel.entity.sax.SaxReadCellEntity; +import com.pig4cloud.pigx.common.poi.exception.excel.ExcelImportException; +import com.pig4cloud.pigx.common.poi.exception.excel.enums.ExcelImportEnum; +import com.pig4cloud.pigx.common.poi.handler.inter.IExcelDataHandler; +import com.pig4cloud.pigx.common.poi.util.PoiPublicUtil; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.apache.poi.ss.usermodel.Cell; + +import java.lang.reflect.Method; +import java.lang.reflect.Type; +import java.math.BigDecimal; +import java.sql.Time; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Arrays; +import java.util.Date; +import java.util.List; +import java.util.Map; + +/** + * + * @author: Luckly + * @date: 2019-05-20 + *

+ * Cell 取值服务 判断类型处理数据 + * 1.判断Excel中的类型 + * 2.根据replace替换值 + * 3.handler处理数据 + * 4.判断返回类型转化数据返回 + */ +@Slf4j +public class CellValueServer { + + private List hanlderList = null; + + /** + * 获取单元格内的值 + * + * @param xclass + * @param cell + * @param entity + * @return + */ + private Object getCellValue(String xclass, Cell cell, ExcelImportEntity entity) { + if (cell == null) { + return ""; + } + Object result = null; + // 日期格式比较特殊,和cell格式不一致 + if ("class java.util.Date".equals(xclass) || ("class java.sql.Time").equals(xclass)) { + if (Cell.CELL_TYPE_NUMERIC == cell.getCellType()) { + // 日期格式 + result = cell.getDateCellValue(); + } else { + cell.setCellType(Cell.CELL_TYPE_STRING); + result = getDateData(entity, cell.getStringCellValue()); + } + if (("class java.sql.Time").equals(xclass)) { + result = new Time(((Date) result).getTime()); + } + } else if (Cell.CELL_TYPE_NUMERIC == cell.getCellType()) { + result = cell.getNumericCellValue(); + } else if (Cell.CELL_TYPE_BOOLEAN == cell.getCellType()) { + result = cell.getBooleanCellValue(); + } else { + result = cell.getStringCellValue(); + } + return result; + } + + /** + * 获取日期类型数据 + * + * @param entity + * @param value + * @return + */ + private Date getDateData(ExcelImportEntity entity, String value) { + if (StringUtils.isNotEmpty(entity.getFormat()) && StringUtils.isNotEmpty(value)) { + SimpleDateFormat format = new SimpleDateFormat(entity.getFormat()); + try { + return format.parse(value); + } catch (ParseException e) { + log.error("时间格式化失败,格式化:{},值:{}", entity.getFormat(), value); + throw new ExcelImportException(ExcelImportEnum.GET_VALUE_ERROR); + } + } + return null; + } + + /** + * 获取cell的值 + * + * @param object + * @param excelParams + * @param cell + * @param titleString + */ + public Object getValue(IExcelDataHandler dataHanlder, Object object, Cell cell, Map excelParams, String titleString) throws Exception { + ExcelImportEntity entity = excelParams.get(titleString); + String xclass = "class java.lang.Object"; + if (!(object instanceof Map)) { + Method setMethod = entity.getMethods() != null && entity.getMethods().size() > 0 ? entity.getMethods().get(entity.getMethods().size() - 1) : entity.getMethod(); + Type[] ts = setMethod.getGenericParameterTypes(); + xclass = ts[0].toString(); + } + Object result = getCellValue(xclass, cell, entity); + if (entity != null) { + result = hanlderSuffix(entity.getSuffix(), result); + result = replaceValue(entity.getReplace(), result,entity.isMultiReplace()); + } + result = hanlderValue(dataHanlder, object, result, titleString); + return getValueByType(xclass, result, entity); + } + + /** + * 获取cell值 + * + * @param dataHanlder + * @param object + * @param entity + * @param excelParams + * @param titleString + * @return + */ + public Object getValue(IExcelDataHandler dataHanlder, Object object, SaxReadCellEntity cellEntity, Map excelParams, String titleString) { + ExcelImportEntity entity = excelParams.get(titleString); + Method setMethod = entity.getMethods() != null && entity.getMethods().size() > 0 ? entity.getMethods().get(entity.getMethods().size() - 1) : entity.getMethod(); + Type[] ts = setMethod.getGenericParameterTypes(); + String xclass = ts[0].toString(); + Object result = cellEntity.getValue(); + result = hanlderSuffix(entity.getSuffix(), result); + result = replaceValue(entity.getReplace(), result,entity.isMultiReplace()); + result = hanlderValue(dataHanlder, object, result, titleString); + return getValueByType(xclass, result, entity); + } + + /** + * 把后缀删除掉 + * + * @param result + * @param suffix + * @return + */ + private Object hanlderSuffix(String suffix, Object result) { + if (StringUtils.isNotEmpty(suffix) && result != null && result.toString().endsWith(suffix)) { + String temp = result.toString(); + return temp.substring(0, temp.length() - suffix.length()); + } + return result; + } + + /** + * 根据返回类型获取返回值 + * + * @param xclass + * @param result + * @param entity + * @return + */ + private Object getValueByType(String xclass, Object result, ExcelImportEntity entity) { + try { + //update-begin-author:scott date:20180711 for:TASK #2950 【bug】excel 导入报错,空指针问题 + if(result==null || "".equals(String.valueOf(result))){ + return null; + } + //update-end-author:scott date:20180711 for:TASK #2950 【bug】excel 导入报错,空指针问题 + if ("class java.util.Date".equals(xclass)) { + return result; + } + if ("class java.lang.Boolean".equals(xclass) || "boolean".equals(xclass)) { + return Boolean.valueOf(String.valueOf(result)); + } + if ("class java.lang.Double".equals(xclass) || "double".equals(xclass)) { + return Double.valueOf(String.valueOf(result)); + } + if ("class java.lang.Long".equals(xclass) || "long".equals(xclass)) { + return Long.valueOf(String.valueOf(result)); + } + if ("class java.lang.Float".equals(xclass) || "float".equals(xclass)) { + return Float.valueOf(String.valueOf(result)); + } + if ("class java.lang.Integer".equals(xclass) || "int".equals(xclass)) { + return Integer.valueOf(String.valueOf(result)); + } + if ("class java.math.BigDecimal".equals(xclass)) { + return new BigDecimal(String.valueOf(result)); + } + if ("class java.lang.String".equals(xclass)) { + // 针对String 类型,但是Excel获取的数据却不是String,比如Double类型,防止科学计数法 + if (result instanceof String) { + return result; + } + // double类型防止科学计数法 + if (result instanceof Double) { + return PoiPublicUtil.doubleToString((Double) result); + } + return String.valueOf(result); + } + return result; + } catch (Exception e) { + log.error(e.getMessage(), e); + throw new ExcelImportException(ExcelImportEnum.GET_VALUE_ERROR); + } + } + + /** + * 调用处理接口处理值 + * + * @param dataHanlder + * @param object + * @param result + * @param titleString + * @return + */ + private Object hanlderValue(IExcelDataHandler dataHanlder, Object object, Object result, String titleString) { + if (dataHanlder == null || dataHanlder.getNeedHandlerFields() == null || dataHanlder.getNeedHandlerFields().length == 0) { + return result; + } + if (hanlderList == null) { + hanlderList = Arrays.asList(dataHanlder.getNeedHandlerFields()); + } + if (hanlderList.contains(titleString)) { + return dataHanlder.importHandler(object, titleString, result); + } + return result; + } + + /** + * 导入支持多值替换 + * + * @param replace 数据库中字典查询出来的数组 + * @param result excel单元格获取的值 + * @param multiReplace 是否支持多值替换 + */ + private Object replaceValue(String[] replace, Object result,boolean multiReplace) { + if(result == null){ + return ""; + } + if(replace == null || replace.length<=0){ + return result; + } + String temp = String.valueOf(result); + String backValue = ""; + if(temp.indexOf(",")>0 && multiReplace){ + //原值中带有逗号,认为他是多值的 + String multiReplaces[] = temp.split(","); + for (String str : multiReplaces) { + backValue = backValue.concat(replaceSingleValue(replace, str)+","); + } + if(backValue.equals("")){ + backValue = temp; + }else{ + backValue = backValue.substring(0, backValue.length()-1); + } + }else{ + backValue = replaceSingleValue(replace, temp); + } + return backValue; + } + /** + * 单值替换 ,若没找到则原值返回 + */ + private String replaceSingleValue(String[] replace, String temp){ + String[] tempArr; + for (int i = 0; i < replace.length; i++) { + tempArr = replace[i].split("_"); + if (temp.equals(tempArr[0])) { + return tempArr[1]; + } + } + return temp; + } +} diff --git a/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/imports/ExcelImportServer.java b/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/imports/ExcelImportServer.java new file mode 100644 index 000000000..8a37aacfe --- /dev/null +++ b/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/imports/ExcelImportServer.java @@ -0,0 +1,410 @@ +package com.pig4cloud.pigx.common.poi.excel.imports; + +import com.pig4cloud.pigx.common.poi.excel.annotation.ExcelTarget; +import com.pig4cloud.pigx.common.poi.excel.entity.ImportParams; +import com.pig4cloud.pigx.common.poi.excel.entity.params.ExcelCollectionParams; +import com.pig4cloud.pigx.common.poi.excel.entity.params.ExcelImportEntity; +import com.pig4cloud.pigx.common.poi.excel.entity.result.ExcelImportResult; +import com.pig4cloud.pigx.common.poi.excel.entity.result.ExcelVerifyHanlderResult; +import com.pig4cloud.pigx.common.poi.excel.imports.base.ImportBaseService; +import com.pig4cloud.pigx.common.poi.excel.imports.verifys.VerifyHandlerServer; +import com.pig4cloud.pigx.common.poi.exception.excel.ExcelImportException; +import com.pig4cloud.pigx.common.poi.exception.excel.enums.ExcelImportEnum; +import com.pig4cloud.pigx.common.poi.util.ExcelUtil; +import com.pig4cloud.pigx.common.poi.util.PoiPublicUtil; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.apache.poi.POIXMLDocument; +import org.apache.poi.hssf.usermodel.HSSFSheet; +import org.apache.poi.hssf.usermodel.HSSFWorkbook; +import org.apache.poi.openxml4j.opc.OPCPackage; +import org.apache.poi.poifs.filesystem.POIFSFileSystem; +import org.apache.poi.ss.formula.functions.T; +import org.apache.poi.ss.usermodel.*; +import org.apache.poi.xssf.usermodel.XSSFSheet; +import org.apache.poi.xssf.usermodel.XSSFWorkbook; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.InputStream; +import java.io.PushbackInputStream; +import java.lang.reflect.Field; +import java.util.*; + +/** + * + * @author: Luckly + * @date: 2019-05-20 + *

+ * Excel 导入服务 + */ +@Slf4j +@SuppressWarnings({ "rawtypes", "unchecked", "hiding" }) +public class ExcelImportServer extends ImportBaseService { + + private CellValueServer cellValueServer; + + private VerifyHandlerServer verifyHandlerServer; + + private boolean verfiyFail = false; + /** + * 异常数据styler + */ + private CellStyle errorCellStyle; + + public ExcelImportServer() { + this.cellValueServer = new CellValueServer(); + this.verifyHandlerServer = new VerifyHandlerServer(); + } + + /*** + * 向List里面继续添加元素 + * + * @param exclusions + * @param object + * @param param + * @param row + * @param titlemap + * @param targetId + * @param pictures + * @param params + */ + private void addListContinue(Object object, ExcelCollectionParams param, Row row, Map titlemap, String targetId, Map pictures, ImportParams params) throws Exception { + Collection collection = (Collection) PoiPublicUtil.getMethod(param.getName(), object.getClass()).invoke(object, new Object[] {}); + Object entity = PoiPublicUtil.createObject(param.getType(), targetId); + String picId; + boolean isUsed = false;// 是否需要加上这个对象 + for (int i = row.getFirstCellNum(); i < row.getLastCellNum(); i++) { + Cell cell = row.getCell(i); + String titleString = (String) titlemap.get(i); + if (param.getExcelParams().containsKey(titleString)) { + if (param.getExcelParams().get(titleString).getType() == 2) { + picId = row.getRowNum() + "_" + i; + saveImage(object, picId, param.getExcelParams(), titleString, pictures, params); + } else { + saveFieldValue(params, entity, cell, param.getExcelParams(), titleString, row); + } + isUsed = true; + } + } + if (isUsed) { + collection.add(entity); + } + } + + /** + * 获取key的值,针对不同类型获取不同的值 + * + * @param cell + * @return + */ + private String getKeyValue(Cell cell) { + Object obj = null; + switch (cell.getCellType()) { + case Cell.CELL_TYPE_STRING: + obj = cell.getStringCellValue(); + break; + case Cell.CELL_TYPE_BOOLEAN: + obj = cell.getBooleanCellValue(); + break; + case Cell.CELL_TYPE_NUMERIC: + obj = cell.getNumericCellValue(); + break; + case Cell.CELL_TYPE_FORMULA: + obj = cell.getCellFormula(); + break; + } + return obj == null ? null : obj.toString().trim(); + } + + /** + * 获取保存的真实路径 + * + * @param excelImportEntity + * @param object + * @return + * @throws Exception + */ + private String getSaveUrl(ExcelImportEntity excelImportEntity, Object object) throws Exception { + String url = ""; + if (excelImportEntity.getSaveUrl().equals("upload")) { + if (excelImportEntity.getMethods() != null && excelImportEntity.getMethods().size() > 0) { + object = getFieldBySomeMethod(excelImportEntity.getMethods(), object); + } + url = object.getClass().getName().split("\\.")[object.getClass().getName().split("\\.").length - 1]; + return excelImportEntity.getSaveUrl() + "/" + url.substring(0, url.lastIndexOf("Entity")); + } + return excelImportEntity.getSaveUrl(); + } + private List importExcel(Collection result, Sheet sheet, Class pojoClass, ImportParams params, Map pictures) throws Exception { + List collection = new ArrayList(); + Map excelParams = new HashMap(); + List excelCollection = new ArrayList(); + String targetId = null; + if (!Map.class.equals(pojoClass)) { + Field fileds[] = PoiPublicUtil.getClassFields(pojoClass); + ExcelTarget etarget = pojoClass.getAnnotation(ExcelTarget.class); + if (etarget != null) { + targetId = etarget.value(); + } + getAllExcelField(targetId, fileds, excelParams, excelCollection, pojoClass, null); + } + Iterator rows = sheet.rowIterator(); + Map titlemap = getTitleMap(sheet, rows, params, excelCollection); + Row row = null; + //跳过表头和标题行 + for (int j = 0; j < params.getTitleRows() + params.getHeadRows(); j++) { + row = rows.next(); + } + Object object = null; + String picId; + while (rows.hasNext() && (row == null || sheet.getLastRowNum() - row.getRowNum() > params.getLastOfInvalidRow())) { + row = rows.next(); + // 判断是集合元素还是不是集合元素,如果是就继续加入这个集合,不是就创建新的对象 + if ((row.getCell(params.getKeyIndex()) == null || StringUtils.isEmpty(getKeyValue(row.getCell(params.getKeyIndex())))) + && object != null && !Map.class.equals(pojoClass)) { + for (ExcelCollectionParams param : excelCollection) { + addListContinue(object, param, row, titlemap, targetId, pictures, params); + } + + } else { + object = PoiPublicUtil.createObject(pojoClass, targetId); + try { + for (int i = row.getFirstCellNum(), le = row.getLastCellNum(); i < le; i++) { + Cell cell = row.getCell(i); + String titleString = (String) titlemap.get(i); + if (excelParams.containsKey(titleString) || Map.class.equals(pojoClass)) { + if (excelParams.get(titleString) != null && excelParams.get(titleString).getType() == 2) { + picId = row.getRowNum() + "_" + i; + saveImage(object, picId, excelParams, titleString, pictures, params); + } else { + saveFieldValue(params, object, cell, excelParams, titleString, row); + } + } + } + + for (ExcelCollectionParams param : excelCollection) { + addListContinue(object, param, row, titlemap, targetId, pictures, params); + } + collection.add(object); + } catch (ExcelImportException e) { + if (!e.getType().equals(ExcelImportEnum.VERIFY_ERROR)) { + throw new ExcelImportException(e.getType(), e); + } + } + } + } + return collection; + } + + /** + * 获取表格字段列名对应信息 + * + * @param rows + * @param params + * @param excelCollection + * @return + */ + private Map getTitleMap(Sheet sheet, Iterator rows, ImportParams params, List excelCollection) { + Map titlemap = new HashMap(); + Iterator cellTitle = null; + String collectionName = null; + ExcelCollectionParams collectionParams = null; + Row headRow = null; + int headBegin = params.getTitleRows(); + //找到首行表头,每个sheet都必须至少有一行表头 + while(headRow == null){ + headRow = sheet.getRow(headBegin++); + } + //设置表头行数 + if (ExcelUtil.isMergedRegion(sheet, headRow.getRowNum(), 0)) { + params.setHeadRows(2); + }else{ + params.setHeadRows(1); + } + cellTitle = headRow.cellIterator(); + while (cellTitle.hasNext()) { + Cell cell = cellTitle.next(); + String value = getKeyValue(cell); + if (StringUtils.isNotEmpty(value)) { + titlemap.put(cell.getColumnIndex(), value);//加入表头列表 + } + } + + //多行表头 + for (int j = headBegin; j < headBegin + params.getHeadRows()-1; j++) { + headRow = sheet.getRow(j); + cellTitle = headRow.cellIterator(); + while (cellTitle.hasNext()) { + Cell cell = cellTitle.next(); + String value = getKeyValue(cell); + if (StringUtils.isNotEmpty(value)) { + int columnIndex = cell.getColumnIndex(); + //当前cell的上一行是否为合并单元格 + if(ExcelUtil.isMergedRegion(sheet, cell.getRowIndex()-1, columnIndex)){ + collectionName = ExcelUtil.getMergedRegionValue(sheet, cell.getRowIndex()-1, columnIndex); + titlemap.put(cell.getColumnIndex(), collectionName + "_" + value); + }else{ + titlemap.put(cell.getColumnIndex(), value); + } + /*int i = cell.getColumnIndex(); + // 用以支持重名导入 + if (titlemap.containsKey(i)) { + collectionName = titlemap.get(i); + collectionParams = getCollectionParams(excelCollection, collectionName); + titlemap.put(i, collectionName + "_" + value); + } else if (StringUtils.isNotEmpty(collectionName) && collectionParams.getExcelParams().containsKey(collectionName + "_" + value)) { + titlemap.put(i, collectionName + "_" + value); + } else { + collectionName = null; + collectionParams = null; + } + if (StringUtils.isEmpty(collectionName)) { + titlemap.put(i, value); + }*/ + } + } + } + return titlemap; + } + /** + * 获取这个名称对应的集合信息 + * + * @param excelCollection + * @param collectionName + * @return + */ + private ExcelCollectionParams getCollectionParams(List excelCollection, String collectionName) { + for (ExcelCollectionParams excelCollectionParams : excelCollection) { + if (collectionName.equals(excelCollectionParams.getExcelName())) { + return excelCollectionParams; + } + } + return null; + } + + /** + * Excel 导入 field 字段类型 Integer,Long,Double,Date,String,Boolean + * + * @param inputstream + * @param pojoClass + * @param params + * @return + * @throws Exception + */ + public ExcelImportResult importExcelByIs(InputStream inputstream, Class pojoClass, ImportParams params) throws Exception { + if (log.isDebugEnabled()) { + log.debug("Excel import start ,class is {}", pojoClass); + } + List result = new ArrayList(); + Workbook book = null; + boolean isXSSFWorkbook = true; + if (!(inputstream.markSupported())) { + inputstream = new PushbackInputStream(inputstream, 8); + } + if (POIFSFileSystem.hasPOIFSHeader(inputstream)) { + book = new HSSFWorkbook(inputstream); + isXSSFWorkbook = false; + } else if (POIXMLDocument.hasOOXMLHeader(inputstream)) { + book = new XSSFWorkbook(OPCPackage.open(inputstream)); + } + createErrorCellStyle(book); + Map pictures; + for (int i = 0; i < params.getSheetNum(); i++) { + if (log.isDebugEnabled()) { + log.debug(" start to read excel by is ,startTime is {}", new Date().getTime()); + } + if (isXSSFWorkbook) { + pictures = PoiPublicUtil.getSheetPictrues07((XSSFSheet) book.getSheetAt(i), (XSSFWorkbook) book); + } else { + pictures = PoiPublicUtil.getSheetPictrues03((HSSFSheet) book.getSheetAt(i), (HSSFWorkbook) book); + } + if (log.isDebugEnabled()) { + log.debug(" end to read excel by is ,endTime is {}", new Date().getTime()); + } + result.addAll(importExcel(result, book.getSheetAt(i), pojoClass, params, pictures)); + if (log.isDebugEnabled()) { + log.debug(" end to read excel list by pos ,endTime is {}", new Date().getTime()); + } + } + if (params.isNeedSave()) { + saveThisExcel(params, pojoClass, isXSSFWorkbook, book); + } + return new ExcelImportResult(result, verfiyFail, book); + } + + /** + * 保存字段值(获取值,校验值,追加错误信息) + * + * @param params + * @param object + * @param cell + * @param excelParams + * @param titleString + * @param row + * @throws Exception + */ + private void saveFieldValue(ImportParams params, Object object, Cell cell, Map excelParams, String titleString, Row row) throws Exception { + Object value = cellValueServer.getValue(params.getDataHanlder(), object, cell, excelParams, titleString); + if (object instanceof Map) { + if (params.getDataHanlder() != null) { + params.getDataHanlder().setMapValue((Map) object, titleString, value); + } else { + ((Map) object).put(titleString, value); + } + } else { + ExcelVerifyHanlderResult verifyResult = verifyHandlerServer.verifyData(object, value, titleString, excelParams.get(titleString).getVerify(), params.getVerifyHanlder()); + if (verifyResult.isSuccess()) { + setValues(excelParams.get(titleString), object, value); + } else { + Cell errorCell = row.createCell(row.getLastCellNum()); + errorCell.setCellValue(verifyResult.getMsg()); + errorCell.setCellStyle(errorCellStyle); + verfiyFail = true; + throw new ExcelImportException(ExcelImportEnum.VERIFY_ERROR); + } + } + } + + /** + * + * @param object + * @param picId + * @param excelParams + * @param titleString + * @param pictures + * @param params + * @throws Exception + */ + private void saveImage(Object object, String picId, Map excelParams, String titleString, Map pictures, ImportParams params) throws Exception { + if (pictures == null) { + return; + } + PictureData image = pictures.get(picId); + byte[] data = image.getData(); + String fileName = "pic" + Math.round(Math.random() * 100000000000L); + fileName += "." + PoiPublicUtil.getFileExtendName(data); + if (excelParams.get(titleString).getSaveType() == 1) { + String path = PoiPublicUtil.getWebRootPath(getSaveUrl(excelParams.get(titleString), object)); + File savefile = new File(path); + if (!savefile.exists()) { + savefile.mkdirs(); + } + savefile = new File(path + "/" + fileName); + FileOutputStream fos = new FileOutputStream(savefile); + fos.write(data); + fos.close(); + setValues(excelParams.get(titleString), object, getSaveUrl(excelParams.get(titleString), object) + "/" + fileName); + } else { + setValues(excelParams.get(titleString), object, data); + } + } + + private void createErrorCellStyle(Workbook workbook) { + errorCellStyle = workbook.createCellStyle(); + Font font = workbook.createFont(); + font.setColor(Font.COLOR_RED); + errorCellStyle.setFont(font); + } + +} diff --git a/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/imports/base/ImportBaseService.java b/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/imports/base/ImportBaseService.java new file mode 100644 index 000000000..48302e85e --- /dev/null +++ b/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/imports/base/ImportBaseService.java @@ -0,0 +1,282 @@ +package com.pig4cloud.pigx.common.poi.excel.imports.base; + +import java.io.File; +import java.io.FileOutputStream; +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.lang.reflect.ParameterizedType; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Date; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import com.baomidou.mybatisplus.core.toolkit.StringPool; +import com.pig4cloud.pigx.common.core.util.ApplicationContextUtil; +import com.pig4cloud.pigx.common.dict.service.AutoPoiDictServiceI; +import org.apache.commons.lang3.StringUtils; +import org.apache.poi.ss.usermodel.Workbook; +import com.pig4cloud.pigx.common.poi.excel.annotation.Excel; +import com.pig4cloud.pigx.common.poi.excel.annotation.ExcelCollection; +import com.pig4cloud.pigx.common.poi.excel.annotation.ExcelVerify; +import com.pig4cloud.pigx.common.poi.excel.entity.ImportParams; +import com.pig4cloud.pigx.common.poi.excel.entity.params.ExcelCollectionParams; +import com.pig4cloud.pigx.common.poi.excel.entity.params.ExcelImportEntity; +import com.pig4cloud.pigx.common.poi.excel.entity.params.ExcelVerifyEntity; +import com.pig4cloud.pigx.common.poi.util.PoiPublicUtil; + +/** + * @author: Luckly + * @date: 2019-05-20 + *

+ * 导入基础和,普通方法和Sax共用 + */ +public class ImportBaseService { + + /** + * 把这个注解解析放到类型对象中 + * + * @param targetId + * @param field + * @param excelEntity + * @param pojoClass + * @param getMethods + * @param temp + * @throws Exception + */ + public void addEntityToMap(String targetId, Field field, ExcelImportEntity excelEntity, Class pojoClass, List getMethods, Map temp) throws Exception { + Excel excel = field.getAnnotation(Excel.class); + excelEntity = new ExcelImportEntity(); + excelEntity.setType(excel.type()); + excelEntity.setSaveUrl(excel.savePath()); + excelEntity.setSaveType(excel.imageType()); + excelEntity.setReplace(excel.replace()); + excelEntity.setDatabaseFormat(excel.databaseFormat()); + excelEntity.setVerify(getImportVerify(field)); + excelEntity.setSuffix(excel.suffix()); + excelEntity.setMultiReplace(excel.multiReplace()); + if(StringUtils.isNotEmpty(excel.dicCode())){ + AutoPoiDictServiceI bossDictService = null; + try { + bossDictService = ApplicationContextUtil.getContext().getBean(AutoPoiDictServiceI.class); + } catch (Exception e) { + } + if(bossDictService!=null){ + String[] dictReplace = bossDictService.queryDict(excel.dictTable(), excel.dicCode(), excel.dicText()); + if(excelEntity.getReplace()!=null && dictReplace!=null && dictReplace.length!=0){ + excelEntity.setReplace(dictReplace); + } + } + } + getExcelField(targetId, field, excelEntity, excel, pojoClass); + if (getMethods != null) { + List newMethods = new ArrayList(); + newMethods.addAll(getMethods); + newMethods.add(excelEntity.getMethod()); + excelEntity.setMethods(newMethods); + } + temp.put(excelEntity.getName(), excelEntity); + + } + + /** + * 获取导入校验参数 + * + * @param field + * @return + */ + public ExcelVerifyEntity getImportVerify(Field field) { + ExcelVerify verify = field.getAnnotation(ExcelVerify.class); + if (verify != null) { + ExcelVerifyEntity entity = new ExcelVerifyEntity(); + entity.setEmail(verify.isEmail()); + entity.setInterHandler(verify.interHandler()); + entity.setMaxLength(verify.maxLength()); + entity.setMinLength(verify.minLength()); + entity.setMobile(verify.isMobile()); + entity.setNotNull(verify.notNull()); + entity.setRegex(verify.regex()); + entity.setRegexTip(verify.regexTip()); + entity.setTel(verify.isTel()); + return entity; + } + return null; + } + + /** + * 获取需要导出的全部字段 + * + * + * @param exclusions + * @param targetId + * 目标ID + * @param fields + * @param excelCollection + * @throws Exception + */ + public void getAllExcelField(String targetId, Field[] fields, Map excelParams, List excelCollection, Class pojoClass, List getMethods) throws Exception { + ExcelImportEntity excelEntity = null; + for (int i = 0; i < fields.length; i++) { + Field field = fields[i]; + if (PoiPublicUtil.isNotUserExcelUserThis(null, field, targetId)) { + continue; + } + if (PoiPublicUtil.isCollection(field.getType())) { + // 集合对象设置属性 + ExcelCollectionParams collection = new ExcelCollectionParams(); + collection.setName(field.getName()); + Map temp = new HashMap(); + ParameterizedType pt = (ParameterizedType) field.getGenericType(); + Class clz = (Class) pt.getActualTypeArguments()[0]; + collection.setType(clz); + getExcelFieldList(targetId, PoiPublicUtil.getClassFields(clz), clz, temp, null); + collection.setExcelParams(temp); + collection.setExcelName(field.getAnnotation(ExcelCollection.class).name()); + additionalCollectionName(collection); + excelCollection.add(collection); + } else if (PoiPublicUtil.isJavaClass(field)) { + addEntityToMap(targetId, field, excelEntity, pojoClass, getMethods, excelParams); + } else { + List newMethods = new ArrayList(); + if (getMethods != null) { + newMethods.addAll(getMethods); + } + newMethods.add(PoiPublicUtil.getMethod(field.getName(), pojoClass)); + getAllExcelField(targetId, PoiPublicUtil.getClassFields(field.getType()), excelParams, excelCollection, field.getType(), newMethods); + } + } + } + + /** + * 追加集合名称到前面 + * + * @param collection + */ + private void additionalCollectionName(ExcelCollectionParams collection) { + Set keys = new HashSet(); + keys.addAll(collection.getExcelParams().keySet()); + for (String key : keys) { + collection.getExcelParams().put(collection.getExcelName() + "_" + key, collection.getExcelParams().get(key)); + collection.getExcelParams().remove(key); + } + } + + public void getExcelField(String targetId, Field field, ExcelImportEntity excelEntity, Excel excel, Class pojoClass) throws Exception { + excelEntity.setName(getExcelName(excel.name(), targetId)); + String fieldname = field.getName(); + excelEntity.setMethod(PoiPublicUtil.getMethod(fieldname, pojoClass, field.getType(),excel.importConvert())); + if (StringUtils.isNotEmpty(excel.importFormat())) { + excelEntity.setFormat(excel.importFormat()); + } else { + excelEntity.setFormat(excel.format()); + } + } + + public void getExcelFieldList(String targetId, Field[] fields, Class pojoClass, Map temp, List getMethods) throws Exception { + ExcelImportEntity excelEntity = null; + for (int i = 0; i < fields.length; i++) { + Field field = fields[i]; + if (PoiPublicUtil.isNotUserExcelUserThis(null, field, targetId)) { + continue; + } + if (PoiPublicUtil.isJavaClass(field)) { + addEntityToMap(targetId, field, excelEntity, pojoClass, getMethods, temp); + } else { + List newMethods = new ArrayList(); + if (getMethods != null) { + newMethods.addAll(getMethods); + } + newMethods.add(PoiPublicUtil.getMethod(field.getName(), pojoClass, field.getType())); + getExcelFieldList(targetId, PoiPublicUtil.getClassFields(field.getType()), field.getType(), temp, newMethods); + } + } + } + + /** + * 判断在这个单元格显示的名称 + * + * @param exportName + * @param targetId + * @return + */ + public String getExcelName(String exportName, String targetId) { + if (exportName.indexOf("_") < 0) { + return exportName; + } + String[] arr = exportName.split(StringPool.COMMA); + for (String str : arr) { + if (str.indexOf(targetId) != -1) { + return str.split("_")[0]; + } + } + return null; + } + + public Object getFieldBySomeMethod(List list, Object t) throws Exception { + Method m; + for (int i = 0; i < list.size() - 1; i++) { + m = list.get(i); + t = m.invoke(t, new Object[] {}); + } + return t; + } + + public void saveThisExcel(ImportParams params, Class pojoClass, boolean isXSSFWorkbook, Workbook book) throws Exception { + String path = PoiPublicUtil.getWebRootPath(getSaveExcelUrl(params, pojoClass)); + File savefile = new File(path); + if (!savefile.exists()) { + savefile.mkdirs(); + } + SimpleDateFormat format = new SimpleDateFormat("yyyMMddHHmmss"); + FileOutputStream fos = new FileOutputStream(path + "/" + format.format(new Date()) + "_" + Math.round(Math.random() * 100000) + (isXSSFWorkbook == true ? ".xlsx" : ".xls")); + book.write(fos); + fos.close(); + } + + /** + * 获取保存的Excel 的真实路径 + * + * @param params + * @param pojoClass + * @return + * @throws Exception + */ + public String getSaveExcelUrl(ImportParams params, Class pojoClass) throws Exception { + String url = ""; + if (params.getSaveUrl().equals("upload/excelUpload")) { + url = pojoClass.getName().split("\\.")[pojoClass.getName().split("\\.").length - 1]; + return params.getSaveUrl() + "/" + url; + } + return params.getSaveUrl(); + } + + /** + * 多个get 最后再set + * + * @param setMethods + * @param object + */ + public void setFieldBySomeMethod(List setMethods, Object object, Object value) throws Exception { + Object t = getFieldBySomeMethod(setMethods, object); + setMethods.get(setMethods.size() - 1).invoke(t, value); + } + + /** + * + * @param entity + * @param object + * @param value + * @throws Exception + */ + public void setValues(ExcelImportEntity entity, Object object, Object value) throws Exception { + if (entity.getMethods() != null) { + setFieldBySomeMethod(entity.getMethods(), object, value); + } else { + entity.getMethod().invoke(object, value); + } + } + +} diff --git a/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/imports/package-info.java b/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/imports/package-info.java new file mode 100644 index 000000000..5bb26f96c --- /dev/null +++ b/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/imports/package-info.java @@ -0,0 +1,7 @@ +/** + * @author: Luckly + * @date: 2019-05-20 + *

+ * 导入类 + */ +package com.pig4cloud.pigx.common.poi.excel.imports; \ No newline at end of file diff --git a/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/imports/sax/SaxReadExcel.java b/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/imports/sax/SaxReadExcel.java new file mode 100644 index 000000000..e2ed74020 --- /dev/null +++ b/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/imports/sax/SaxReadExcel.java @@ -0,0 +1,75 @@ +package com.pig4cloud.pigx.common.poi.excel.imports.sax; + +import com.pig4cloud.pigx.common.poi.excel.entity.ImportParams; +import com.pig4cloud.pigx.common.poi.excel.imports.sax.parse.ISaxRowRead; +import com.pig4cloud.pigx.common.poi.excel.imports.sax.parse.SaxRowRead; +import com.pig4cloud.pigx.common.poi.exception.excel.ExcelImportException; +import com.pig4cloud.pigx.common.poi.handler.inter.IExcelReadRowHanlder; +import lombok.extern.slf4j.Slf4j; +import org.apache.poi.openxml4j.opc.OPCPackage; +import org.apache.poi.xssf.eventusermodel.XSSFReader; +import org.apache.poi.xssf.model.SharedStringsTable; +import org.xml.sax.ContentHandler; +import org.xml.sax.InputSource; +import org.xml.sax.SAXException; +import org.xml.sax.XMLReader; +import org.xml.sax.helpers.XMLReaderFactory; + +import java.io.InputStream; +import java.util.Iterator; +import java.util.List; + +/** + * + * @author: Luckly + * @date: 2019-05-20 + *

+ * 基于SAX Excel大数据读取,读取Excel 07版本,不支持图片读取 + */ +@Slf4j +@SuppressWarnings("rawtypes") +public class SaxReadExcel { + + + public List readExcel(InputStream inputstream, Class pojoClass, ImportParams params, ISaxRowRead rowRead, IExcelReadRowHanlder hanlder) { + try { + OPCPackage opcPackage = OPCPackage.open(inputstream); + return readExcel(opcPackage, pojoClass, params, rowRead, hanlder); + } catch (Exception e) { + log.error(e.getMessage(), e); + throw new ExcelImportException(e.getMessage()); + } + } + + private List readExcel(OPCPackage opcPackage, Class pojoClass, ImportParams params, ISaxRowRead rowRead, IExcelReadRowHanlder hanlder) { + try { + XSSFReader xssfReader = new XSSFReader(opcPackage); + SharedStringsTable sst = xssfReader.getSharedStringsTable(); + if (rowRead == null) { + rowRead = new SaxRowRead(pojoClass, params, hanlder); + } + XMLReader parser = fetchSheetParser(sst, rowRead); + Iterator sheets = xssfReader.getSheetsData(); + int sheetIndex = 0; + while (sheets.hasNext() && sheetIndex < params.getSheetNum()) { + sheetIndex++; + InputStream sheet = sheets.next(); + InputSource sheetSource = new InputSource(sheet); + parser.parse(sheetSource); + sheet.close(); + } + return rowRead.getList(); + } catch (Exception e) { + log.error(e.getMessage(), e); + throw new ExcelImportException("SAX导入数据失败"); + } + } + + private XMLReader fetchSheetParser(SharedStringsTable sst, ISaxRowRead rowRead) throws SAXException { + XMLReader parser = XMLReaderFactory.createXMLReader("org.apache.xerces.parsers.SAXParser"); + ContentHandler handler = new SheetHandler(sst, rowRead); + parser.setContentHandler(handler); + return parser; + } + +} diff --git a/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/imports/sax/SheetHandler.java b/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/imports/sax/SheetHandler.java new file mode 100644 index 000000000..f49cbac11 --- /dev/null +++ b/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/imports/sax/SheetHandler.java @@ -0,0 +1,122 @@ +package com.pig4cloud.pigx.common.poi.excel.imports.sax; + +import java.math.BigDecimal; +import java.util.Date; +import java.util.List; + +import org.apache.poi.hssf.usermodel.HSSFDateUtil; +import org.apache.poi.xssf.model.SharedStringsTable; +import org.apache.poi.xssf.usermodel.XSSFRichTextString; +import com.pig4cloud.pigx.common.poi.excel.entity.enmus.CellValueType; +import com.pig4cloud.pigx.common.poi.excel.entity.sax.SaxReadCellEntity; +import com.pig4cloud.pigx.common.poi.excel.imports.sax.parse.ISaxRowRead; +import org.xml.sax.Attributes; +import org.xml.sax.SAXException; +import org.xml.sax.helpers.DefaultHandler; + +import com.google.common.collect.Lists; + +/** + * + * @author: Luckly + * @date: 2019-05-20 + *

+ * 回调接口 + */ +public class SheetHandler extends DefaultHandler { + + private SharedStringsTable sst; + private String lastContents; + + // 当前行 + private int curRow = 0; + // 当前列 + private int curCol = 0; + + private CellValueType type; + + private ISaxRowRead read; + + // 存储行记录的容器 + private List rowlist = Lists.newArrayList(); + + public SheetHandler(SharedStringsTable sst, ISaxRowRead rowRead) { + this.sst = sst; + this.read = rowRead; + } + + @Override + public void startElement(String uri, String localName, String name, Attributes attributes) throws SAXException { + // 置空 + lastContents = ""; + // c => 单元格 + if ("c".equals(name)) { + // 如果下一个元素是 SST 的索引,则将nextIsString标记为true + String cellType = attributes.getValue("t"); + if ("s".equals(cellType)) { + type = CellValueType.String; + return; + } + // 日期格式 + cellType = attributes.getValue("s"); + if ("1".equals(cellType)) { + type = CellValueType.Date; + } else if ("2".equals(cellType)) { + type = CellValueType.Number; + } + } else if ("t".equals(name)) {// 当元素为t时 + type = CellValueType.TElement; + } + + } + + @Override + public void endElement(String uri, String localName, String name) throws SAXException { + + // 根据SST的索引值的到单元格的真正要存储的字符串 + // 这时characters()方法可能会被调用多次 + if (CellValueType.String.equals(type)) { + try { + int idx = Integer.parseInt(lastContents); + lastContents = new XSSFRichTextString(sst.getEntryAt(idx)).toString(); + } catch (Exception e) { + + } + } + // t元素也包含字符串 + if (CellValueType.TElement.equals(type)) { + String value = lastContents.trim(); + rowlist.add(curCol, new SaxReadCellEntity(CellValueType.String, value)); + curCol++; + type = CellValueType.None; + // v => 单元格的值,如果单元格是字符串则v标签的值为该字符串在SST中的索引 + // 将单元格内容加入rowlist中,在这之前先去掉字符串前后的空白符 + } else if ("v".equals(name)) { + String value = lastContents.trim(); + value = value.equals("") ? " " : value; + if (CellValueType.Date.equals(type)) { + Date date = HSSFDateUtil.getJavaDate(Double.valueOf(value)); + rowlist.add(curCol, new SaxReadCellEntity(CellValueType.Date, date)); + } else if (CellValueType.Number.equals(type)) { + BigDecimal bd = new BigDecimal(value); + rowlist.add(curCol, new SaxReadCellEntity(CellValueType.Number, bd)); + } else if (CellValueType.String.equals(type)) { + rowlist.add(curCol, new SaxReadCellEntity(CellValueType.String, value)); + } + curCol++; + } else if (name.equals("row")) {// 如果标签名称为 row ,这说明已到行尾,调用 optRows() 方法 + read.parse(curRow, rowlist); + rowlist.clear(); + curRow++; + curCol = 0; + } + + } + + @Override + public void characters(char[] ch, int start, int length) throws SAXException { + // 得到单元格内容的值 + lastContents += new String(ch, start, length); + } + +} diff --git a/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/imports/sax/parse/ISaxRowRead.java b/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/imports/sax/parse/ISaxRowRead.java new file mode 100644 index 000000000..2661e0c79 --- /dev/null +++ b/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/imports/sax/parse/ISaxRowRead.java @@ -0,0 +1,30 @@ +package com.pig4cloud.pigx.common.poi.excel.imports.sax.parse; + +import java.util.List; + +import com.pig4cloud.pigx.common.poi.excel.entity.sax.SaxReadCellEntity; + +/** + * + * @author: Luckly + * @date: 2019-05-20 + *

+ */ +public interface ISaxRowRead { + /** + * 获取返回数据 + * + * @param + * @return + */ + public List getList(); + + /** + * 解析数据 + * + * @param index + * @param datas + */ + public void parse(int index, List datas); + +} diff --git a/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/imports/sax/parse/SaxRowRead.java b/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/imports/sax/parse/SaxRowRead.java new file mode 100644 index 000000000..39d729890 --- /dev/null +++ b/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/imports/sax/parse/SaxRowRead.java @@ -0,0 +1,192 @@ +package com.pig4cloud.pigx.common.poi.excel.imports.sax.parse; + +import com.google.common.collect.Lists; +import com.pig4cloud.pigx.common.poi.excel.annotation.ExcelTarget; +import com.pig4cloud.pigx.common.poi.excel.entity.ImportParams; +import com.pig4cloud.pigx.common.poi.excel.entity.params.ExcelCollectionParams; +import com.pig4cloud.pigx.common.poi.excel.entity.params.ExcelImportEntity; +import com.pig4cloud.pigx.common.poi.excel.entity.sax.SaxReadCellEntity; +import com.pig4cloud.pigx.common.poi.excel.imports.CellValueServer; +import com.pig4cloud.pigx.common.poi.excel.imports.base.ImportBaseService; +import com.pig4cloud.pigx.common.poi.exception.excel.ExcelImportException; +import com.pig4cloud.pigx.common.poi.handler.inter.IExcelReadRowHanlder; +import com.pig4cloud.pigx.common.poi.util.PoiPublicUtil; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; + +import java.lang.reflect.Field; +import java.util.*; + +/** + * + * @author: Luckly + * @date: 2019-05-20 + *

+ * 当行读取数据 + */ +@Slf4j +@SuppressWarnings({ "rawtypes", "unchecked" }) +public class SaxRowRead extends ImportBaseService implements ISaxRowRead { + + /** 需要返回的数据 **/ + private List list; + /** 导出的对象 **/ + private Class pojoClass; + /** 导入参数 **/ + private ImportParams params; + /** 列表头对应关系 **/ + private Map titlemap = new HashMap(); + /** 当前的对象 **/ + private Object object = null; + + private Map excelParams = new HashMap(); + + private List excelCollection = new ArrayList(); + + private String targetId; + + private CellValueServer cellValueServer; + + private IExcelReadRowHanlder hanlder; + + public SaxRowRead(Class pojoClass, ImportParams params, IExcelReadRowHanlder hanlder) { + list = Lists.newArrayList(); + this.params = params; + this.pojoClass = pojoClass; + cellValueServer = new CellValueServer(); + this.hanlder = hanlder; + initParams(pojoClass, params); + } + + private void initParams(Class pojoClass, ImportParams params) { + try { + + Field fileds[] = PoiPublicUtil.getClassFields(pojoClass); + ExcelTarget etarget = pojoClass.getAnnotation(ExcelTarget.class); + if (etarget != null) { + targetId = etarget.value(); + } + getAllExcelField(targetId, fileds, excelParams, excelCollection, pojoClass, null); + } catch (Exception e) { + log.error(e.getMessage(), e); + throw new ExcelImportException(e.getMessage()); + } + + } + + @Override + public List getList() { + return list; + } + + @Override + public void parse(int index, List datas) { + try { + if (datas == null || datas.size() == 0) { + return; + } + // 标题行跳过 + if (index < params.getTitleRows()) { + return; + } + // 表头行 + if (index < params.getTitleRows() + params.getHeadRows()) { + addHeadData(datas); + } else { + addListData(datas); + } + } catch (Exception e) { + log.error(e.getMessage(), e); + throw new ExcelImportException(e.getMessage()); + } + } + + /** + * 集合元素处理 + * + * @param datas + */ + private void addListData(List datas) throws Exception { + // 判断是集合元素还是不是集合元素,如果是就继续加入这个集合,不是就创建新的对象 + if ((datas.get(params.getKeyIndex()) == null || StringUtils.isEmpty(String.valueOf(datas.get(params.getKeyIndex()).getValue()))) && object != null) { + for (ExcelCollectionParams param : excelCollection) { + addListContinue(object, param, datas, titlemap, targetId, params); + } + } else { + if (object != null && hanlder != null) { + hanlder.hanlder(object); + } + object = PoiPublicUtil.createObject(pojoClass, targetId); + SaxReadCellEntity entity; + for (int i = 0, le = datas.size(); i < le; i++) { + entity = datas.get(i); + String titleString = (String) titlemap.get(i); + if (excelParams.containsKey(titleString)) { + saveFieldValue(params, object, entity, excelParams, titleString); + } + } + for (ExcelCollectionParams param : excelCollection) { + addListContinue(object, param, datas, titlemap, targetId, params); + } + if (hanlder == null) { + list.add(object); + } + } + + } + + /*** + * 向List里面继续添加元素 + * + * @param exclusions + * @param object + * @param param + * @param datas + * @param titlemap + * @param targetId + * @param params + */ + private void addListContinue(Object object, ExcelCollectionParams param, List datas, Map titlemap, String targetId, ImportParams params) throws Exception { + Collection collection = (Collection) PoiPublicUtil.getMethod(param.getName(), object.getClass()).invoke(object, new Object[] {}); + Object entity = PoiPublicUtil.createObject(param.getType(), targetId); + boolean isUsed = false;// 是否需要加上这个对象 + for (int i = 0; i < datas.size(); i++) { + String titleString = (String) titlemap.get(i); + if (param.getExcelParams().containsKey(titleString)) { + saveFieldValue(params, entity, datas.get(i), param.getExcelParams(), titleString); + isUsed = true; + } + } + if (isUsed) { + collection.add(entity); + } + } + + /** + * 设置值 + * + * @param params + * @param object + * @param entity + * @param excelParams + * @param titleString + * @throws Exception + */ + private void saveFieldValue(ImportParams params, Object object, SaxReadCellEntity entity, Map excelParams, String titleString) throws Exception { + Object value = cellValueServer.getValue(params.getDataHanlder(), object, entity, excelParams, titleString); + setValues(excelParams.get(titleString), object, value); + } + + /** + * put 表头数据 + * + * @param datas + */ + private void addHeadData(List datas) { + for (int i = 0; i < datas.size(); i++) { + if (StringUtils.isNotEmpty(String.valueOf(datas.get(i).getValue()))) { + titlemap.put(i, String.valueOf(datas.get(i).getValue())); + } + } + } +} diff --git a/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/imports/verifys/BaseVerifyHandler.java b/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/imports/verifys/BaseVerifyHandler.java new file mode 100644 index 000000000..10e3bcc2d --- /dev/null +++ b/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/imports/verifys/BaseVerifyHandler.java @@ -0,0 +1,131 @@ +package com.pig4cloud.pigx.common.poi.excel.imports.verifys; + +import java.util.regex.Pattern; + +import com.pig4cloud.pigx.common.poi.excel.entity.result.ExcelVerifyHanlderResult; + +/** + * + * @author: Luckly + * @date: 2019-05-20 + *

+ * 基础校验工具类 + */ +public class BaseVerifyHandler { + + private static String NOT_NULL = "不允许为空"; + private static String IS_MOBILE = "不是手机号"; + private static String IS_TEL = "不是电话号码"; + private static String IS_EMAIL = "不是邮箱地址"; + private static String MIN_LENGHT = "小于规定长度"; + private static String MAX_LENGHT = "超过规定长度"; + + private static Pattern mobilePattern = Pattern.compile("^[1][3,4,5,8,7][0-9]{9}$"); + + private static Pattern telPattern = Pattern.compile("^([0][1-9]{2,3}-)?[0-9]{5,10}$"); + + private static Pattern emailPattern = Pattern.compile("^([a-zA-Z0-9]+[_|\\_|\\.]?)*[a-zA-Z0-9]+@([a-zA-Z0-9]+[_|\\_|\\.]?)*[a-zA-Z0-9]+\\.[a-zA-Z]{2,3}$"); + + /** + * email校验 + * + * @param name + * @param val + * @return + */ + public static ExcelVerifyHanlderResult isEmail(String name, Object val) { + if (!emailPattern.matcher(String.valueOf(val)).matches()) { + return new ExcelVerifyHanlderResult(false, name + IS_EMAIL); + } + return new ExcelVerifyHanlderResult(true); + } + + /** + * 手机校验 + * + * @param name + * @param val + * @return + */ + public static ExcelVerifyHanlderResult isMobile(String name, Object val) { + if (!mobilePattern.matcher(String.valueOf(val)).matches()) { + return new ExcelVerifyHanlderResult(false, name + IS_MOBILE); + } + return new ExcelVerifyHanlderResult(true); + } + + /** + * 电话校验 + * + * @param name + * @param val + * @return + */ + public static ExcelVerifyHanlderResult isTel(String name, Object val) { + if (!telPattern.matcher(String.valueOf(val)).matches()) { + return new ExcelVerifyHanlderResult(false, name + IS_TEL); + } + return new ExcelVerifyHanlderResult(true); + } + + /** + * 最大长度校验 + * + * @param name + * @param val + * @return + */ + public static ExcelVerifyHanlderResult maxLength(String name, Object val, int maxLength) { + if (notNull(name, val).isSuccess() && String.valueOf(val).length() > maxLength) { + return new ExcelVerifyHanlderResult(false, name + MAX_LENGHT); + } + return new ExcelVerifyHanlderResult(true); + } + + /** + * 最小长度校验 + * + * @param name + * @param val + * @param minLength + * @return + */ + public static ExcelVerifyHanlderResult minLength(String name, Object val, int minLength) { + if (notNull(name, val).isSuccess() && String.valueOf(val).length() < minLength) { + return new ExcelVerifyHanlderResult(false, name + MIN_LENGHT); + } + return new ExcelVerifyHanlderResult(true); + } + + /** + * 非空校验 + * + * @param name + * @param val + * @return + */ + public static ExcelVerifyHanlderResult notNull(String name, Object val) { + if (val == null || val.toString().equals("")) { + return new ExcelVerifyHanlderResult(false, name + NOT_NULL); + } + return new ExcelVerifyHanlderResult(true); + } + + /** + * 正则表达式校验 + * + * @param name + * @param val + * @param regex + * @param regexTip + * @return + */ + public static ExcelVerifyHanlderResult regex(String name, Object val, String regex, String regexTip) { + Pattern pattern = Pattern.compile(regex); + if (!pattern.matcher(String.valueOf(val)).matches()) { + return new ExcelVerifyHanlderResult(false, name + regexTip); + } + return new ExcelVerifyHanlderResult(true); + } + +} diff --git a/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/imports/verifys/VerifyHandlerServer.java b/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/imports/verifys/VerifyHandlerServer.java new file mode 100644 index 000000000..920c18dad --- /dev/null +++ b/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/imports/verifys/VerifyHandlerServer.java @@ -0,0 +1,68 @@ +package com.pig4cloud.pigx.common.poi.excel.imports.verifys; + +import org.apache.commons.lang3.StringUtils; +import com.pig4cloud.pigx.common.poi.excel.entity.params.ExcelVerifyEntity; +import com.pig4cloud.pigx.common.poi.excel.entity.result.ExcelVerifyHanlderResult; +import com.pig4cloud.pigx.common.poi.handler.inter.IExcelVerifyHandler; + +/** + * + * @author: Luckly + * @date: 2019-05-20 + *

+ * 校验服务 + */ +public class VerifyHandlerServer { + + private final static ExcelVerifyHanlderResult DEFAULT_RESULT = new ExcelVerifyHanlderResult(true); + + private void addVerifyResult(ExcelVerifyHanlderResult hanlderResult, ExcelVerifyHanlderResult result) { + if (!hanlderResult.isSuccess()) { + result.setSuccess(false); + result.setMsg((StringUtils.isEmpty(result.getMsg()) ? "" : result.getMsg() + " , ") + hanlderResult.getMsg()); + } + } + + /** + * 校验数据 + * + * @param object + * @param value + * @param name + * @param verify + * @param excelVerifyHandler + * @return + */ + public ExcelVerifyHanlderResult verifyData(Object object, Object value, String name, ExcelVerifyEntity verify, IExcelVerifyHandler excelVerifyHandler) { + if (verify == null) { + return DEFAULT_RESULT; + } + ExcelVerifyHanlderResult result = new ExcelVerifyHanlderResult(true, ""); + if (verify.isNotNull()) { + addVerifyResult(BaseVerifyHandler.notNull(name, value), result); + } + if (verify.isEmail()) { + addVerifyResult(BaseVerifyHandler.isEmail(name, value), result); + } + if (verify.isMobile()) { + addVerifyResult(BaseVerifyHandler.isMobile(name, value), result); + } + if (verify.isTel()) { + addVerifyResult(BaseVerifyHandler.isTel(name, value), result); + } + if (verify.getMaxLength() != -1) { + addVerifyResult(BaseVerifyHandler.maxLength(name, value, verify.getMaxLength()), result); + } + if (verify.getMinLength() != -1) { + addVerifyResult(BaseVerifyHandler.minLength(name, value, verify.getMinLength()), result); + } + if (StringUtils.isNotEmpty(verify.getRegex())) { + addVerifyResult(BaseVerifyHandler.regex(name, value, verify.getRegex(), verify.getRegexTip()), result); + } + if (verify.isInterHandler()) { + addVerifyResult(excelVerifyHandler.verifyHandler(object, name, value), result); + } + return result; + + } +} diff --git a/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/view/MiniAbstractExcelView.java b/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/view/MiniAbstractExcelView.java new file mode 100644 index 000000000..7d597f09f --- /dev/null +++ b/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/view/MiniAbstractExcelView.java @@ -0,0 +1,29 @@ +package com.pig4cloud.pigx.common.poi.excel.view; + +import javax.servlet.http.HttpServletRequest; + +import org.springframework.web.servlet.view.AbstractView; + +/** + * 基础抽象Excel View + * + * @author: Luckly + * @date: 2019-05-20 + *

+ */ +public abstract class MiniAbstractExcelView extends AbstractView { + + private static final String CONTENT_TYPE = "application/vnd.ms-excel"; + + protected static final String HSSF = ".xls"; + protected static final String XSSF = ".xlsx"; + + public MiniAbstractExcelView() { + setContentType(CONTENT_TYPE); + } + + protected boolean isIE(HttpServletRequest request) { + return (request.getHeader("USER-AGENT").toLowerCase().indexOf("msie") > 0 || request.getHeader("USER-AGENT").toLowerCase().indexOf("rv:11.0") > 0) ? true : false; + } + +} diff --git a/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/view/PigxEntityExcelView.java b/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/view/PigxEntityExcelView.java new file mode 100644 index 000000000..4822de5ec --- /dev/null +++ b/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/view/PigxEntityExcelView.java @@ -0,0 +1,68 @@ +package com.pig4cloud.pigx.common.poi.excel.view; + +import java.util.Collection; +import java.util.List; +import java.util.Map; + +import javax.servlet.ServletOutputStream; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.apache.poi.hssf.usermodel.HSSFWorkbook; +import org.apache.poi.ss.usermodel.Workbook; +import com.pig4cloud.pigx.common.poi.excel.ExcelExportUtil; +import com.pig4cloud.pigx.common.poi.excel.def.NormalExcelConstants; +import com.pig4cloud.pigx.common.poi.excel.entity.ExportParams; +import com.pig4cloud.pigx.common.poi.excel.export.ExcelExportServer; +import org.springframework.stereotype.Controller; + +/** + * Entity 实体数据对象导出 + * @author: Luckly + * @date: 2019-05-20 + *

+ * + */ +@SuppressWarnings("unchecked") +@Controller(NormalExcelConstants.PIGX_ENTITY_EXCEL_VIEW) +public class PigxEntityExcelView extends MiniAbstractExcelView { + + public PigxEntityExcelView() { + super(); + } + + @Override + protected void renderMergedOutputModel(Map model, HttpServletRequest request, HttpServletResponse response) throws Exception { + String codedFileName = "临时文件"; + Workbook workbook = null; + if (model.containsKey(NormalExcelConstants.MAP_LIST)) { + List> list = (List>) model.get(NormalExcelConstants.MAP_LIST); + if (list.size() == 0) { + throw new RuntimeException("MAP_LIST IS NULL"); + } + workbook = ExcelExportUtil.exportExcel((ExportParams) list.get(0).get(NormalExcelConstants.PARAMS), (Class) list.get(0).get(NormalExcelConstants.CLASS), (Collection) list.get(0).get(NormalExcelConstants.DATA_LIST)); + for (int i = 1; i < list.size(); i++) { + new ExcelExportServer().createSheet(workbook, (ExportParams) list.get(i).get(NormalExcelConstants.PARAMS), (Class) list.get(i).get(NormalExcelConstants.CLASS), (Collection) list.get(i).get(NormalExcelConstants.DATA_LIST)); + } + } else { + workbook = ExcelExportUtil.exportExcel((ExportParams) model.get(NormalExcelConstants.PARAMS), (Class) model.get(NormalExcelConstants.CLASS), (Collection) model.get(NormalExcelConstants.DATA_LIST)); + } + if (model.containsKey(NormalExcelConstants.FILE_NAME)) { + codedFileName = (String) model.get(NormalExcelConstants.FILE_NAME); + } + if (workbook instanceof HSSFWorkbook) { + codedFileName += HSSF; + } else { + codedFileName += XSSF; + } + if (isIE(request)) { + codedFileName = java.net.URLEncoder.encode(codedFileName, "UTF8"); + } else { + codedFileName = new String(codedFileName.getBytes("UTF-8"), "ISO-8859-1"); + } + response.setHeader("content-disposition", "attachment;filename=" + codedFileName); + ServletOutputStream out = response.getOutputStream(); + workbook.write(out); + out.flush(); + } +} diff --git a/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/view/PigxMapExcelView.java b/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/view/PigxMapExcelView.java new file mode 100644 index 000000000..2fcdce232 --- /dev/null +++ b/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/view/PigxMapExcelView.java @@ -0,0 +1,57 @@ +package com.pig4cloud.pigx.common.poi.excel.view; + +import java.util.Collection; +import java.util.List; +import java.util.Map; + +import javax.servlet.ServletOutputStream; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.apache.poi.hssf.usermodel.HSSFWorkbook; +import org.apache.poi.ss.usermodel.Workbook; +import com.pig4cloud.pigx.common.poi.excel.ExcelExportUtil; +import com.pig4cloud.pigx.common.poi.excel.def.MapExcelConstants; +import com.pig4cloud.pigx.common.poi.excel.entity.ExportParams; +import com.pig4cloud.pigx.common.poi.excel.entity.params.ExcelExportEntity; +import org.springframework.stereotype.Controller; + +/** + * Map 数据对象接口导出 + * + * @author: Luckly + * @date: 2019-05-20 + *

+ */ +@SuppressWarnings("unchecked") +@Controller(MapExcelConstants.PIGX_MAP_EXCEL_VIEW) +public class PigxMapExcelView extends MiniAbstractExcelView { + + public PigxMapExcelView() { + super(); + } + + @Override + protected void renderMergedOutputModel(Map model, HttpServletRequest request, HttpServletResponse response) throws Exception { + String codedFileName = "临时文件"; + Workbook workbook = ExcelExportUtil.exportExcel((ExportParams) model.get(MapExcelConstants.PARAMS), (List) model.get(MapExcelConstants.ENTITY_LIST), (Collection>) model.get(MapExcelConstants.MAP_LIST)); + if (model.containsKey(MapExcelConstants.FILE_NAME)) { + codedFileName = (String) model.get(MapExcelConstants.FILE_NAME); + } + if (workbook instanceof HSSFWorkbook) { + codedFileName += HSSF; + } else { + codedFileName += XSSF; + } + if (isIE(request)) { + codedFileName = java.net.URLEncoder.encode(codedFileName, "UTF8"); + } else { + codedFileName = new String(codedFileName.getBytes("UTF-8"), "ISO-8859-1"); + } + response.setHeader("content-disposition", "attachment;filename=" + codedFileName); + ServletOutputStream out = response.getOutputStream(); + workbook.write(out); + out.flush(); + } + +} diff --git a/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/view/PigxTemplateExcelView.java b/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/view/PigxTemplateExcelView.java new file mode 100644 index 000000000..c8af95e02 --- /dev/null +++ b/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/view/PigxTemplateExcelView.java @@ -0,0 +1,55 @@ +package com.pig4cloud.pigx.common.poi.excel.view; + +import java.util.List; +import java.util.Map; + +import javax.servlet.ServletOutputStream; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.apache.poi.hssf.usermodel.HSSFWorkbook; +import org.apache.poi.ss.usermodel.Workbook; +import com.pig4cloud.pigx.common.poi.excel.ExcelExportUtil; +import com.pig4cloud.pigx.common.poi.excel.def.NormalExcelConstants; +import com.pig4cloud.pigx.common.poi.excel.def.TemplateExcelConstants; +import com.pig4cloud.pigx.common.poi.excel.entity.TemplateExportParams; +import org.springframework.stereotype.Controller; + +/** + * Excel 模板导出 + * + * @author: Luckly + * @date: 2019-05-20 + *

+ */ +@SuppressWarnings("unchecked") +@Controller(TemplateExcelConstants.PIGX_TEMPLATE_EXCEL_VIEW) +public class PigxTemplateExcelView extends MiniAbstractExcelView { + + public PigxTemplateExcelView() { + super(); + } + + @Override + protected void renderMergedOutputModel(Map model, HttpServletRequest request, HttpServletResponse response) throws Exception { + String codedFileName = "临时文件"; + Workbook workbook = ExcelExportUtil.exportExcel((TemplateExportParams) model.get(TemplateExcelConstants.PARAMS), (Class) model.get(TemplateExcelConstants.CLASS), (List) model.get(TemplateExcelConstants.LIST_DATA), (Map) model.get(TemplateExcelConstants.MAP_DATA)); + if (model.containsKey(NormalExcelConstants.FILE_NAME)) { + codedFileName = (String) model.get(NormalExcelConstants.FILE_NAME); + } + if (workbook instanceof HSSFWorkbook) { + codedFileName += HSSF; + } else { + codedFileName += XSSF; + } + if (isIE(request)) { + codedFileName = java.net.URLEncoder.encode(codedFileName, "UTF8"); + } else { + codedFileName = new String(codedFileName.getBytes("UTF-8"), "ISO-8859-1"); + } + response.setHeader("content-disposition", "attachment;filename=" + codedFileName); + ServletOutputStream out = response.getOutputStream(); + workbook.write(out); + out.flush(); + } +} diff --git a/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/view/PigxTemplateWordView.java b/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/view/PigxTemplateWordView.java new file mode 100644 index 000000000..fd8a28622 --- /dev/null +++ b/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/excel/view/PigxTemplateWordView.java @@ -0,0 +1,53 @@ +package com.pig4cloud.pigx.common.poi.excel.view; + +import java.util.Map; + +import javax.servlet.ServletOutputStream; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.apache.poi.xwpf.usermodel.XWPFDocument; +import com.pig4cloud.pigx.common.poi.excel.def.TemplateWordConstants; +import com.pig4cloud.pigx.common.poi.word.WordExportUtil; +import org.springframework.stereotype.Controller; +import org.springframework.web.servlet.view.AbstractView; + +/** + * Word模板导出 + * + * @author: Luckly + * @date: 2019-05-20 + *

+ */ +@SuppressWarnings("unchecked") +@Controller(TemplateWordConstants.PIGX_TEMPLATE_WORD_VIEW) +public class PigxTemplateWordView extends AbstractView { + + private static final String CONTENT_TYPE = "application/msword"; + + public PigxTemplateWordView() { + setContentType(CONTENT_TYPE); + } + + public boolean isIE(HttpServletRequest request) { + return (request.getHeader("USER-AGENT").toLowerCase().indexOf("msie") > 0 || request.getHeader("USER-AGENT").toLowerCase().indexOf("rv:11.0") > 0) ? true : false; + } + + @Override + protected void renderMergedOutputModel(Map model, HttpServletRequest request, HttpServletResponse response) throws Exception { + String codedFileName = "临时文件.docx"; + if (model.containsKey(TemplateWordConstants.FILE_NAME)) { + codedFileName = (String) model.get(TemplateWordConstants.FILE_NAME) + ".docx"; + } + if (isIE(request)) { + codedFileName = java.net.URLEncoder.encode(codedFileName, "UTF8"); + } else { + codedFileName = new String(codedFileName.getBytes("UTF-8"), "ISO-8859-1"); + } + response.setHeader("content-disposition", "attachment;filename=" + codedFileName); + XWPFDocument document = WordExportUtil.exportWord07((String) model.get(TemplateWordConstants.URL), (Map) model.get(TemplateWordConstants.MAP_DATA)); + ServletOutputStream out = response.getOutputStream(); + document.write(out); + out.flush(); + } +} diff --git a/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/exception/excel/ExcelExportException.java b/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/exception/excel/ExcelExportException.java new file mode 100644 index 000000000..f861321a8 --- /dev/null +++ b/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/exception/excel/ExcelExportException.java @@ -0,0 +1,48 @@ +package com.pig4cloud.pigx.common.poi.exception.excel; + +import com.pig4cloud.pigx.common.poi.exception.excel.enums.ExcelExportEnum; + +/** + * 导出异常 + * + * @author: Luckly + * @date: 2019-05-20 + *

+ */ +public class ExcelExportException extends RuntimeException { + + private static final long serialVersionUID = 1L; + + private ExcelExportEnum type; + + public ExcelExportException() { + super(); + } + + public ExcelExportException(ExcelExportEnum type) { + super(type.getMsg()); + this.type = type; + } + + public ExcelExportException(ExcelExportEnum type, Throwable cause) { + super(type.getMsg(), cause); + } + + public ExcelExportException(String message) { + super(message); + } + + public ExcelExportException(String message, ExcelExportEnum type) { + super(message); + this.type = type; + } + + public ExcelExportEnum getType() { + return type; + } + + public void setType(ExcelExportEnum type) { + this.type = type; + } + +} diff --git a/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/exception/excel/ExcelImportException.java b/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/exception/excel/ExcelImportException.java new file mode 100644 index 000000000..64579f0da --- /dev/null +++ b/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/exception/excel/ExcelImportException.java @@ -0,0 +1,48 @@ +package com.pig4cloud.pigx.common.poi.exception.excel; + +import com.pig4cloud.pigx.common.poi.exception.excel.enums.ExcelImportEnum; + +/** + * 导入异常 + * + * @author: Luckly + * @date: 2019-05-20 + *

+ */ +public class ExcelImportException extends RuntimeException { + + private static final long serialVersionUID = 1L; + + private ExcelImportEnum type; + + public ExcelImportException() { + super(); + } + + public ExcelImportException(ExcelImportEnum type) { + super(type.getMsg()); + this.type = type; + } + + public ExcelImportException(ExcelImportEnum type, Throwable cause) { + super(type.getMsg(), cause); + } + + public ExcelImportException(String message) { + super(message); + } + + public ExcelImportException(String message, ExcelImportEnum type) { + super(message); + this.type = type; + } + + public ExcelImportEnum getType() { + return type; + } + + public void setType(ExcelImportEnum type) { + this.type = type; + } + +} diff --git a/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/exception/excel/enums/ExcelExportEnum.java b/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/exception/excel/enums/ExcelExportEnum.java new file mode 100644 index 000000000..25037d030 --- /dev/null +++ b/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/exception/excel/enums/ExcelExportEnum.java @@ -0,0 +1,29 @@ +package com.pig4cloud.pigx.common.poi.exception.excel.enums; + +/** + * 导出异常类型枚举 + * + * @author: Luckly + * @date: 2019-05-20 + *

+ */ +public enum ExcelExportEnum { + + PARAMETER_ERROR("Excel导出参数错误"), + EXPORT_ERROR("Excel导出错误"); + + private String msg; + + ExcelExportEnum(String msg) { + this.msg = msg; + } + + public String getMsg() { + return msg; + } + + public void setMsg(String msg) { + this.msg = msg; + } + +} diff --git a/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/exception/excel/enums/ExcelImportEnum.java b/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/exception/excel/enums/ExcelImportEnum.java new file mode 100644 index 000000000..6470d155e --- /dev/null +++ b/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/exception/excel/enums/ExcelImportEnum.java @@ -0,0 +1,29 @@ +package com.pig4cloud.pigx.common.poi.exception.excel.enums; + +/** + * 导出异常类型枚举 + * + * @author: Luckly + * @date: 2019-05-20 + *

+ */ +public enum ExcelImportEnum { + + GET_VALUE_ERROR("Excel值获取失败"), + VERIFY_ERROR("值校验失败"); + + private String msg; + + ExcelImportEnum(String msg) { + this.msg = msg; + } + + public String getMsg() { + return msg; + } + + public void setMsg(String msg) { + this.msg = msg; + } + +} diff --git a/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/exception/word/WordExportException.java b/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/exception/word/WordExportException.java new file mode 100644 index 000000000..6b726985c --- /dev/null +++ b/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/exception/word/WordExportException.java @@ -0,0 +1,28 @@ +package com.pig4cloud.pigx.common.poi.exception.word; + +import com.pig4cloud.pigx.common.poi.exception.word.enmus.WordExportEnum; + +/** + * word导出异常 + * + * @author: Luckly + * @date: 2019-05-20 + *

+ */ +public class WordExportException extends RuntimeException { + + private static final long serialVersionUID = 1L; + + public WordExportException() { + super(); + } + + public WordExportException(String msg) { + super(msg); + } + + public WordExportException(WordExportEnum exception) { + super(exception.getMsg()); + } + +} diff --git a/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/exception/word/enmus/WordExportEnum.java b/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/exception/word/enmus/WordExportEnum.java new file mode 100644 index 000000000..67733ae1b --- /dev/null +++ b/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/exception/word/enmus/WordExportEnum.java @@ -0,0 +1,30 @@ +package com.pig4cloud.pigx.common.poi.exception.word.enmus; + +/** + * 导出异常枚举 + * + * @author: Luckly + * @date: 2019-05-20 + *

+ */ +public enum WordExportEnum { + + EXCEL_PARAMS_ERROR("Excel导出参数错误"), + EXCEL_HEAD_HAVA_NULL("Excel表头有的字段为空"), + EXCEL_NO_HEAD("Excel没有表头"); + + private String msg; + + WordExportEnum(String msg) { + this.msg = msg; + } + + public String getMsg() { + return msg; + } + + public void setMsg(String msg) { + this.msg = msg; + } + +} diff --git a/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/handler/impl/ExcelDataHandlerDefaultImpl.java b/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/handler/impl/ExcelDataHandlerDefaultImpl.java new file mode 100644 index 000000000..76b29d14c --- /dev/null +++ b/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/handler/impl/ExcelDataHandlerDefaultImpl.java @@ -0,0 +1,45 @@ +package com.pig4cloud.pigx.common.poi.handler.impl; + +import com.pig4cloud.pigx.common.poi.handler.inter.IExcelDataHandler; + +import java.util.Map; + +/** + * 数据处理默认实现,返回空 + * + * @author: Luckly + * @date: 2019-05-20 + *

+ */ +public abstract class ExcelDataHandlerDefaultImpl implements IExcelDataHandler { + /** + * 需要处理的字段 + */ + private String[] needHandlerFields; + + @Override + public Object exportHandler(Object obj, String name, Object value) { + return value; + } + + @Override + public String[] getNeedHandlerFields() { + return needHandlerFields; + } + + @Override + public Object importHandler(Object obj, String name, Object value) { + return value; + } + + @Override + public void setNeedHandlerFields(String[] needHandlerFields) { + this.needHandlerFields = needHandlerFields; + } + + @Override + public void setMapValue(Map map, String originKey, Object value) { + map.put(originKey, value); + } + +} diff --git a/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/handler/impl/package-info.java b/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/handler/impl/package-info.java new file mode 100644 index 000000000..3233699db --- /dev/null +++ b/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/handler/impl/package-info.java @@ -0,0 +1,7 @@ +/** + * @author: Luckly + * @date: 2019-05-20 + *

+ * 对接口的抽象的默认实现,避免用户实现过多方法 + */ +package com.pig4cloud.pigx.common.poi.handler.impl; \ No newline at end of file diff --git a/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/handler/inter/IExcelDataHandler.java b/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/handler/inter/IExcelDataHandler.java new file mode 100644 index 000000000..7ad2eda3f --- /dev/null +++ b/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/handler/inter/IExcelDataHandler.java @@ -0,0 +1,57 @@ +package com.pig4cloud.pigx.common.poi.handler.inter; + +import java.util.Map; + +/** + * Excel 导入导出 数据处理接口 + * + * @author: Luckly + * @date: 2019-05-20 + *

+ */ +public interface IExcelDataHandler { + + /** + * 导出处理方法 + * + * @param obj 当前对象 + * @param name 当前字段名称 + * @param value 当前值 + * @return + */ + Object exportHandler(Object obj, String name, Object value); + + /** + * 获取需要处理的字段,导入和导出统一处理了, 减少书写的字段 + * + * @return + */ + String[] getNeedHandlerFields(); + + /** + * 导入处理方法 当前对象,当前字段名称,当前值 + * + * @param obj 当前对象 + * @param name 当前字段名称 + * @param value 当前值 + * @return + */ + Object importHandler(Object obj, String name, Object value); + + /** + * 设置需要处理的属性列表 + * + * @param fields + */ + void setNeedHandlerFields(String[] fields); + + /** + * 设置Map导入,自定义 put + * + * @param map + * @param originKey + * @param value + */ + void setMapValue(Map map, String originKey, Object value); + +} diff --git a/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/handler/inter/IExcelReadRowHanlder.java b/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/handler/inter/IExcelReadRowHanlder.java new file mode 100644 index 000000000..2c48dbce8 --- /dev/null +++ b/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/handler/inter/IExcelReadRowHanlder.java @@ -0,0 +1,18 @@ +package com.pig4cloud.pigx.common.poi.handler.inter; + +/** + * 接口自定义处理类 + * + * @author: Luckly + * @date: 2019-05-20 + *

+ */ +public interface IExcelReadRowHanlder { + /** + * 处理解析对象 + * + * @param t + */ + void hanlder(T t); + +} diff --git a/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/handler/inter/IExcelVerifyHandler.java b/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/handler/inter/IExcelVerifyHandler.java new file mode 100644 index 000000000..edd5469dc --- /dev/null +++ b/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/handler/inter/IExcelVerifyHandler.java @@ -0,0 +1,38 @@ +package com.pig4cloud.pigx.common.poi.handler.inter; + +import com.pig4cloud.pigx.common.poi.excel.entity.result.ExcelVerifyHanlderResult; + +/** + * 导入校验接口 + * + * @author: Luckly + * @date: 2019-05-20 + *

+ */ +public interface IExcelVerifyHandler { + + /** + * 获取需要处理的字段,导入和导出统一处理了, 减少书写的字段 + * + * @return + */ + String[] getNeedVerifyFields(); + + /** + * 获取需要处理的字段,导入和导出统一处理了, 减少书写的字段 + * + * @return + */ + void setNeedVerifyFields(String[] arr); + + /** + * 导出处理方法 + * + * @param obj 当前对象 + * @param name 当前字段名称 + * @param value 当前值 + * @return + */ + ExcelVerifyHanlderResult verifyHandler(Object obj, String name, Object value); + +} diff --git a/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/handler/package-info.java b/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/handler/package-info.java new file mode 100644 index 000000000..0733cc0b3 --- /dev/null +++ b/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/handler/package-info.java @@ -0,0 +1,7 @@ +/** + * 数据处理中心,对导入导出进行数据处理 + * @author: Luckly + * @date: 2019-05-20 + *

+ */ +package com.pig4cloud.pigx.common.poi.handler; \ No newline at end of file diff --git a/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/package-info.java b/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/package-info.java new file mode 100644 index 000000000..2b0b98870 --- /dev/null +++ b/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/package-info.java @@ -0,0 +1,13 @@ +/** + * @author: Luckly + * @date: 2019-05-20 + *

+ * 对POI进行封装,通过注解的使用,完成POI的简易重复操作 + * 通过模板完成较为复杂的操作 + * 进阶步骤:
+ *

1.了解注解,图片类

+ *

2.模板语言

+ *

3.模板组合

+ * + */ +package com.pig4cloud.pigx.common.poi; \ No newline at end of file diff --git a/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/util/ExcelUtil.java b/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/util/ExcelUtil.java new file mode 100644 index 000000000..2c65b80fa --- /dev/null +++ b/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/util/ExcelUtil.java @@ -0,0 +1,292 @@ +package com.pig4cloud.pigx.common.poi.util; +/** + * @author: Luckly + * @date: 2019-05-20 + *

+ * POI对EXCEL操作工具 + */ + +import org.apache.poi.hssf.usermodel.HSSFCell; +import org.apache.poi.hssf.usermodel.HSSFWorkbook; +import org.apache.poi.openxml4j.exceptions.InvalidFormatException; +import org.apache.poi.ss.usermodel.*; +import org.apache.poi.ss.util.CellRangeAddress; +import org.apache.poi.xssf.usermodel.XSSFWorkbook; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; + +public class ExcelUtil { + + public static void main(String[] args) { + //读取excel数据 + ArrayList> result = ExcelUtil.readExcelToObj("D:\\上传表.xlsx"); + for (Map map : result) { + System.out.println(map); + } + + } + + /** + * 读取excel数据 + * + * @param path + */ + public static ArrayList> readExcelToObj(String path) { + + Workbook wb = null; + ArrayList> result = null; + try { + wb = WorkbookFactory.create(new File(path)); + result = readExcel(wb, 0, 2, 0); + } catch (InvalidFormatException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } + return result; + } + + /** + * 读取excel文件 + * + * @param wb + * @param sheetIndex sheet页下标:从0开始 + * @param startReadLine 开始读取的行:从0开始 + * @param tailLine 去除最后读取的行 + */ + public static ArrayList> readExcel(Workbook wb, int sheetIndex, int startReadLine, int tailLine) { + Sheet sheet = wb.getSheetAt(sheetIndex); + Row row = null; + ArrayList> result = new ArrayList>(); + for (int i = startReadLine; i < sheet.getLastRowNum() - tailLine + 1; i++) { + + row = sheet.getRow(i); + Map map = new HashMap(); + for (Cell c : row) { + String returnStr = ""; + + boolean isMerge = isMergedRegion(sheet, i, c.getColumnIndex()); + //判断是否具有合并单元格 + if (isMerge) { + String rs = getMergedRegionValue(sheet, row.getRowNum(), c.getColumnIndex()); + returnStr = rs; + } else { + returnStr = c.getRichStringCellValue().getString(); + } + if (c.getColumnIndex() == 0) { + map.put("id", returnStr); + } else if (c.getColumnIndex() == 1) { + map.put("base", returnStr); + } else if (c.getColumnIndex() == 2) { + map.put("siteName", returnStr); + } else if (c.getColumnIndex() == 3) { + map.put("articleName", returnStr); + } else if (c.getColumnIndex() == 4) { + map.put("mediaName", returnStr); + } else if (c.getColumnIndex() == 5) { + map.put("mediaUrl", returnStr); + } else if (c.getColumnIndex() == 6) { + map.put("newsSource", returnStr); + } else if (c.getColumnIndex() == 7) { + map.put("isRecord", returnStr); + } else if (c.getColumnIndex() == 8) { + map.put("recordTime", returnStr); + } else if (c.getColumnIndex() == 9) { + map.put("remark", returnStr); + } + + } + result.add(map); + } + return result; + + } + + /** + * 获取合并单元格的值 + * + * @param sheet + * @param row + * @param column + * @return + */ + public static String getMergedRegionValue(Sheet sheet, int row, int column) { + int sheetMergeCount = sheet.getNumMergedRegions(); + + for (int i = 0; i < sheetMergeCount; i++) { + CellRangeAddress ca = sheet.getMergedRegion(i); + int firstColumn = ca.getFirstColumn(); + int lastColumn = ca.getLastColumn(); + int firstRow = ca.getFirstRow(); + int lastRow = ca.getLastRow(); + + if (row >= firstRow && row <= lastRow) { + + if (column >= firstColumn && column <= lastColumn) { + Row fRow = sheet.getRow(firstRow); + Cell fCell = fRow.getCell(firstColumn); + return getCellValue(fCell); + } + } + } + + return null; + } + + /** + * 判断合并了行 + * + * @param sheet + * @param row + * @param column + * @return + */ + public static boolean isMergedRow(Sheet sheet, int row, int column) { + int sheetMergeCount = sheet.getNumMergedRegions(); + for (int i = 0; i < sheetMergeCount; i++) { + CellRangeAddress range = sheet.getMergedRegion(i); + int firstColumn = range.getFirstColumn(); + int lastColumn = range.getLastColumn(); + int firstRow = range.getFirstRow(); + int lastRow = range.getLastRow(); + if (row == firstRow && row == lastRow) { + if (column >= firstColumn && column <= lastColumn) { + return true; + } + } + } + return false; + } + + /** + * 判断指定的单元格是否是合并单元格 + * + * @param sheet + * @param row 行下标 + * @param column 列下标 + * @return + */ + public static boolean isMergedRegion(Sheet sheet, int row, int column) { + int sheetMergeCount = sheet.getNumMergedRegions(); + for (int i = 0; i < sheetMergeCount; i++) { + CellRangeAddress range = sheet.getMergedRegion(i); + int firstColumn = range.getFirstColumn(); + int lastColumn = range.getLastColumn(); + int firstRow = range.getFirstRow(); + int lastRow = range.getLastRow(); + if (row >= firstRow && row <= lastRow) { + if (column >= firstColumn && column <= lastColumn) { + return true; + } + } + } + return false; + } + + /** + * 判断sheet页中是否含有合并单元格 + * + * @param sheet + * @return + */ + public static boolean hasMerged(Sheet sheet) { + return sheet.getNumMergedRegions() > 0 ? true : false; + } + + /** + * 合并单元格 + * + * @param sheet + * @param firstRow 开始行 + * @param lastRow 结束行 + * @param firstCol 开始列 + * @param lastCol 结束列 + */ + public static void mergeRegion(Sheet sheet, int firstRow, int lastRow, int firstCol, int lastCol) { + sheet.addMergedRegion(new CellRangeAddress(firstRow, lastRow, firstCol, lastCol)); + } + + /** + * 获取单元格的值 + * + * @param cell + * @return + */ + public static String getCellValue(Cell cell) { + if (cell == null) return ""; + if (cell.getCellType() == Cell.CELL_TYPE_STRING) { + return cell.getStringCellValue(); + } else if (cell.getCellType() == Cell.CELL_TYPE_BOOLEAN) { + return String.valueOf(cell.getBooleanCellValue()); + } else if (cell.getCellType() == Cell.CELL_TYPE_FORMULA) { + return cell.getCellFormula(); + } else if (cell.getCellType() == Cell.CELL_TYPE_NUMERIC) { + return String.valueOf(cell.getNumericCellValue()); + } + return ""; + } + + /** + * 从excel读取内容 + */ + public static void readContent(String fileName) { + //判断是否是excel2007格式 + boolean isE2007 = false; + if (fileName.endsWith("xlsx")) + isE2007 = true; + try { + //建立输入流 + InputStream input = new FileInputStream(fileName); + Workbook wb = null; + //根据文件格式(2003或者2007)来初始化 + if (isE2007) + wb = new XSSFWorkbook(input); + else + wb = new HSSFWorkbook(input); + //获得第一个表单 + Sheet sheet = wb.getSheetAt(0); + //获得第一个表单的迭代器 + Iterator rows = sheet.rowIterator(); + while (rows.hasNext()) { + //获得行数据 + Row row = rows.next(); + //获得行号从0开始 + System.out.println("Row #" + row.getRowNum()); + //获得第一行的迭代器 + Iterator cells = row.cellIterator(); + while (cells.hasNext()) { + Cell cell = cells.next(); + System.out.println("Cell #" + cell.getColumnIndex()); + //根据cell中的类型来输出数据 + switch (cell.getCellType()) { + case HSSFCell.CELL_TYPE_NUMERIC: + System.out.println(cell.getNumericCellValue()); + break; + case HSSFCell.CELL_TYPE_STRING: + System.out.println(cell.getStringCellValue()); + break; + case HSSFCell.CELL_TYPE_BOOLEAN: + System.out.println(cell.getBooleanCellValue()); + break; + case HSSFCell.CELL_TYPE_FORMULA: + System.out.println(cell.getCellFormula()); + break; + default: + //System.out.println("unsuported sell type======="+cell.getCellType()); + break; + } + } + } + } catch (IOException ex) { + ex.printStackTrace(); + } + } + +} \ No newline at end of file diff --git a/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/util/PoiElUtil.java b/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/util/PoiElUtil.java new file mode 100644 index 000000000..e5fc33a74 --- /dev/null +++ b/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/util/PoiElUtil.java @@ -0,0 +1,229 @@ +package com.pig4cloud.pigx.common.poi.util; + +import com.pig4cloud.pigx.common.poi.exception.excel.ExcelExportException; + +import java.util.Map; + +/** + * EasyPoi的el 表达式支持工具类 + * + * @author: Luckly + * @date: 2019-05-20 + *

+ */ +public final class PoiElUtil { + + public static final String LENGTH = "le:"; + public static final String FOREACH = "fe:"; + public static final String FOREACH_NOT_CREATE = "!fe:"; + public static final String FOREACH_AND_SHIFT = "$fe:"; + public static final String START_STR = "{{"; + public static final String END_STR = "}}"; + public static final String NUMBER_SYMBOL = "n:"; + public static final String FORMAT_DATE = "fd:"; + public static final String FORMAT_NUMBER = "fn:"; + public static final String IF_DELETE = "!if:"; + public static final String EMPTY = ""; + public static final String LEFT_BRACKET = "("; + public static final String RIGHT_BRACKET = ")"; + + private PoiElUtil() { + } + + /** + * 解析字符串,支持 le,fd,fn,!if,三目 + * + * @param text + * @param map + * @return + * @throws Exception + */ + public static Object eval(String text, Map map) throws Exception { + String tempText = new String(text); + Object obj = innerEval(text, map); + // 如果没有被处理而且这个值找map中存在就处理这个值 + if (tempText.equals(obj.toString()) && map.containsKey(tempText.split("\\.")[0])) { + return PoiPublicUtil.getParamsValue(tempText, map); + } + return obj; + } + + /** + * 解析字符串,支持 le,fd,fn,!if,三目 + * + * @param text + * @param map + * @return + * @throws Exception + */ + public static Object innerEval(String text, Map map) throws Exception { + if (text.indexOf("?") != -1 && text.indexOf(":") != -1) { + return trinocular(text, map); + } + if (text.indexOf(LENGTH) != -1) { + return length(text, map); + } + if (text.indexOf(FORMAT_DATE) != -1) { + return formatDate(text, map); + } + if (text.indexOf(FORMAT_NUMBER) != -1) { + return formatNumber(text, map); + } + if (text.indexOf(IF_DELETE) != -1) { + return ifDelete(text, map); + } + if (text.startsWith("'")) { + return text.replace("'", ""); + } + return text; + } + + /** + * 是不是删除列 + * + * @param text + * @param map + * @return + * @throws Exception + */ + private static Object ifDelete(String text, Map map) throws Exception { + // 把多个空格变成一个空格 + text = text.replaceAll("\\s{1,}", " ").trim(); + String[] keys = getKey(IF_DELETE, text).split(" "); + text = text.replace(IF_DELETE, EMPTY); + return isTrue(keys, map); + } + + /** + * 是不是真 + * + * @param keys + * @param map + * @return + * @throws Exception + */ + private static Boolean isTrue(String[] keys, Map map) throws Exception { + if (keys.length == 0) { + String constant = null; + if ((constant = isConstant(keys[0])) != null) { + return Boolean.valueOf(constant); + } + return Boolean.valueOf(PoiPublicUtil.getParamsValue(keys[0], map).toString()); + } + if (keys.length == 3) { + Object first = eval(keys[0], map); + Object second = eval(keys[2], map); + return PoiFunctionUtil.isTrue(first, keys[1], second); + } + throw new ExcelExportException("判断参数不对"); + } + + /** + * 判断是不是常量 + * + * @param param + * @return + */ + private static String isConstant(String param) { + if (param.indexOf("'") != -1) { + return param.replace("'", ""); + } + return null; + } + + /** + * 格式化数字 + * + * @param text + * @param map + * @return + * @throws Exception + */ + private static Object formatNumber(String text, Map map) throws Exception { + String[] key = getKey(FORMAT_NUMBER, text).split(";"); + text = text.replace(FORMAT_NUMBER, EMPTY); + return innerEval(replacinnerEvalue(text, PoiFunctionUtil.formatNumber(PoiPublicUtil.getParamsValue(key[0], map), key[1])), map); + } + + /** + * 格式化时间 + * + * @param text + * @param map + * @return + * @throws Exception + */ + private static Object formatDate(String text, Map map) throws Exception { + String[] key = getKey(FORMAT_DATE, text).split(";"); + text = text.replace(FORMAT_DATE, EMPTY); + return innerEval(replacinnerEvalue(text, PoiFunctionUtil.formatDate(PoiPublicUtil.getParamsValue(key[0], map), key[1])), map); + } + + /** + * 计算这个的长度 + * + * @param text + * @param map + * @throws Exception + */ + private static Object length(String text, Map map) throws Exception { + String key = getKey(LENGTH, text); + text = text.replace(LENGTH, EMPTY); + Object val = PoiPublicUtil.getParamsValue(key, map); + return innerEval(replacinnerEvalue(text, PoiFunctionUtil.length(val)), map); + } + + private static String replacinnerEvalue(String text, Object val) { + StringBuilder sb = new StringBuilder(); + sb.append(text.substring(0, text.indexOf(LEFT_BRACKET))); + sb.append(" "); + sb.append(val); + sb.append(" "); + sb.append(text.substring(text.indexOf(RIGHT_BRACKET) + 1, text.length())); + return sb.toString().trim(); + } + + private static String getKey(String prefix, String text) { + int leftBracket = 1, rigthBracket = 0, position = 0; + int index = text.indexOf(prefix) + prefix.length(); + while (text.charAt(index) == " ".charAt(0)) { + text = text.substring(0, index) + text.substring(index + 1, text.length()); + } + for (int i = text.indexOf(prefix + LEFT_BRACKET) + prefix.length() + 1; i < text.length(); i++) { + if (text.charAt(i) == LEFT_BRACKET.charAt(0)) { + leftBracket++; + } + if (text.charAt(i) == RIGHT_BRACKET.charAt(0)) { + rigthBracket++; + } + if (leftBracket == rigthBracket) { + position = i; + break; + } + } + return text.substring(text.indexOf(prefix + LEFT_BRACKET) + 1 + prefix.length(), position).trim(); + } + + public static void main(String[] args) { + System.out.println(getKey(IF_DELETE, "测试 " + IF_DELETE + " (小明)")); + } + + /** + * 三目运算 + * + * @return + * @throws Exception + */ + private static Object trinocular(String text, Map map) throws Exception { + // 把多个空格变成一个空格 + text = text.replaceAll("\\s{1,}", " ").trim(); + String testText = text.substring(0, text.indexOf("?")); + text = text.substring(text.indexOf("?") + 1, text.length()).trim(); + text = innerEval(text, map).toString(); + String[] keys = text.split(":"); + Object first = eval(keys[0].trim(), map); + Object second = eval(keys[1].trim(), map); + return isTrue(testText.split(" "), map) ? first : second; + } + +} diff --git a/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/util/PoiFunctionUtil.java b/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/util/PoiFunctionUtil.java new file mode 100644 index 000000000..85a491c10 --- /dev/null +++ b/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/util/PoiFunctionUtil.java @@ -0,0 +1,153 @@ +package com.pig4cloud.pigx.common.poi.util; + +import com.pig4cloud.pigx.common.poi.exception.excel.ExcelExportException; + +import java.lang.reflect.Array; +import java.text.DecimalFormat; +import java.text.SimpleDateFormat; +import java.util.Collection; +import java.util.Map; + +/** + * if else,length,for each,fromatNumber,formatDate 满足模板的 el 表达式支持 + * + * @author: Luckly + * @date: 2019-05-20 + *

+ */ +public final class PoiFunctionUtil { + + private static final String TWO_DECIMAL_STR = "###.00"; + private static final String THREE_DECIMAL_STR = "###.000"; + + private static final DecimalFormat TWO_DECIMAL = new DecimalFormat(TWO_DECIMAL_STR); + private static final DecimalFormat THREE_DECIMAL = new DecimalFormat(THREE_DECIMAL_STR); + + private static final String DAY_STR = "yyyy-MM-dd"; + private static final String TIME_STR = "yyyy-MM-dd HH:mm:ss"; + private static final String TIME__NO_S_STR = "yyyy-MM-dd HH:mm"; + + private static final SimpleDateFormat DAY_FORMAT = new SimpleDateFormat(DAY_STR); + private static final SimpleDateFormat TIME_FORMAT = new SimpleDateFormat(TIME_STR); + private static final SimpleDateFormat TIME__NO_S_FORMAT = new SimpleDateFormat(TIME__NO_S_STR); + + private PoiFunctionUtil() { + } + + /** + * 获取对象的长度 + * + * @param obj + * @return + */ + @SuppressWarnings("rawtypes") + public static int length(Object obj) { + if (obj == null) { + return 0; + } + if (obj instanceof Map) { + return ((Map) obj).size(); + } + if (obj instanceof Collection) { + return ((Collection) obj).size(); + } + if (obj.getClass().isArray()) { + return Array.getLength(obj); + } + return String.valueOf(obj).length(); + } + + /** + * 格式化数字 + * + * @param obj + * @return + * @throws NumberFormatException + */ + public static String formatNumber(Object obj, String format) { + if (obj == null || obj.toString() == "") { + return ""; + } + double number = Double.valueOf(obj.toString()); + DecimalFormat decimalFormat = null; + if (TWO_DECIMAL.equals(format)) { + decimalFormat = TWO_DECIMAL; + } else if (THREE_DECIMAL_STR.equals(format)) { + decimalFormat = THREE_DECIMAL; + } else { + decimalFormat = new DecimalFormat(format); + } + return decimalFormat.format(number); + } + + /** + * 格式化时间 + * + * @param obj + * @return + */ + public static String formatDate(Object obj, String format) { + if (obj == null || obj.toString() == "") { + return ""; + } + SimpleDateFormat dateFormat = null; + if (DAY_STR.equals(format)) { + dateFormat = DAY_FORMAT; + } else if (TIME_STR.equals(format)) { + dateFormat = TIME_FORMAT; + } else if (TIME__NO_S_STR.equals(format)) { + dateFormat = TIME__NO_S_FORMAT; + } else { + dateFormat = new SimpleDateFormat(format); + } + return dateFormat.format(obj); + } + + /** + * 判断是不是成功 + * + * @param first + * @param operator + * @param second + * @return + */ + public static boolean isTrue(Object first, String operator, Object second) { + if (">".endsWith(operator)) { + return isGt(first, second); + } else if ("<".endsWith(operator)) { + return isGt(second, first); + } else if ("==".endsWith(operator)) { + if (first != null && second != null) { + return first.equals(second); + } + return first == second; + } else if ("!=".endsWith(operator)) { + if (first != null && second != null) { + return !first.equals(second); + } + return first != second; + } else { + throw new ExcelExportException("占不支持改操作符"); + } + } + + /** + * 前者是不是大于后者 + * + * @param first + * @param second + * @return + */ + private static boolean isGt(Object first, Object second) { + if (first == null || first.toString() == "") { + return false; + } + if (second == null || second.toString() == "") { + return true; + } + double one = Double.valueOf(first.toString()); + double two = Double.valueOf(second.toString()); + return one > two; + } + +} diff --git a/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/util/PoiMergeCellUtil.java b/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/util/PoiMergeCellUtil.java new file mode 100644 index 000000000..08eab3ca7 --- /dev/null +++ b/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/util/PoiMergeCellUtil.java @@ -0,0 +1,182 @@ +package com.pig4cloud.pigx.common.poi.util; + +import org.apache.commons.lang3.StringUtils; +import org.apache.poi.ss.usermodel.Cell; +import org.apache.poi.ss.usermodel.Row; +import org.apache.poi.ss.usermodel.Sheet; +import org.apache.poi.ss.util.CellRangeAddress; +import com.pig4cloud.pigx.common.poi.excel.entity.params.MergeEntity; +import com.pig4cloud.pigx.common.poi.exception.excel.ExcelExportException; + +import java.util.*; + +/** + * 纵向合并单元格工具类 + * + * @author: Luckly + * @date: 2019-05-20 + *

+ */ +public final class PoiMergeCellUtil { + + private PoiMergeCellUtil() { + } + + /** + * 纵向合并相同内容的单元格 + * + * @param sheet + * @param startRow 开始行 + * @param columns 需要处理的列 + */ + public static void mergeCells(Sheet sheet, int startRow, Integer... columns) { + if (columns == null) { + throw new ExcelExportException("至少需要处理1列"); + } + Map mergeMap = new HashMap(); + for (int i = 0; i < columns.length; i++) { + mergeMap.put(columns[i], null); + } + mergeCells(sheet, mergeMap, startRow, sheet.getLastRowNum()); + } + + /** + * 纵向合并相同内容的单元格 + * + * @param sheet + * @param mergeMap key--列,value--依赖的列,没有传空 + * @param startRow 开始行 + */ + public static void mergeCells(Sheet sheet, Map mergeMap, int startRow) { + mergeCells(sheet, mergeMap, startRow, sheet.getLastRowNum()); + } + + /** + * 纵向合并相同内容的单元格 + * + * @param sheet + * @param mergeMap key--列,value--依赖的列,没有传空 + * @param startRow 开始行 + * @param endRow 结束行 + */ + public static void mergeCells(Sheet sheet, Map mergeMap, int startRow, int endRow) { + Map mergeDataMap = new HashMap(); + if (mergeMap.size() == 0) { + return; + } + Row row; + Set sets = mergeMap.keySet(); + String text; + for (int i = startRow; i <= endRow; i++) { + row = sheet.getRow(i); + for (Integer index : sets) { + if (row == null || row.getCell(index) == null) { + if (mergeDataMap.get(index) == null) { + continue; + } + if (mergeDataMap.get(index).getEndRow() == 0) { + mergeDataMap.get(index).setEndRow(i - 1); + } + } else { + text = row.getCell(index).getStringCellValue(); + if (StringUtils.isNotEmpty(text)) { + hanlderMergeCells(index, i, text, mergeDataMap, sheet, row.getCell(index), mergeMap.get(index)); + } else { + mergeCellOrContinue(index, mergeDataMap, sheet); + } + } + } + } + if (mergeDataMap.size() > 0) { + for (Integer index : mergeDataMap.keySet()) { + sheet.addMergedRegion(new CellRangeAddress(mergeDataMap.get(index).getStartRow(), mergeDataMap.get(index).getEndRow(), index, index)); + } + } + + } + + /** + * 处理合并单元格 + * + * @param index + * @param rowNum + * @param text + * @param mergeDataMap + * @param sheet + * @param cell + * @param delys + */ + private static void hanlderMergeCells(Integer index, int rowNum, String text, Map mergeDataMap, Sheet sheet, Cell cell, int[] delys) { + if (mergeDataMap.containsKey(index)) { + if (checkIsEqualByCellContents(mergeDataMap.get(index), text, cell, delys, rowNum)) { + mergeDataMap.get(index).setEndRow(rowNum); + } else { + sheet.addMergedRegion(new CellRangeAddress(mergeDataMap.get(index).getStartRow(), mergeDataMap.get(index).getEndRow(), index, index)); + mergeDataMap.put(index, createMergeEntity(text, rowNum, cell, delys)); + } + } else { + mergeDataMap.put(index, createMergeEntity(text, rowNum, cell, delys)); + } + } + + /** + * 字符为空的情况下判断 + * + * @param index + * @param mergeDataMap + * @param sheet + */ + private static void mergeCellOrContinue(Integer index, Map mergeDataMap, Sheet sheet) { + if (mergeDataMap.containsKey(index) && mergeDataMap.get(index).getEndRow() != mergeDataMap.get(index).getStartRow()) { + sheet.addMergedRegion(new CellRangeAddress(mergeDataMap.get(index).getStartRow(), mergeDataMap.get(index).getEndRow(), index, index)); + mergeDataMap.remove(index); + } + } + + private static MergeEntity createMergeEntity(String text, int rowNum, Cell cell, int[] delys) { + MergeEntity mergeEntity = new MergeEntity(text, rowNum, rowNum); + // 存在依赖关系 + if (delys != null && delys.length != 0) { + List list = new ArrayList(delys.length); + mergeEntity.setRelyList(list); + for (int i = 0; i < delys.length; i++) { + list.add(getCellNotNullText(cell, delys[i], rowNum)); + } + } + return mergeEntity; + } + + private static boolean checkIsEqualByCellContents(MergeEntity mergeEntity, String text, Cell cell, int[] delys, int rowNum) { + // 没有依赖关系 + if (delys == null || delys.length == 0) { + return mergeEntity.getText().equals(text); + } + // 存在依赖关系 + if (mergeEntity.getText().equals(text)) { + for (int i = 0; i < delys.length; i++) { + if (!getCellNotNullText(cell, delys[i], rowNum).equals(mergeEntity.getRelyList().get(i))) { + return false; + } + } + return true; + } + return false; + } + + /** + * 获取一个单元格的值,确保这个单元格必须有值,不然向上查询 + * + * @param cell + * @param index + * @param rowNum + * @return + */ + private static String getCellNotNullText(Cell cell, int index, int rowNum) { + String temp = cell.getRow().getCell(index).getStringCellValue(); + while (StringUtils.isEmpty(temp)) { + temp = cell.getRow().getSheet().getRow(--rowNum).getCell(index).getStringCellValue(); + } + return temp; + } + +} diff --git a/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/util/PoiPublicUtil.java b/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/util/PoiPublicUtil.java new file mode 100644 index 000000000..b9562cac1 --- /dev/null +++ b/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/util/PoiPublicUtil.java @@ -0,0 +1,459 @@ +package com.pig4cloud.pigx.common.poi.util; + +import com.pig4cloud.pigx.common.poi.excel.annotation.Excel; +import com.pig4cloud.pigx.common.poi.excel.annotation.ExcelCollection; +import com.pig4cloud.pigx.common.poi.excel.annotation.ExcelEntity; +import com.pig4cloud.pigx.common.poi.excel.annotation.ExcelIgnore; +import com.pig4cloud.pigx.common.poi.excel.entity.vo.PoiBaseConstants; +import com.pig4cloud.pigx.common.poi.word.entity.WordImageEntity; +import com.pig4cloud.pigx.common.poi.word.entity.params.ExcelListEntity; +import lombok.extern.slf4j.Slf4j; +import org.apache.poi.POIXMLDocumentPart; +import org.apache.poi.hssf.usermodel.*; +import org.apache.poi.ss.usermodel.PictureData; +import org.apache.poi.xssf.usermodel.*; +import org.apache.poi.xwpf.usermodel.XWPFDocument; +import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.CTMarker; +import org.springframework.util.ClassUtils; + +import javax.imageio.ImageIO; +import java.awt.image.BufferedImage; +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.math.BigDecimal; +import java.util.*; + +/** + * EASYPOI 的公共基础类 + * + * @author: Luckly + * @date: 2019-05-20 + *

+ */ +@Slf4j +public final class PoiPublicUtil { + + private PoiPublicUtil() { + + } + + @SuppressWarnings({"unchecked"}) + public static Map mapFor(Object... mapping) { + Map map = new HashMap(); + for (int i = 0; i < mapping.length; i += 2) { + map.put((K) mapping[i], (V) mapping[i + 1]); + } + return map; + } + + /** + * 彻底创建一个对象 + * + * @param clazz + * @return + */ + public static Object createObject(Class clazz, String targetId) { + Object obj = null; + Method setMethod; + try { + if (clazz.equals(Map.class)) { + return new HashMap(); + } + obj = clazz.newInstance(); + Field[] fields = getClassFields(clazz); + for (Field field : fields) { + if (isNotUserExcelUserThis(null, field, targetId)) { + continue; + } + if (isCollection(field.getType())) { + ExcelCollection collection = field.getAnnotation(ExcelCollection.class); + setMethod = getMethod(field.getName(), clazz, field.getType()); + setMethod.invoke(obj, collection.type().newInstance()); + } else if (!isJavaClass(field)) { + setMethod = getMethod(field.getName(), clazz, field.getType()); + setMethod.invoke(obj, createObject(field.getType(), targetId)); + } + } + + } catch (Exception e) { + log.error(e.getMessage(), e); + throw new RuntimeException("创建对象异常"); + } + return obj; + + } + + /** + * 获取class的 包括父类的 + * + * @param clazz + * @return + */ + public static Field[] getClassFields(Class clazz) { + List list = new ArrayList(); + Field[] fields; + do { + fields = clazz.getDeclaredFields(); + for (int i = 0; i < fields.length; i++) { + list.add(fields[i]); + } + clazz = clazz.getSuperclass(); + } while (clazz != Object.class && clazz != null); + return list.toArray(fields); + } + + /** + * @param photoByte + * @return + */ + public static String getFileExtendName(byte[] photoByte) { + String strFileExtendName = "JPG"; + if ((photoByte[0] == 71) && (photoByte[1] == 73) && (photoByte[2] == 70) && (photoByte[3] == 56) && ((photoByte[4] == 55) || (photoByte[4] == 57)) && (photoByte[5] == 97)) { + strFileExtendName = "GIF"; + } else if ((photoByte[6] == 74) && (photoByte[7] == 70) && (photoByte[8] == 73) && (photoByte[9] == 70)) { + strFileExtendName = "JPG"; + } else if ((photoByte[0] == 66) && (photoByte[1] == 77)) { + strFileExtendName = "BMP"; + } else if ((photoByte[1] == 80) && (photoByte[2] == 78) && (photoByte[3] == 71)) { + strFileExtendName = "PNG"; + } + return strFileExtendName; + } + + /** + * 获取GET方法 + * + * @param name + * @param pojoClass + * @return + * @throws Exception + */ + public static Method getMethod(String name, Class pojoClass) throws Exception { + StringBuffer getMethodName = new StringBuffer(PoiBaseConstants.GET); + getMethodName.append(name.substring(0, 1).toUpperCase()); + getMethodName.append(name.substring(1)); + Method method = null; + try { + method = pojoClass.getMethod(getMethodName.toString(), new Class[]{}); + } catch (Exception e) { + method = pojoClass.getMethod(getMethodName.toString().replace(PoiBaseConstants.GET, PoiBaseConstants.IS), new Class[]{}); + } + return method; + } + + /** + * 获取SET方法 + * + * @param name + * @param pojoClass + * @param type + * @return + * @throws Exception + */ + public static Method getMethod(String name, Class pojoClass, Class type) throws Exception { + StringBuffer getMethodName = new StringBuffer(PoiBaseConstants.SET); + getMethodName.append(name.substring(0, 1).toUpperCase()); + getMethodName.append(name.substring(1)); + return pojoClass.getMethod(getMethodName.toString(), new Class[]{type}); + } + + /** + * 获取get方法 通过EXCEL注解exportConvert判断是否支持值的转换 + * + * @param name + * @param pojoClass + * @param convert + * @return + * @throws Exception + */ + public static Method getMethod(String name, Class pojoClass, boolean convert) throws Exception { + StringBuffer getMethodName = new StringBuffer(); + if (convert) { + getMethodName.append(PoiBaseConstants.CONVERT); + } + getMethodName.append(PoiBaseConstants.GET); + getMethodName.append(name.substring(0, 1).toUpperCase()); + getMethodName.append(name.substring(1)); + Method method = null; + try { + method = pojoClass.getMethod(getMethodName.toString(), new Class[]{}); + } catch (Exception e) { + method = pojoClass.getMethod(getMethodName.toString().replace(PoiBaseConstants.GET, PoiBaseConstants.IS), new Class[]{}); + } + return method; + } + + /** + * 获取set方法 通过EXCEL注解importConvert判断是否支持值的转换 + * + * @param name + * @param pojoClass + * @param type + * @param convert + * @return + * @throws Exception + */ + public static Method getMethod(String name, Class pojoClass, Class type, boolean convert) throws Exception { + StringBuffer setMethodName = new StringBuffer(); + if (convert) { + setMethodName.append(PoiBaseConstants.CONVERT); + } + setMethodName.append(PoiBaseConstants.SET); + setMethodName.append(name.substring(0, 1).toUpperCase()); + setMethodName.append(name.substring(1)); + return pojoClass.getMethod(setMethodName.toString(), new Class[]{type}); + } + + /** + * 获取Excel2003图片 + * + * @param sheet 当前sheet对象 + * @param workbook 工作簿对象 + * @return Map key:图片单元格索引(1_1)String,value:图片流PictureData + */ + public static Map getSheetPictrues03(HSSFSheet sheet, HSSFWorkbook workbook) { + Map sheetIndexPicMap = new HashMap(); + List pictures = workbook.getAllPictures(); + if (!pictures.isEmpty()) { + for (HSSFShape shape : sheet.getDrawingPatriarch().getChildren()) { + HSSFClientAnchor anchor = (HSSFClientAnchor) shape.getAnchor(); + if (shape instanceof HSSFPicture) { + HSSFPicture pic = (HSSFPicture) shape; + int pictureIndex = pic.getPictureIndex() - 1; + HSSFPictureData picData = pictures.get(pictureIndex); + String picIndex = String.valueOf(anchor.getRow1()) + "_" + String.valueOf(anchor.getCol1()); + sheetIndexPicMap.put(picIndex, picData); + } + } + return sheetIndexPicMap; + } else { + return null; + } + } + + /** + * 获取Excel2007图片 + * + * @param sheet 当前sheet对象 + * @param workbook 工作簿对象 + * @return Map key:图片单元格索引(1_1)String,value:图片流PictureData + */ + public static Map getSheetPictrues07(XSSFSheet sheet, XSSFWorkbook workbook) { + Map sheetIndexPicMap = new HashMap(); + for (POIXMLDocumentPart dr : sheet.getRelations()) { + if (dr instanceof XSSFDrawing) { + XSSFDrawing drawing = (XSSFDrawing) dr; + List shapes = drawing.getShapes(); + for (XSSFShape shape : shapes) { + XSSFPicture pic = (XSSFPicture) shape; + XSSFClientAnchor anchor = pic.getPreferredSize(); + CTMarker ctMarker = anchor.getFrom(); + String picIndex = ctMarker.getRow() + "_" + ctMarker.getCol(); + sheetIndexPicMap.put(picIndex, pic.getPictureData()); + } + } + } + return sheetIndexPicMap; + } + + public static String getWebRootPath(String filePath) { +// String path = PoiPublicUtil.class.getClassLoader().getResource("").toURI().getPath(); + String path = ClassUtils.getDefaultClassLoader().getResource("").getPath(); + log.debug("--- getWebRootPath ----filePath--- " + path); + path = path.replace("WEB-INF/classes/", ""); + path = path.replace("file:/", ""); + log.debug("--- path--- " + path); + log.debug("--- filePath--- " + filePath); + return path + filePath; + } + + /** + * 判断是不是集合的实现类 + * + * @param clazz + * @return + */ + public static boolean isCollection(Class clazz) { + return Collection.class.isAssignableFrom(clazz); + } + + /** + * 是不是java基础类 + * + * @param field + * @return + */ + public static boolean isJavaClass(Field field) { + Class fieldType = field.getType(); + boolean isBaseClass = false; + if (fieldType.isArray()) { + isBaseClass = false; + } else if (fieldType.isPrimitive() || fieldType.getPackage() == null || fieldType.getPackage().getName().equals("java.lang") || fieldType.getPackage().getName().equals("java.math") || fieldType.getPackage().getName().equals("java.sql") || fieldType.getPackage().getName().equals("java.util")) { + isBaseClass = true; + } + return isBaseClass; + } + + /** + * 判断是否不要在这个excel操作中 + * + * @param + * @param field + * @param targetId + * @return + */ + public static boolean isNotUserExcelUserThis(List exclusionsList, Field field, String targetId) { + boolean boo = true; + if (field.getAnnotation(ExcelIgnore.class) != null) { + boo = true; + } else if (boo && field.getAnnotation(ExcelCollection.class) != null && isUseInThis(field.getAnnotation(ExcelCollection.class).name(), targetId) && (exclusionsList == null || !exclusionsList.contains(field.getAnnotation(ExcelCollection.class).name()))) { + boo = false; + } else if (boo && field.getAnnotation(Excel.class) != null && isUseInThis(field.getAnnotation(Excel.class).name(), targetId) && (exclusionsList == null || !exclusionsList.contains(field.getAnnotation(Excel.class).name()))) { + boo = false; + } else if (boo && field.getAnnotation(ExcelEntity.class) != null && isUseInThis(field.getAnnotation(ExcelEntity.class).name(), targetId) && (exclusionsList == null || !exclusionsList.contains(field.getAnnotation(ExcelEntity.class).name()))) { + boo = false; + } + return boo; + } + + /** + * 判断是不是使用 + * + * @param exportName + * @param targetId + * @return + */ + private static boolean isUseInThis(String exportName, String targetId) { + return targetId == null || exportName.equals("") || exportName.indexOf("_") < 0 || exportName.indexOf(targetId) != -1; + } + + private static Integer getImageType(String type) { + if (type.equalsIgnoreCase("JPG") || type.equalsIgnoreCase("JPEG")) { + return XWPFDocument.PICTURE_TYPE_JPEG; + } + if (type.equalsIgnoreCase("GIF")) { + return XWPFDocument.PICTURE_TYPE_GIF; + } + if (type.equalsIgnoreCase("BMP")) { + return XWPFDocument.PICTURE_TYPE_GIF; + } + if (type.equalsIgnoreCase("PNG")) { + return XWPFDocument.PICTURE_TYPE_PNG; + } + return XWPFDocument.PICTURE_TYPE_JPEG; + } + + /** + * 返回流和图片类型 + * + * @param entity + * @return + * @throws Exception + */ + public static Object[] getIsAndType(WordImageEntity entity) throws Exception { + Object[] result = new Object[2]; + String type; + if (entity.getType().equals(WordImageEntity.URL)) { + ByteArrayOutputStream byteArrayOut = new ByteArrayOutputStream(); + BufferedImage bufferImg; + String path = Thread.currentThread().getContextClassLoader().getResource("").toURI().getPath() + entity.getUrl(); + path = path.replace("WEB-INF/classes/", ""); + path = path.replace("file:/", ""); + bufferImg = ImageIO.read(new File(path)); + ImageIO.write(bufferImg, entity.getUrl().substring(entity.getUrl().indexOf(".") + 1, entity.getUrl().length()), byteArrayOut); + result[0] = byteArrayOut.toByteArray(); + type = entity.getUrl().split("/.")[entity.getUrl().split("/.").length - 1]; + } else { + result[0] = entity.getData(); + type = PoiPublicUtil.getFileExtendName(entity.getData()); + } + result[1] = getImageType(type); + return result; + } + + /** + * 获取参数值 + * + * @param params + * @param map + * @return + */ + @SuppressWarnings("rawtypes") + public static Object getParamsValue(String params, Object object) throws Exception { + if (params.indexOf(".") != -1) { + String[] paramsArr = params.split("\\."); + return getValueDoWhile(object, paramsArr, 0); + } + if (object instanceof Map) { + return ((Map) object).get(params); + } + return getMethod(params, object.getClass()).invoke(object, new Object[]{}); + } + + /** + * 解析数据 + * + * @param currentText + * @param map + * @return + * @throws Exception + */ + public static Object getRealValue(String currentText, Map map) throws Exception { + String params = ""; + while (currentText.indexOf("{{") != -1) { + params = currentText.substring(currentText.indexOf("{{") + 2, currentText.indexOf("}}")); + Object obj = getParamsValue(params.trim(), map); + // 判断图片或者是集合 + + if (obj instanceof WordImageEntity || obj instanceof List || obj instanceof ExcelListEntity) { + return obj; + } else { + currentText = currentText.replace("{{" + params + "}}", obj.toString()); + } + } + return currentText; + } + + /** + * 通过遍历过去对象值 + * + * @param object + * @param paramsArr + * @param index + * @return + * @throws Exception + */ + @SuppressWarnings("rawtypes") + public static Object getValueDoWhile(Object object, String[] paramsArr, int index) throws Exception { + if (object == null) { + return ""; + } + if (object instanceof WordImageEntity) { + return object; + } + if (object instanceof Map) { + object = ((Map) object).get(paramsArr[index]); + } else { + object = getMethod(paramsArr[index], object.getClass()).invoke(object, new Object[]{}); + } + return (index == paramsArr.length - 1) ? (object == null ? "" : object) : getValueDoWhile(object, paramsArr, ++index); + } + + /** + * double to String 防止科学计数法 + * + * @param value + * @return + */ + public static String doubleToString(Double value) { + String temp = value.toString(); + if (temp.contains("E")) { + BigDecimal bigDecimal = new BigDecimal(temp); + temp = bigDecimal.toPlainString(); + } + return temp; + } + +} diff --git a/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/util/PoiSheetUtility.java b/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/util/PoiSheetUtility.java new file mode 100644 index 000000000..1dff07f4c --- /dev/null +++ b/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/util/PoiSheetUtility.java @@ -0,0 +1,94 @@ +package com.pig4cloud.pigx.common.poi.util; + +import org.apache.poi.ss.usermodel.Cell; +import org.apache.poi.ss.usermodel.Row; +import org.apache.poi.ss.usermodel.Sheet; + +/** + * Helper functions to aid in the management of sheets + * 国外的,不过也不好,慎用,效率不行 TODO + * + * @author: 国外 + * @date: 2019-05-20 + *

+ */ +public class PoiSheetUtility extends Object { + + /** + * Given a sheet, this method deletes a column from a sheet and moves all + * the columns to the right of it to the left one cell. + *

+ * Note, this method will not update any formula references. + * + * @param sheet + * @param columnToDelete + */ + public static void deleteColumn(Sheet sheet, int columnToDelete) { + int maxColumn = 0; + for (int r = 0; r < sheet.getLastRowNum() + 1; r++) { + Row row = sheet.getRow(r); + + // if no row exists here; then nothing to do; next! + if (row == null) + continue; + + // if the row doesn't have this many columns then we are good; next! + int lastColumn = row.getLastCellNum(); + if (lastColumn > maxColumn) + maxColumn = lastColumn; + + if (lastColumn < columnToDelete) + continue; + + for (int x = columnToDelete + 1; x < lastColumn + 1; x++) { + Cell oldCell = row.getCell(x - 1); + if (oldCell != null) + row.removeCell(oldCell); + + Cell nextCell = row.getCell(x); + if (nextCell != null) { + Cell newCell = row.createCell(x - 1, nextCell.getCellType()); + cloneCell(newCell, nextCell); + } + } + } + + // Adjust the column widths + for (int c = 0; c < maxColumn; c++) { + sheet.setColumnWidth(c, sheet.getColumnWidth(c + 1)); + } + } + + /* + * Takes an existing Cell and merges all the styles and forumla into the new + * one + */ + private static void cloneCell(Cell cNew, Cell cOld) { + cNew.setCellComment(cOld.getCellComment()); + cNew.setCellStyle(cOld.getCellStyle()); + + switch (cNew.getCellType()) { + case Cell.CELL_TYPE_BOOLEAN: { + cNew.setCellValue(cOld.getBooleanCellValue()); + break; + } + case Cell.CELL_TYPE_NUMERIC: { + cNew.setCellValue(cOld.getNumericCellValue()); + break; + } + case Cell.CELL_TYPE_STRING: { + cNew.setCellValue(cOld.getStringCellValue()); + break; + } + case Cell.CELL_TYPE_ERROR: { + cNew.setCellValue(cOld.getErrorCellValue()); + break; + } + case Cell.CELL_TYPE_FORMULA: { + cNew.setCellFormula(cOld.getCellFormula()); + break; + } + } + + } +} \ No newline at end of file diff --git a/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/word/WordExportUtil.java b/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/word/WordExportUtil.java new file mode 100644 index 000000000..39fccf495 --- /dev/null +++ b/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/word/WordExportUtil.java @@ -0,0 +1,43 @@ +package com.pig4cloud.pigx.common.poi.word; + +import org.apache.poi.xwpf.usermodel.XWPFDocument; +import com.pig4cloud.pigx.common.poi.word.parse.ParseWord07; + +import java.util.Map; + +/** + * Word使用模板导出工具类 + * + * @author: Luckly + * @date: 2019-05-20 + *

+ */ +public final class WordExportUtil { + + private WordExportUtil() { + + } + + /** + * 解析Word2007版本 + * + * @param url 模板地址 + * @param map 解析数据源 + * @return + */ + public static XWPFDocument exportWord07(String url, Map map) throws Exception { + return new ParseWord07().parseWord(url, map); + } + + /** + * 解析Word2007版本 + * + * @param document 模板 + * @param map 解析数据源 + * @return + */ + public static void exportWord07(XWPFDocument document, Map map) throws Exception { + new ParseWord07().parseWord(document, map); + } + +} diff --git a/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/word/entity/MyXWPFDocument.java b/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/word/entity/MyXWPFDocument.java new file mode 100644 index 000000000..3a28dada5 --- /dev/null +++ b/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/word/entity/MyXWPFDocument.java @@ -0,0 +1,107 @@ +package com.pig4cloud.pigx.common.poi.word.entity; + +import lombok.extern.slf4j.Slf4j; +import org.apache.poi.openxml4j.opc.OPCPackage; +import org.apache.poi.xwpf.usermodel.XWPFDocument; +import org.apache.poi.xwpf.usermodel.XWPFRun; +import org.apache.xmlbeans.XmlException; +import org.apache.xmlbeans.XmlToken; +import org.openxmlformats.schemas.drawingml.x2006.main.CTNonVisualDrawingProps; +import org.openxmlformats.schemas.drawingml.x2006.main.CTPositiveSize2D; +import org.openxmlformats.schemas.drawingml.x2006.wordprocessingDrawing.CTInline; + +import java.io.InputStream; + +/** + * 扩充document,修复图片插入失败问题问题 + * + * @author: Luckly + * @date: 2019-05-20 + *

+ */ +@Slf4j +public class MyXWPFDocument extends XWPFDocument { + + private static String PICXML = "" + + "" + + " " + + " " + + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + + " " + + " " + " " + + " " + " " + + " " + " " + + " " + + " " + ""; + + public MyXWPFDocument() { + super(); + } + + public MyXWPFDocument(InputStream in) throws Exception { + super(in); + } + + public MyXWPFDocument(OPCPackage opcPackage) throws Exception { + super(opcPackage); + } + + public void createPicture(String blipId, int id, int width, int height) { + final int EMU = 9525; + width *= EMU; + height *= EMU; + CTInline inline = createParagraph().createRun().getCTR().addNewDrawing().addNewInline(); + String picXml = String.format(PICXML, id, blipId, width, height); + XmlToken xmlToken = null; + try { + xmlToken = XmlToken.Factory.parse(picXml); + } catch (XmlException xe) { + log.error(xe.getMessage(), xe.fillInStackTrace()); + } + inline.set(xmlToken); + + inline.setDistT(0); + inline.setDistB(0); + inline.setDistL(0); + inline.setDistR(0); + + CTPositiveSize2D extent = inline.addNewExtent(); + extent.setCx(width); + extent.setCy(height); + + CTNonVisualDrawingProps docPr = inline.addNewDocPr(); + docPr.setId(id); + docPr.setName("Picture " + id); + docPr.setDescr("Generated"); + } + + public void createPicture(XWPFRun run, String blipId, int id, int width, int height) { + final int EMU = 9525; + width *= EMU; + height *= EMU; + CTInline inline = run.getCTR().addNewDrawing().addNewInline(); + String picXml = String.format(PICXML, id, blipId, width, height); + XmlToken xmlToken = null; + try { + xmlToken = XmlToken.Factory.parse(picXml); + } catch (XmlException xe) { + log.error(xe.getMessage(), xe.fillInStackTrace()); + } + inline.set(xmlToken); + + inline.setDistT(0); + inline.setDistB(0); + inline.setDistL(0); + inline.setDistR(0); + + CTPositiveSize2D extent = inline.addNewExtent(); + extent.setCx(width); + extent.setCy(height); + + CTNonVisualDrawingProps docPr = inline.addNewDocPr(); + docPr.setId(id); + docPr.setName("Picture " + id); + docPr.setDescr("Generated"); + } + +} diff --git a/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/word/entity/WordImageEntity.java b/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/word/entity/WordImageEntity.java new file mode 100644 index 000000000..bc7bb48c3 --- /dev/null +++ b/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/word/entity/WordImageEntity.java @@ -0,0 +1,60 @@ +package com.pig4cloud.pigx.common.poi.word.entity; + +import lombok.Data; + +/** + * word导出,图片设置和图片信息 + * + * @author: Luckly + * @date: 2019-05-20 + *

+ */ +@Data +public class WordImageEntity { + /** + * 地址 + */ + public static String URL = "url"; + /** + * 数据 + */ + public static String Data = "data"; + /** + * 图片输入方式 + */ + private String type = URL; + /** + * 图片宽度 + */ + private int width; + /** + * 图片高度 + */ + private int height; + /** + * 图片地址 + */ + private String url; + /** + * 图片信息 + */ + private byte[] data; + + public WordImageEntity() { + + } + + public WordImageEntity(byte[] data, int width, int height) { + this.data = data; + this.width = width; + this.height = height; + this.type = Data; + } + + public WordImageEntity(String url, int width, int height) { + this.url = url; + this.width = width; + this.height = height; + } + +} diff --git a/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/word/entity/params/ExcelListEntity.java b/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/word/entity/params/ExcelListEntity.java new file mode 100644 index 000000000..6c03cc3d5 --- /dev/null +++ b/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/word/entity/params/ExcelListEntity.java @@ -0,0 +1,83 @@ +package com.pig4cloud.pigx.common.poi.word.entity.params; + +import com.pig4cloud.pigx.common.poi.excel.entity.ExcelBaseParams; +import com.pig4cloud.pigx.common.poi.handler.inter.IExcelDataHandler; + +import java.util.List; + +/** + * @author: Luckly + * @date: 2019-05-20 + *

+ * Excel 导出对象 + */ +public class ExcelListEntity extends ExcelBaseParams { + + /** + * 数据源 + */ + private List list; + + /** + * 实体类对象 + */ + private Class clazz; + + /** + * 表头行数 + */ + private int headRows = 1; + + public ExcelListEntity() { + + } + + public ExcelListEntity(List list, Class clazz) { + this.list = list; + this.clazz = clazz; + } + + public ExcelListEntity(List list, Class clazz, IExcelDataHandler dataHanlder) { + this.list = list; + this.clazz = clazz; + setDataHanlder(dataHanlder); + } + + public ExcelListEntity(List list, Class clazz, IExcelDataHandler dataHanlder, int headRows) { + this.list = list; + this.clazz = clazz; + this.headRows = headRows; + setDataHanlder(dataHanlder); + } + + public ExcelListEntity(List list, Class clazz, int headRows) { + this.list = list; + this.clazz = clazz; + this.headRows = headRows; + } + + public Class getClazz() { + return clazz; + } + + public int getHeadRows() { + return headRows; + } + + public List getList() { + return list; + } + + public void setClazz(Class clazz) { + this.clazz = clazz; + } + + public void setHeadRows(int headRows) { + this.headRows = headRows; + } + + public void setList(List list) { + this.list = list; + } + +} diff --git a/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/word/entity/params/ListParamEntity.java b/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/word/entity/params/ListParamEntity.java new file mode 100644 index 000000000..d93f2d201 --- /dev/null +++ b/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/word/entity/params/ListParamEntity.java @@ -0,0 +1,55 @@ +package com.pig4cloud.pigx.common.poi.word.entity.params; + +import lombok.Data; + +/** + * Excel 对象导出结构 + * + * @author: Luckly + * @date: 2019-05-20 + *

+ */ +@Data +public class ListParamEntity { + /** + * 唯一值,在遍历中重复使用 + */ + public static final String SINGLE = "single"; + /** + * 属于数组类型 + */ + public static final String LIST = "list"; + /** + * 属性名称 + */ + private String name; + /** + * 目标 + */ + private String target; + /** + * 当是唯一值的时候直接求出值 + */ + private Object value; + /** + * 数据类型,SINGLE || LIST + */ + private String type; + + public ListParamEntity() { + + } + + public ListParamEntity(String name, Object value) { + this.name = name; + this.value = value; + this.type = LIST; + } + + public ListParamEntity(String name, String target) { + this.name = name; + this.target = target; + this.type = LIST; + } + +} diff --git a/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/word/parse/ParseWord07.java b/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/word/parse/ParseWord07.java new file mode 100644 index 000000000..3ad10c747 --- /dev/null +++ b/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/word/parse/ParseWord07.java @@ -0,0 +1,259 @@ +package com.pig4cloud.pigx.common.poi.word.parse; + +import com.pig4cloud.pigx.common.poi.cache.WordCache; +import com.pig4cloud.pigx.common.poi.util.PoiPublicUtil; +import com.pig4cloud.pigx.common.poi.word.entity.MyXWPFDocument; +import com.pig4cloud.pigx.common.poi.word.entity.WordImageEntity; +import com.pig4cloud.pigx.common.poi.word.entity.params.ExcelListEntity; +import com.pig4cloud.pigx.common.poi.word.parse.excel.ExcelEntityParse; +import com.pig4cloud.pigx.common.poi.word.parse.excel.ExcelMapParse; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.apache.poi.xwpf.usermodel.*; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +/** + * 解析07版的Word,替换文字,生成表格,生成图片 + * + * @author: Luckly + * @date: 2019-05-20 + *

+ */ +@Slf4j +@SuppressWarnings({ "unchecked", "rawtypes" }) +public class ParseWord07 { + + /** + * 添加图片 + * + * @param obj + * @param currentRun + * @throws Exception + */ + private void addAnImage(WordImageEntity obj, XWPFRun currentRun) throws Exception { + Object[] isAndType = PoiPublicUtil.getIsAndType(obj); + String picId; + try { + picId = currentRun.getParagraph().getDocument().addPictureData((byte[]) isAndType[0], (Integer) isAndType[1]); + ((MyXWPFDocument) currentRun.getParagraph().getDocument()).createPicture(currentRun, picId, currentRun.getParagraph().getDocument().getNextPicNameNumber((Integer) isAndType[1]), obj.getWidth(), obj.getHeight()); + + } catch (Exception e) { + log.error(e.getMessage(), e); + } + + } + + /** + * 根据条件改变值 + * + * @param paragraph + * @param currentRun + * @param currentText + * @param runIndex + * @param map + * @throws Exception + */ + private void changeValues(XWPFParagraph paragraph, XWPFRun currentRun, String currentText, List runIndex, Map map) throws Exception { + Object obj = PoiPublicUtil.getRealValue(currentText, map); + if (obj instanceof WordImageEntity) {// 如果是图片就设置为图片 + currentRun.setText("", 0); + addAnImage((WordImageEntity) obj, currentRun); + } else { + currentText = obj.toString(); + currentRun.setText(currentText, 0); + } + for (int k = 0; k < runIndex.size(); k++) { + paragraph.getRuns().get(runIndex.get(k)).setText("", 0); + } + runIndex.clear(); + } + + /** + * 判断是不是迭代输出 + * + * @param cell + * @param map + * @return + * @throws Exception + */ + private Object checkThisTableIsNeedIterator(XWPFTableCell cell, Map map) throws Exception { + String text = cell.getText().trim(); + // 判断是不是迭代输出 + if (text.startsWith("{{") && text.endsWith("}}") && text.indexOf("in ") != -1) { + return PoiPublicUtil.getRealValue(text.replace("in ", "").trim(), map); + } + return null; + } + + /** + * 解析所有的文本 + * + * @param paragraphs + * @param map + * @throws Exception + */ + private void parseAllParagraphic(List paragraphs, Map map) throws Exception { + XWPFParagraph paragraph; + for (int i = 0; i < paragraphs.size(); i++) { + paragraph = paragraphs.get(i); + if (paragraph.getText().indexOf("{{") != -1) { + parseThisParagraph(paragraph, map); + } + + } + + } + + /** + * 解析这个段落 + * @param paragraph + * @param map + * @throws Exception + */ + private void parseThisParagraph(XWPFParagraph paragraph, Map map) throws Exception { + XWPFRun run; + XWPFRun currentRun = null;// 拿到的第一个run,用来set值,可以保存格式 + String currentText = "";// 存放当前的text + String text; + Boolean isfinde = false;// 判断是不是已经遇到{{ + List runIndex = new ArrayList();// 存储遇到的run,把他们置空 + for (int i = 0; i < paragraph.getRuns().size(); i++) { + run = paragraph.getRuns().get(i); + text = run.getText(0); + if (StringUtils.isEmpty(text)) { + continue; + }// 如果为空或者""这种这继续循环跳过 + if (isfinde) { + currentText += text; + if (currentText.indexOf("{{") == -1) { + isfinde = false; + runIndex.clear(); + } else { + runIndex.add(i); + } + if (currentText.indexOf("}}") != -1) { + changeValues(paragraph, currentRun, currentText, runIndex, map); + currentText = ""; + isfinde = false; + } + } else if (text.indexOf("{") >= 0) {// 判断是不是开始 + currentText = text; + isfinde = true; + currentRun = run; + } else { + currentText = ""; + } + if (currentText.indexOf("}}") != -1) { + changeValues(paragraph, currentRun, currentText, runIndex, map); + isfinde = false; + } + } + + } + + private void parseThisRow(List cells, Map map) throws Exception { + for (XWPFTableCell cell : cells) { + parseAllParagraphic(cell.getParagraphs(), map); + } + } + + /** + * 解析这个段落 + * + * @param table + * @param map + * @throws Exception + */ + private void parseThisTable(XWPFTable table, Map map) throws Exception { + XWPFTableRow row; + List cells; + Object listobj; + ExcelEntityParse excelEntityParse = new ExcelEntityParse(); + for (int i = 0; i < table.getNumberOfRows(); i++) { + row = table.getRow(i); + cells = row.getTableCells(); + if (cells.size() == 1) { + listobj = checkThisTableIsNeedIterator(cells.get(0), map); + if (listobj == null) { + parseThisRow(cells, map); + } else if (listobj instanceof ExcelListEntity) { + table.removeRow(i);// 删除这一行 + excelEntityParse.parseNextRowAndAddRow(table, i, (ExcelListEntity) listobj); + } else { + table.removeRow(i);// 删除这一行 + ExcelMapParse.parseNextRowAndAddRow(table, i, (List) listobj); + } + } else { + parseThisRow(cells, map); + } + } + } + + /** + * 解析07版的Word并且进行赋值 + * @param url + * @param map + * @return + * @throws Exception + */ + public XWPFDocument parseWord(String url, Map map) throws Exception { + MyXWPFDocument doc = WordCache.getXWPFDocumen(url); + parseWordSetValue(doc, map); + return doc; + } + + /** + * 解析07版的Word并且进行赋值 + * + * @param document + * @param map + * @throws Exception + */ + public void parseWord(XWPFDocument document, Map map) throws Exception { + parseWordSetValue((MyXWPFDocument) document, map); + } + + private void parseWordSetValue(MyXWPFDocument doc, Map map) throws Exception { + // 第一步解析文档 + parseAllParagraphic(doc.getParagraphs(), map); + // 第二步解析页眉,页脚 + parseHeaderAndFoot(doc, map); + // 第三步解析所有表格 + XWPFTable table; + Iterator itTable = doc.getTablesIterator(); + while (itTable.hasNext()) { + table = itTable.next(); + if (table.getText().indexOf("{{") != -1) { + parseThisTable(table, map); + } + } + + } + + /** + * 解析页眉和页脚 + * + * @param doc + * @param map + * @throws Exception + */ + private void parseHeaderAndFoot(MyXWPFDocument doc, Map map) throws Exception { + List headerList = doc.getHeaderList(); + for (XWPFHeader xwpfHeader : headerList) { + for (int i = 0; i < xwpfHeader.getListParagraph().size(); i++) { + parseThisParagraph(xwpfHeader.getListParagraph().get(i), map); + } + } + List footerList = doc.getFooterList(); + for (XWPFFooter xwpfFooter : footerList) { + for (int i = 0; i < xwpfFooter.getListParagraph().size(); i++) { + parseThisParagraph(xwpfFooter.getListParagraph().get(i), map); + } + } + + } +} diff --git a/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/word/parse/excel/ExcelEntityParse.java b/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/word/parse/excel/ExcelEntityParse.java new file mode 100644 index 000000000..2d194d563 --- /dev/null +++ b/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/word/parse/excel/ExcelEntityParse.java @@ -0,0 +1,217 @@ +package com.pig4cloud.pigx.common.poi.word.parse.excel; + +import com.pig4cloud.pigx.common.poi.excel.annotation.ExcelTarget; +import com.pig4cloud.pigx.common.poi.excel.entity.params.ExcelExportEntity; +import com.pig4cloud.pigx.common.poi.excel.export.base.ExportBase; +import com.pig4cloud.pigx.common.poi.exception.word.WordExportException; +import com.pig4cloud.pigx.common.poi.exception.word.enmus.WordExportEnum; +import com.pig4cloud.pigx.common.poi.util.PoiPublicUtil; +import com.pig4cloud.pigx.common.poi.word.entity.params.ExcelListEntity; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.apache.poi.xwpf.usermodel.XWPFTable; +import org.apache.poi.xwpf.usermodel.XWPFTableCell; +import org.apache.poi.xwpf.usermodel.XWPFTableRow; + +import java.lang.reflect.Field; +import java.util.*; + +/** + * 解析实体类对象 复用注解 + * + * @author: Luckly + * @date: 2019-05-20 + *

+ */ +@Slf4j +public class ExcelEntityParse extends ExportBase { + + private static void checkExcelParams(ExcelListEntity entity) { + if (entity.getList() == null || entity.getClazz() == null) { + throw new WordExportException(WordExportEnum.EXCEL_PARAMS_ERROR); + } + + } + + /** + * createCells + * + * @param index + * @param t + * @param excelParams + * @param table + * @param rowHeight + * @return + * @throws Exception + */ + private int createCells(int index, Object t, List excelParams, XWPFTable table, short rowHeight) throws Exception { + ExcelExportEntity entity; + XWPFTableRow row = table.createRow(); + row.setHeight(rowHeight); + int maxHeight = 1, cellNum = 0; + for (int k = 0, paramSize = excelParams.size(); k < paramSize; k++) { + entity = excelParams.get(k); + if (entity.getList() != null) { + Collection list = (Collection) entity.getMethod().invoke(t, new Object[] {}); + int listC = 0; + for (Object obj : list) { + createListCells(index + listC, cellNum, obj, entity.getList(), table); + listC++; + } + cellNum += entity.getList().size(); + if (list != null && list.size() > maxHeight) { + maxHeight = list.size(); + } + } else { + Object value = getCellValue(entity, t); + if (entity.getType() == 1) { + setCellValue(row, value, cellNum++); + } + } + } + // 合并需要合并的单元格 + cellNum = 0; + for (int k = 0, paramSize = excelParams.size(); k < paramSize; k++) { + entity = excelParams.get(k); + if (entity.getList() != null) { + cellNum += entity.getList().size(); + } else if (entity.isNeedMerge()) { + table.setCellMargins(index, index + maxHeight - 1, cellNum, cellNum); + cellNum++; + } + } + return maxHeight; + } + + /** + * 创建List之后的各个Cells + * + * @param index + * @param cellNum + * @param obj + * @param excelParams + * @param table + * @throws Exception + */ + public void createListCells(int index, int cellNum, Object obj, List excelParams, XWPFTable table) throws Exception { + ExcelExportEntity entity; + XWPFTableRow row; + if (table.getRow(index) == null) { + row = table.createRow(); + row.setHeight(getRowHeight(excelParams)); + } else { + row = table.getRow(index); + } + for (int k = 0, paramSize = excelParams.size(); k < paramSize; k++) { + entity = excelParams.get(k); + Object value = getCellValue(entity, obj); + if (entity.getType() == 1) { + setCellValue(row, value, cellNum++); + } + } + } + + /** + * 获取表头数据 + * + * @param table + * @param index + * @return + */ + private Map getTitleMap(XWPFTable table, int index, int headRows) { + if (index < headRows) { + throw new WordExportException(WordExportEnum.EXCEL_NO_HEAD); + } + Map map = new HashMap(); + String text; + for (int j = 0; j < headRows; j++) { + List cells = table.getRow(index - j - 1).getTableCells(); + for (int i = 0; i < cells.size(); i++) { + text = cells.get(i).getText(); + if (StringUtils.isEmpty(text)) { + throw new WordExportException(WordExportEnum.EXCEL_HEAD_HAVA_NULL); + } + map.put(text, i); + } + } + return map; + } + + /** + * 解析上一行并生成更多行 + * + * @param table + * @param index + * @param entity + */ + public void parseNextRowAndAddRow(XWPFTable table, int index, ExcelListEntity entity) { + checkExcelParams(entity); + // 获取表头数据 + Map titlemap = getTitleMap(table, index, entity.getHeadRows()); + try { + // 得到所有字段 + Field fileds[] = PoiPublicUtil.getClassFields(entity.getClazz()); + ExcelTarget etarget = entity.getClazz().getAnnotation(ExcelTarget.class); + String targetId = null; + if (etarget != null) { + targetId = etarget.value(); + } + // 获取实体对象的导出数据 + List excelParams = new ArrayList(); + getAllExcelField(null, targetId, fileds, excelParams, entity.getClazz(), null); + // 根据表头进行筛选排序 + sortAndFilterExportField(excelParams, titlemap); + short rowHeight = getRowHeight(excelParams); + Iterator its = entity.getList().iterator(); + while (its.hasNext()) { + Object t = its.next(); + index += createCells(index, t, excelParams, table, rowHeight); + } + } catch (Exception e) { + log.error(e.getMessage(), e); + } + } + + /** + * setCellValue + * + * @param row + * @param value + * @param cellNum + */ + private void setCellValue(XWPFTableRow row, Object value, int cellNum) { + if (row.getCell(cellNum++) != null) { + row.getCell(cellNum - 1).setText(value == null ? "" : value.toString()); + } else { + row.createCell().setText(value == null ? "" : value.toString()); + } + } + + /** + * 对导出序列进行排序和塞选 + * + * @param excelParams + * @param titlemap + * @return + */ + private void sortAndFilterExportField(List excelParams, Map titlemap) { + for (int i = excelParams.size() - 1; i >= 0; i--) { + if (excelParams.get(i).getList() != null && excelParams.get(i).getList().size() > 0) { + sortAndFilterExportField(excelParams.get(i).getList(), titlemap); + if (excelParams.get(i).getList().size() == 0) { + excelParams.remove(i); + } else { + excelParams.get(i).setOrderNum(i); + } + } else { + if (titlemap.containsKey(excelParams.get(i).getName())) { + excelParams.get(i).setOrderNum(i); + } else { + excelParams.remove(i); + } + } + } + sortAllParams(excelParams); + } + +} diff --git a/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/word/parse/excel/ExcelMapParse.java b/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/word/parse/excel/ExcelMapParse.java new file mode 100644 index 000000000..dd4d64869 --- /dev/null +++ b/pigx-common/pigx-common-autopoi/src/main/java/com/pig4cloud/pigx/common/poi/word/parse/excel/ExcelMapParse.java @@ -0,0 +1,61 @@ +package com.pig4cloud.pigx.common.poi.word.parse.excel; + +import org.apache.poi.xwpf.usermodel.XWPFTable; +import org.apache.poi.xwpf.usermodel.XWPFTableCell; +import org.apache.poi.xwpf.usermodel.XWPFTableRow; +import com.pig4cloud.pigx.common.poi.util.PoiPublicUtil; + +import java.util.List; + +/** + * 处理和生成Map 类型的数据变成表格 + * + * @author: Luckly + * @date: 2019-05-20 + *

+ */ +public final class ExcelMapParse { + + /** + * 解析参数行,获取参数列表 + * + * @param currentRow + * @return + */ + private static String[] parseCurrentRowGetParams(XWPFTableRow currentRow) { + List cells = currentRow.getTableCells(); + String[] params = new String[cells.size()]; + String text; + for (int i = 0; i < cells.size(); i++) { + text = cells.get(i).getText(); + params[i] = text == null ? "" : text.trim().replace("{{", "").replace("}}", ""); + } + return params; + } + + /** + * 解析下一行,并且生成更多的行 + * + * @param table + * @param index + * @param list + * @throws Exception + */ + public static void parseNextRowAndAddRow(XWPFTable table, int index, List list) throws Exception { + XWPFTableRow currentRow = table.getRow(index); + String[] params = parseCurrentRowGetParams(currentRow); + table.removeRow(index);// 移除这一行 + int cellIndex = 0;// 创建完成对象一行好像多了一个cell + for (Object obj : list) { + currentRow = table.createRow(); + for (cellIndex = 0; cellIndex < currentRow.getTableCells().size(); cellIndex++) { + currentRow.getTableCells().get(cellIndex).setText(PoiPublicUtil.getValueDoWhile(obj, params[cellIndex].split("\\."), 0).toString()); + } + for (; cellIndex < params.length; cellIndex++) { + currentRow.createCell().setText(PoiPublicUtil.getValueDoWhile(obj, params[cellIndex].split("\\."), 0).toString()); + } + } + + } + +} diff --git a/pigx-common/pigx-common-bom/pom.xml b/pigx-common/pigx-common-bom/pom.xml index 38a0aa873..1421909af 100644 --- a/pigx-common/pigx-common-bom/pom.xml +++ b/pigx-common/pigx-common-bom/pom.xml @@ -27,6 +27,11 @@ + + com.pig4cloud + pigx-common-autopoi + ${pigx.version} + com.pig4cloud pigx-common-core diff --git a/pigx-common/pom.xml b/pigx-common/pom.xml index 829f9c872..e4603a538 100644 --- a/pigx-common/pom.xml +++ b/pigx-common/pom.xml @@ -43,5 +43,6 @@ pigx-common-security pigx-common-swagger pigx-common-transaction + pigx-common-autopoi diff --git a/pom.xml b/pom.xml index 0b6ee4f83..55950c0bd 100644 --- a/pom.xml +++ b/pom.xml @@ -56,6 +56,7 @@ 2.10.0 1.7 4.1.0 + 3.15 2.1.1 2.10.2 6.0.4 @@ -124,6 +125,23 @@ + + + org.apache.poi + poi + ${poi.version} + + + org.apache.poi + poi-ooxml + ${poi.version} + + + org.apache.poi + poi-ooxml-schemas + ${poi.version} + + org.springframework.boot spring-boot-dependencies From 6eaa933fde733e858784e1778ff341be3feec104 Mon Sep 17 00:00:00 2001 From: Lucky0829 <641787296@qq.com> Date: Tue, 21 May 2019 14:22:08 +0800 Subject: [PATCH 2/7] =?UTF-8?q?:zap:=20=E4=BC=98=E5=8C=96.=20=E5=85=AC?= =?UTF-8?q?=E5=85=B1=E5=8F=82=E6=95=B0=E5=BC=95=E5=85=A5=E5=AF=BC=E5=85=A5?= =?UTF-8?q?=E5=AF=BC=E5=87=BA=E6=A1=88=E4=BE=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pigx-upms/pigx-upms-api/pom.xml | 4 + .../pigx/admin/api/entity/SysPublicParam.java | 36 +++++-- .../controller/SysPublicParamController.java | 93 ++++++++++++++++++- 3 files changed, 120 insertions(+), 13 deletions(-) diff --git a/pigx-upms/pigx-upms-api/pom.xml b/pigx-upms/pigx-upms-api/pom.xml index df9f82ff2..4e1639c5f 100644 --- a/pigx-upms/pigx-upms-api/pom.xml +++ b/pigx-upms/pigx-upms-api/pom.xml @@ -44,5 +44,9 @@ com.baomidou mybatis-plus-extension + + com.pig4cloud + pigx-common-autopoi + diff --git a/pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/entity/SysPublicParam.java b/pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/entity/SysPublicParam.java index 055862894..773da7f22 100644 --- a/pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/entity/SysPublicParam.java +++ b/pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/entity/SysPublicParam.java @@ -20,12 +20,15 @@ package com.pig4cloud.pigx.admin.api.entity; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableLogic; import com.baomidou.mybatisplus.extension.activerecord.Model; +import com.fasterxml.jackson.annotation.JsonFormat; +import com.pig4cloud.pigx.common.poi.excel.annotation.Excel; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Data; import lombok.EqualsAndHashCode; +import org.springframework.format.annotation.DateTimeFormat; -import java.time.LocalDateTime; +import java.util.Date; /** * 公共参数配置 @@ -49,18 +52,21 @@ public class SysPublicParam extends Model { * 公共参数名称 */ @ApiModelProperty(value = "公共参数名称", required = true, example = "公共参数名称") + @Excel(name = "名称", width = 15) private String publicName; /** * 公共参数地址值,英文大写+下划线 */ @ApiModelProperty(value = "键[英文大写+下划线]", required = true, example = "PIGX_PUBLIC_KEY") + @Excel(name = "键", width = 15) private String publicKey; /** * 值 */ @ApiModelProperty(value = "值", required = true, example = "999") + @Excel(name = "值", width = 15) private String publicValue; /** @@ -80,29 +86,43 @@ public class SysPublicParam extends Model { * 公共参数编码 */ @ApiModelProperty(value = "编码", example = "^(PIG|PIGX)$") + @Excel(name = "编码", width = 15) private String validateCode; /** * 创建时间 */ @ApiModelProperty(value = "创建时间", example = "2019-03-21 12:28:48") - private LocalDateTime createTime; - - /** - * 是否是系统内置 - */ - private String system; + @Excel(name = "创建时间", width = 20, format = "yyyy-MM-dd HH:mm:ss") + @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private Date createTime; /** * 修改时间 */ @ApiModelProperty(value = "修改时间", example = "2019-03-21 12:28:48") - private LocalDateTime updateTime; + //TODO 待处理 时间导入导出 java.util.Date类型,java.time.LocalDateTime报错 + //时间格式三要素:Excel JsonFormat DateTimeFormat + @Excel(name = "修改时间", width = 20, format = "yyyy-MM-dd HH:mm:ss") + @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private Date updateTime; + + /** + * 是否是系统内置 + */ + @ApiModelProperty(value = "是否是系统内置") + @Excel(name = "备注", width = 15) + private String system; + + /** * 配置类型:0-默认;1-检索;2-原文;3-报表;4-安全;5-文档;6-消息;9-其他 */ @ApiModelProperty(value = "类型[1-检索;2-原文...]", example = "1") + @Excel(name = "配置类型", width = 15) private String publicType; diff --git a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/controller/SysPublicParamController.java b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/controller/SysPublicParamController.java index f8aac1f39..66c0e041d 100644 --- a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/controller/SysPublicParamController.java +++ b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/controller/SysPublicParamController.java @@ -17,22 +17,29 @@ package com.pig4cloud.pigx.admin.controller; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.pig4cloud.pigx.admin.api.entity.SysPublicParam; import com.pig4cloud.pigx.admin.service.SysPublicParamService; -import com.pig4cloud.pigx.common.core.constant.CacheConstants; import com.pig4cloud.pigx.common.core.util.R; import com.pig4cloud.pigx.common.log.annotation.SysLog; +import com.pig4cloud.pigx.common.poi.excel.ExcelImportUtil; +import com.pig4cloud.pigx.common.poi.excel.def.NormalExcelConstants; +import com.pig4cloud.pigx.common.poi.excel.entity.ExportParams; +import com.pig4cloud.pigx.common.poi.excel.entity.ImportParams; +import com.pig4cloud.pigx.common.poi.excel.view.PigxEntityExcelView; import com.pig4cloud.pigx.common.security.annotation.Inner; import io.swagger.annotations.Api; -import io.swagger.annotations.ApiImplicitParam; -import io.swagger.annotations.ApiImplicitParams; import io.swagger.annotations.ApiOperation; import lombok.AllArgsConstructor; -import org.springframework.cache.annotation.CacheEvict; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; +import org.springframework.web.servlet.ModelAndView; + +import java.io.IOException; +import java.util.List; /** @@ -57,7 +64,6 @@ public class SysPublicParamController { */ @Inner(value = false) @ApiOperation(value = "查询公共参数值", notes = "根据key查询公共参数值") - @ApiImplicitParams({@ApiImplicitParam(name = "publicKey", value = "键值,譬如:VERSION_INSTRUCTIONS", required = true)}) @GetMapping("/publicValue/{publicKey}") public R publicKey(@PathVariable("publicKey") String publicKey) { return R.ok(sysPublicParamService.getSysPublicParamKeyToValue(publicKey)); @@ -70,6 +76,7 @@ public class SysPublicParamController { * @param sysPublicParam 公共参数 * @return */ + @ApiOperation(value = "分页查询", notes = "分页查询") @GetMapping("/page") public R getSysPublicParamPage(Page page, SysPublicParam sysPublicParam) { return R.ok(sysPublicParamService.page(page, Wrappers.query(sysPublicParam))); @@ -82,6 +89,7 @@ public class SysPublicParamController { * @param publicId id * @return R */ + @ApiOperation(value = "通过id查询公共参数", notes = "通过id查询公共参数") @GetMapping("/{publicId}") public R getById(@PathVariable("publicId") Long publicId) { return R.ok(sysPublicParamService.getById(publicId)); @@ -93,6 +101,7 @@ public class SysPublicParamController { * @param sysPublicParam 公共参数 * @return R */ + @ApiOperation(value = "新增公共参数", notes = "新增公共参数") @SysLog("新增公共参数") @PostMapping @PreAuthorize("@pms.hasPermission('admin_syspublicparam_add')") @@ -106,6 +115,7 @@ public class SysPublicParamController { * @param sysPublicParam 公共参数 * @return R */ + @ApiOperation(value = "修改公共参数", notes = "修改公共参数") @SysLog("修改公共参数") @PutMapping @PreAuthorize("@pms.hasPermission('admin_syspublicparam_edit')") @@ -119,6 +129,7 @@ public class SysPublicParamController { * @param publicId id * @return R */ + @ApiOperation(value = "删除公共参数", notes = "删除公共参数") @SysLog("删除公共参数") @DeleteMapping("/{publicId}") @PreAuthorize("@pms.hasPermission('admin_syspublicparam_del')") @@ -126,4 +137,76 @@ public class SysPublicParamController { return sysPublicParamService.removeParam(publicId); } + + /** + * 导出excel + * + */ + //临时接口调试开启Inner + @Inner(value = false) + @SysLog("导出excel数据") + @ApiOperation(value = "导出excel数据", notes = "导出excel数据") + @GetMapping(value = "/exportXls") +// @PostMapping(value = "/exportXls") + public ModelAndView exportXls() { + // Step.1 组装查询条件 + // TODO 后续封装完成 通用查询条件 包含权限、排序、普通检索、高级检索 QueryGenerator.initQueryWrapper(...); + QueryWrapper queryWrapper = null; + queryWrapper = Wrappers.query(); + + // Step.2 AutoPoi 导出Excel + ModelAndView mv = new ModelAndView(new PigxEntityExcelView()); + List pageList = sysPublicParamService.list(Wrappers.query()); + + //Step.3 导出文件名称 + mv.addObject(NormalExcelConstants.FILE_NAME, "参数配置列表"); + mv.addObject(NormalExcelConstants.CLASS, SysPublicParam.class); + mv.addObject(NormalExcelConstants.PARAMS, new ExportParams("参数配置列表数据", "导出人:pigx", "导出信息")); + mv.addObject(NormalExcelConstants.DATA_LIST, pageList); + return mv; + } + + /** + * 通过excel导入数据 + * + * @param file + * @return + */ + //临时接口调试开启Inner + @Inner(value = false) + @SysLog("导入excel数据") + @ApiOperation(value = "导入excel数据", notes = "导入excel数据") + @PostMapping(value = "/importExcel") + public R importExcel(@RequestParam("file") MultipartFile file) { +// HttpServletRequest request +// MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request; +// Map fileMap = multipartRequest.getFileMap(); + //for (Map.Entry entity : fileMap.entrySet()) { + // 获取上传文件对象 + //MultipartFile file = entity.getValue(); + ImportParams params = new ImportParams(); + params.setTitleRows(2); + params.setHeadRows(1); + params.setNeedSave(true); + try { + List listSysPublicParams = null; + if(file.getInputStream() != null){ + listSysPublicParams = ExcelImportUtil.importExcel(file.getInputStream(), SysPublicParam.class, params); + for (SysPublicParam sysPublicParamExcel : listSysPublicParams) { + sysPublicParamService.save(sysPublicParamExcel); + } + } + + return R.ok("文件导入成功!数据行数:" + listSysPublicParams.size()); + } catch (Exception e) { + return R.failed("文件导入失败!"); + } finally { + try { + file.getInputStream().close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + //} + } } From 896dbdeb404bb9ff572a375f537a8a3b43f73e85 Mon Sep 17 00:00:00 2001 From: Lucky <641787296@qq.com> Date: Tue, 21 May 2019 23:57:40 +0800 Subject: [PATCH 3/7] =?UTF-8?q?:sparkles:=20=E6=B7=BB=E5=8A=A0=E6=96=B0?= =?UTF-8?q?=E7=89=B9=E6=80=A7=E3=80=82pigx=20=E5=8A=A8=E6=80=81=E5=88=87?= =?UTF-8?q?=E6=8D=A2=E6=95=B0=E6=8D=AE=E6=BA=90=EF=BC=8C=E4=B8=BA=E5=90=8E?= =?UTF-8?q?=E6=9C=9F=E6=8F=90=E4=BE=9BOnline=E5=BC=80=E5=8F=91=E3=80=81?= =?UTF-8?q?=E6=95=B0=E6=8D=AE=E5=90=8C=E6=AD=A5=E4=BB=A5=E5=8F=8A=E8=AF=BB?= =?UTF-8?q?=E5=86=99=E5=88=86=E7=A6=BB=E5=81=9A=E5=87=86=E5=A4=87?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pigx-common/pigx-common-bom/pom.xml | 5 + pigx-common/pigx-common-datasource/pom.xml | 106 ++++++++++++++++++ .../DataSourceAutoConfiguration.java | 16 +++ .../annotation/EnableDynamicDataSource.java | 20 ++++ .../config/DruidDataSourceProperties.java | 2 +- .../datasource}/config/DynamicDataSource.java | 4 +- .../config/DynamicDataSourceConfig.java | 15 ++- .../config/DynamicDatasourceInterceptor.java | 43 +++++++ .../support}/DataSourceConstants.java | 2 +- .../DynamicDataSourceContextHolder.java | 20 +++- .../main/resources/META-INF/spring.factories | 2 + pigx-common/pom.xml | 1 + 12 files changed, 221 insertions(+), 15 deletions(-) create mode 100644 pigx-common/pigx-common-datasource/pom.xml create mode 100644 pigx-common/pigx-common-datasource/src/main/java/com/pig4cloud/pigx/common/datasource/DataSourceAutoConfiguration.java create mode 100644 pigx-common/pigx-common-datasource/src/main/java/com/pig4cloud/pigx/common/datasource/annotation/EnableDynamicDataSource.java rename {pigx-visual/pigx-codegen/src/main/java/com/pig4cloud/pigx/codegen => pigx-common/pigx-common-datasource/src/main/java/com/pig4cloud/pigx/common/datasource}/config/DruidDataSourceProperties.java (89%) rename {pigx-visual/pigx-codegen/src/main/java/com/pig4cloud/pigx/codegen => pigx-common/pigx-common-datasource/src/main/java/com/pig4cloud/pigx/common/datasource}/config/DynamicDataSource.java (75%) rename {pigx-visual/pigx-codegen/src/main/java/com/pig4cloud/pigx/codegen => pigx-common/pigx-common-datasource/src/main/java/com/pig4cloud/pigx/common/datasource}/config/DynamicDataSourceConfig.java (96%) create mode 100644 pigx-common/pigx-common-datasource/src/main/java/com/pig4cloud/pigx/common/datasource/config/DynamicDatasourceInterceptor.java rename {pigx-visual/pigx-codegen/src/main/java/com/pig4cloud/pigx/codegen/util => pigx-common/pigx-common-datasource/src/main/java/com/pig4cloud/pigx/common/datasource/support}/DataSourceConstants.java (90%) rename {pigx-visual/pigx-codegen/src/main/java/com/pig4cloud/pigx/codegen/util => pigx-common/pigx-common-datasource/src/main/java/com/pig4cloud/pigx/common/datasource/support}/DynamicDataSourceContextHolder.java (54%) create mode 100644 pigx-common/pigx-common-datasource/src/main/resources/META-INF/spring.factories diff --git a/pigx-common/pigx-common-bom/pom.xml b/pigx-common/pigx-common-bom/pom.xml index 1421909af..d75cfa8b2 100644 --- a/pigx-common/pigx-common-bom/pom.xml +++ b/pigx-common/pigx-common-bom/pom.xml @@ -47,6 +47,11 @@ pigx-common-gateway ${pigx.version} + + com.pig4cloud + pigx-common-datasource + ${pigx.version} + com.pig4cloud pigx-common-job diff --git a/pigx-common/pigx-common-datasource/pom.xml b/pigx-common/pigx-common-datasource/pom.xml new file mode 100644 index 000000000..b2d9e0a6c --- /dev/null +++ b/pigx-common/pigx-common-datasource/pom.xml @@ -0,0 +1,106 @@ + + + + pigx-common + com.pig4cloud + 3.0.0 + + 4.0.0 + + com.pig4cloud + pigx-common-datasource + + jar + + pigx 动态切换数据源,为后期提供Online在线开发、读写分离、数据同步做好准备 + + + + org.springframework.boot + spring-boot-starter-jdbc + + + javax.servlet + javax.servlet-api + + + org.springframework + spring-webmvc + + + + com.pig4cloud + pigx-common-core + + + + + com.pig4cloud + pigx-common-data + + + + com.baomidou + mybatis-plus-boot-starter + + + mysql + mysql-connector-java + + + + com.alibaba + druid-spring-boot-starter + + + + com.pig4cloud + pigx-common-core + + + + com.pig4cloud + pigx-common-swagger + + + + com.pig4cloud + pigx-common-security + + + com.pig4cloud + pigx-common-log + + + + velocity + org.apache.velocity + ${velocity.version} + + + + org.springframework.boot + spring-boot-starter-web + + + + org.springframework.boot + spring-boot-starter-undertow + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + com.spotify + docker-maven-plugin + + + + \ No newline at end of file diff --git a/pigx-common/pigx-common-datasource/src/main/java/com/pig4cloud/pigx/common/datasource/DataSourceAutoConfiguration.java b/pigx-common/pigx-common-datasource/src/main/java/com/pig4cloud/pigx/common/datasource/DataSourceAutoConfiguration.java new file mode 100644 index 000000000..8729bc376 --- /dev/null +++ b/pigx-common/pigx-common-datasource/src/main/java/com/pig4cloud/pigx/common/datasource/DataSourceAutoConfiguration.java @@ -0,0 +1,16 @@ +package com.pig4cloud.pigx.common.datasource; + +import com.pig4cloud.pigx.common.datasource.config.DruidDataSourceProperties; +import lombok.AllArgsConstructor; +import org.springframework.boot.context.properties.EnableConfigurationProperties; + +/** + * @author Lucky + * @date 2019-05-18 + *

+ * DbAcess 自动配置类 + */ +@AllArgsConstructor +@EnableConfigurationProperties({DruidDataSourceProperties.class}) +public class DataSourceAutoConfiguration { +} diff --git a/pigx-common/pigx-common-datasource/src/main/java/com/pig4cloud/pigx/common/datasource/annotation/EnableDynamicDataSource.java b/pigx-common/pigx-common-datasource/src/main/java/com/pig4cloud/pigx/common/datasource/annotation/EnableDynamicDataSource.java new file mode 100644 index 000000000..99ebdbd6d --- /dev/null +++ b/pigx-common/pigx-common-datasource/src/main/java/com/pig4cloud/pigx/common/datasource/annotation/EnableDynamicDataSource.java @@ -0,0 +1,20 @@ +package com.pig4cloud.pigx.common.datasource.annotation; + +import com.pig4cloud.pigx.common.datasource.config.DynamicDataSourceConfig; +import org.springframework.context.annotation.Import; + +import java.lang.annotation.*; + +/** + * @author Lucky + * @date 2019-05-18 + *

+ * 开启动态数据源 + */ +@Target({ElementType.TYPE}) +@Retention(RetentionPolicy.RUNTIME) +@Documented +@Inherited +@Import({DynamicDataSourceConfig.class}) +public @interface EnableDynamicDataSource { +} diff --git a/pigx-visual/pigx-codegen/src/main/java/com/pig4cloud/pigx/codegen/config/DruidDataSourceProperties.java b/pigx-common/pigx-common-datasource/src/main/java/com/pig4cloud/pigx/common/datasource/config/DruidDataSourceProperties.java similarity index 89% rename from pigx-visual/pigx-codegen/src/main/java/com/pig4cloud/pigx/codegen/config/DruidDataSourceProperties.java rename to pigx-common/pigx-common-datasource/src/main/java/com/pig4cloud/pigx/common/datasource/config/DruidDataSourceProperties.java index d80228ef8..efb00821c 100644 --- a/pigx-visual/pigx-codegen/src/main/java/com/pig4cloud/pigx/codegen/config/DruidDataSourceProperties.java +++ b/pigx-common/pigx-common-datasource/src/main/java/com/pig4cloud/pigx/common/datasource/config/DruidDataSourceProperties.java @@ -1,4 +1,4 @@ -package com.pig4cloud.pigx.codegen.config; +package com.pig4cloud.pigx.common.datasource.config; import lombok.Data; import org.springframework.boot.context.properties.ConfigurationProperties; diff --git a/pigx-visual/pigx-codegen/src/main/java/com/pig4cloud/pigx/codegen/config/DynamicDataSource.java b/pigx-common/pigx-common-datasource/src/main/java/com/pig4cloud/pigx/common/datasource/config/DynamicDataSource.java similarity index 75% rename from pigx-visual/pigx-codegen/src/main/java/com/pig4cloud/pigx/codegen/config/DynamicDataSource.java rename to pigx-common/pigx-common-datasource/src/main/java/com/pig4cloud/pigx/common/datasource/config/DynamicDataSource.java index 252b8d87f..557b5d236 100644 --- a/pigx-visual/pigx-codegen/src/main/java/com/pig4cloud/pigx/codegen/config/DynamicDataSource.java +++ b/pigx-common/pigx-common-datasource/src/main/java/com/pig4cloud/pigx/common/datasource/config/DynamicDataSource.java @@ -1,6 +1,6 @@ -package com.pig4cloud.pigx.codegen.config; +package com.pig4cloud.pigx.common.datasource.config; -import com.pig4cloud.pigx.codegen.util.DynamicDataSourceContextHolder; +import com.pig4cloud.pigx.common.datasource.support.DynamicDataSourceContextHolder; import lombok.extern.slf4j.Slf4j; import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource; diff --git a/pigx-visual/pigx-codegen/src/main/java/com/pig4cloud/pigx/codegen/config/DynamicDataSourceConfig.java b/pigx-common/pigx-common-datasource/src/main/java/com/pig4cloud/pigx/common/datasource/config/DynamicDataSourceConfig.java similarity index 96% rename from pigx-visual/pigx-codegen/src/main/java/com/pig4cloud/pigx/codegen/config/DynamicDataSourceConfig.java rename to pigx-common/pigx-common-datasource/src/main/java/com/pig4cloud/pigx/common/datasource/config/DynamicDataSourceConfig.java index 88bf9ca93..b0d0d22df 100644 --- a/pigx-visual/pigx-codegen/src/main/java/com/pig4cloud/pigx/codegen/config/DynamicDataSourceConfig.java +++ b/pigx-common/pigx-common-datasource/src/main/java/com/pig4cloud/pigx/common/datasource/config/DynamicDataSourceConfig.java @@ -1,8 +1,13 @@ -package com.pig4cloud.pigx.codegen.config; +package com.pig4cloud.pigx.common.datasource.config; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import javax.annotation.PostConstruct; import com.alibaba.druid.pool.DruidDataSource; import com.mysql.cj.jdbc.Driver; -import com.pig4cloud.pigx.codegen.util.DataSourceConstants; +import com.pig4cloud.pigx.common.datasource.support.DataSourceConstants; import lombok.AllArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.jasypt.encryption.StringEncryptor; @@ -14,12 +19,6 @@ import org.springframework.jdbc.datasource.DriverManagerDataSource; import org.springframework.transaction.PlatformTransactionManager; import org.springframework.transaction.annotation.TransactionManagementConfigurer; -import javax.annotation.PostConstruct; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Optional; - /** * @author lengleng * @date 2019-03-31 diff --git a/pigx-common/pigx-common-datasource/src/main/java/com/pig4cloud/pigx/common/datasource/config/DynamicDatasourceInterceptor.java b/pigx-common/pigx-common-datasource/src/main/java/com/pig4cloud/pigx/common/datasource/config/DynamicDatasourceInterceptor.java new file mode 100644 index 000000000..af25dc51d --- /dev/null +++ b/pigx-common/pigx-common-datasource/src/main/java/com/pig4cloud/pigx/common/datasource/config/DynamicDatasourceInterceptor.java @@ -0,0 +1,43 @@ +package com.pig4cloud.pigx.common.datasource.config; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import com.pig4cloud.pigx.common.datasource.support.DynamicDataSourceContextHolder; +import lombok.AllArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.data.redis.core.HashOperations; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer; +import org.springframework.lang.Nullable; +import org.springframework.stereotype.Component; +import org.springframework.web.servlet.HandlerInterceptor; + +/** + * @author lengleng + * @date 2019-05-18 + *

+ * 动态数据源拦截器 + */ +@Slf4j +@Component +@AllArgsConstructor +public class DynamicDatasourceInterceptor implements HandlerInterceptor { + private final RedisTemplate redisTemplate; + + @Override + public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) { + redisTemplate.setHashValueSerializer(new Jackson2JsonRedisSerializer<>(String.class)); + HashOperations vo = redisTemplate.opsForHash(); +// String dbName = vo.get("db_route_key", 1); + DynamicDataSourceContextHolder.setDataSourceType(1); + log.info("数据源切换:{}", 1); + return true; + } + + @Override + public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, + @Nullable Exception ex) { + DynamicDataSourceContextHolder.clearDataSourceType(); + } + +} diff --git a/pigx-visual/pigx-codegen/src/main/java/com/pig4cloud/pigx/codegen/util/DataSourceConstants.java b/pigx-common/pigx-common-datasource/src/main/java/com/pig4cloud/pigx/common/datasource/support/DataSourceConstants.java similarity index 90% rename from pigx-visual/pigx-codegen/src/main/java/com/pig4cloud/pigx/codegen/util/DataSourceConstants.java rename to pigx-common/pigx-common-datasource/src/main/java/com/pig4cloud/pigx/common/datasource/support/DataSourceConstants.java index 9bc663d87..7c9502ad6 100644 --- a/pigx-visual/pigx-codegen/src/main/java/com/pig4cloud/pigx/codegen/util/DataSourceConstants.java +++ b/pigx-common/pigx-common-datasource/src/main/java/com/pig4cloud/pigx/common/datasource/support/DataSourceConstants.java @@ -1,4 +1,4 @@ -package com.pig4cloud.pigx.codegen.util; +package com.pig4cloud.pigx.common.datasource.support; /** * @author lengleng diff --git a/pigx-visual/pigx-codegen/src/main/java/com/pig4cloud/pigx/codegen/util/DynamicDataSourceContextHolder.java b/pigx-common/pigx-common-datasource/src/main/java/com/pig4cloud/pigx/common/datasource/support/DynamicDataSourceContextHolder.java similarity index 54% rename from pigx-visual/pigx-codegen/src/main/java/com/pig4cloud/pigx/codegen/util/DynamicDataSourceContextHolder.java rename to pigx-common/pigx-common-datasource/src/main/java/com/pig4cloud/pigx/common/datasource/support/DynamicDataSourceContextHolder.java index 4e0c2d546..d082585d4 100644 --- a/pigx-visual/pigx-codegen/src/main/java/com/pig4cloud/pigx/codegen/util/DynamicDataSourceContextHolder.java +++ b/pigx-common/pigx-common-datasource/src/main/java/com/pig4cloud/pigx/common/datasource/support/DynamicDataSourceContextHolder.java @@ -1,25 +1,39 @@ -package com.pig4cloud.pigx.codegen.util; +package com.pig4cloud.pigx.common.datasource.support; import lombok.experimental.UtilityClass; /** * @author lengleng - * @date 2019-03-31 + * @date 2019-05-18 *

- * 保存上线文中数据库路由 + * 根据当前线程来选择具体的数据源 */ @UtilityClass public class DynamicDataSourceContextHolder { private final ThreadLocal CONTEXT_HOLDER = new ThreadLocal<>(); + /** + * 提供给AOP去设置当前的线程的数据源的信息 + * + * @param dataSourceType + */ public void setDataSourceType(Integer dataSourceType) { CONTEXT_HOLDER.set(dataSourceType); } + /** + * 提供给AbstractRoutingDataSource的实现类,通过key选择数据源 + * + * @return + */ public Integer getDataSourceType() { return CONTEXT_HOLDER.get(); } + /** + * 使用默认的数据源 + * + */ public void clearDataSourceType() { CONTEXT_HOLDER.remove(); } diff --git a/pigx-common/pigx-common-datasource/src/main/resources/META-INF/spring.factories b/pigx-common/pigx-common-datasource/src/main/resources/META-INF/spring.factories new file mode 100644 index 000000000..15efe41d9 --- /dev/null +++ b/pigx-common/pigx-common-datasource/src/main/resources/META-INF/spring.factories @@ -0,0 +1,2 @@ +org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ + com.pig4cloud.pigx.common.datasource.DataSourceAutoConfiguration \ No newline at end of file diff --git a/pigx-common/pom.xml b/pigx-common/pom.xml index e4603a538..4148d1937 100644 --- a/pigx-common/pom.xml +++ b/pigx-common/pom.xml @@ -44,5 +44,6 @@ pigx-common-swagger pigx-common-transaction pigx-common-autopoi + pigx-common-datasource From 23babe67a92ac48776f428fe528e6cabe7c03e08 Mon Sep 17 00:00:00 2001 From: Lucky <641787296@qq.com> Date: Tue, 21 May 2019 23:59:10 +0800 Subject: [PATCH 4/7] =?UTF-8?q?:recycle:=20=E9=87=8D=E6=9E=84=E4=BB=A3?= =?UTF-8?q?=E7=A0=81=20.=20=E5=8A=A8=E6=80=81=E6=95=B0=E6=8D=AE=E6=BA=90?= =?UTF-8?q?=E4=B8=BA=E4=BE=9D=E8=B5=96=E5=8C=85=E5=BC=95=E5=85=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pigx-visual/pigx-codegen/pom.xml | 4 ++-- .../com/pig4cloud/pigx/codegen/PigxCodeGenApplication.java | 2 ++ .../codegen/service/impl/SysDatasourceConfServiceImpl.java | 2 +- .../pigx/codegen/service/impl/SysGeneratorServiceImpl.java | 2 +- 4 files changed, 6 insertions(+), 4 deletions(-) diff --git a/pigx-visual/pigx-codegen/pom.xml b/pigx-visual/pigx-codegen/pom.xml index 0d3abe201..c2e9352f7 100755 --- a/pigx-visual/pigx-codegen/pom.xml +++ b/pigx-visual/pigx-codegen/pom.xml @@ -25,10 +25,10 @@ org.springframework.cloud spring-cloud-starter-alibaba-nacos-config - + com.pig4cloud - pigx-common-data + pigx-common-datasource diff --git a/pigx-visual/pigx-codegen/src/main/java/com/pig4cloud/pigx/codegen/PigxCodeGenApplication.java b/pigx-visual/pigx-codegen/src/main/java/com/pig4cloud/pigx/codegen/PigxCodeGenApplication.java index 25a8ae599..7fc8ef8a8 100755 --- a/pigx-visual/pigx-codegen/src/main/java/com/pig4cloud/pigx/codegen/PigxCodeGenApplication.java +++ b/pigx-visual/pigx-codegen/src/main/java/com/pig4cloud/pigx/codegen/PigxCodeGenApplication.java @@ -17,6 +17,7 @@ package com.pig4cloud.pigx.codegen; +import com.pig4cloud.pigx.common.datasource.annotation.EnableDynamicDataSource; import com.pig4cloud.pigx.common.security.annotation.EnablePigxFeignClients; import com.pig4cloud.pigx.common.security.annotation.EnablePigxResourceServer; import com.pig4cloud.pigx.common.swagger.annotation.EnablePigxSwagger2; @@ -28,6 +29,7 @@ import org.springframework.cloud.client.SpringCloudApplication; * @date 2018/07/29 * 代码生成模块 */ +@EnableDynamicDataSource //开启动态数据源 @EnablePigxSwagger2 @SpringCloudApplication @EnablePigxFeignClients diff --git a/pigx-visual/pigx-codegen/src/main/java/com/pig4cloud/pigx/codegen/service/impl/SysDatasourceConfServiceImpl.java b/pigx-visual/pigx-codegen/src/main/java/com/pig4cloud/pigx/codegen/service/impl/SysDatasourceConfServiceImpl.java index 74e923eb3..384ce0479 100755 --- a/pigx-visual/pigx-codegen/src/main/java/com/pig4cloud/pigx/codegen/service/impl/SysDatasourceConfServiceImpl.java +++ b/pigx-visual/pigx-codegen/src/main/java/com/pig4cloud/pigx/codegen/service/impl/SysDatasourceConfServiceImpl.java @@ -18,10 +18,10 @@ package com.pig4cloud.pigx.codegen.service.impl; import cn.hutool.core.util.StrUtil; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; -import com.pig4cloud.pigx.codegen.config.DynamicDataSourceConfig; import com.pig4cloud.pigx.codegen.entity.SysDatasourceConf; import com.pig4cloud.pigx.codegen.mapper.SysDatasourceConfMapper; import com.pig4cloud.pigx.codegen.service.SysDatasourceConfService; +import com.pig4cloud.pigx.common.datasource.config.DynamicDataSourceConfig; import lombok.AllArgsConstructor; import org.jasypt.encryption.StringEncryptor; import org.springframework.stereotype.Service; diff --git a/pigx-visual/pigx-codegen/src/main/java/com/pig4cloud/pigx/codegen/service/impl/SysGeneratorServiceImpl.java b/pigx-visual/pigx-codegen/src/main/java/com/pig4cloud/pigx/codegen/service/impl/SysGeneratorServiceImpl.java index ec5a5a8ee..6ca497974 100755 --- a/pigx-visual/pigx-codegen/src/main/java/com/pig4cloud/pigx/codegen/service/impl/SysGeneratorServiceImpl.java +++ b/pigx-visual/pigx-codegen/src/main/java/com/pig4cloud/pigx/codegen/service/impl/SysGeneratorServiceImpl.java @@ -23,8 +23,8 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.pig4cloud.pigx.codegen.entity.GenConfig; import com.pig4cloud.pigx.codegen.mapper.SysGeneratorMapper; import com.pig4cloud.pigx.codegen.service.SysGeneratorService; -import com.pig4cloud.pigx.codegen.util.DynamicDataSourceContextHolder; import com.pig4cloud.pigx.codegen.util.GenUtils; +import com.pig4cloud.pigx.common.datasource.support.DynamicDataSourceContextHolder; import lombok.AllArgsConstructor; import org.springframework.stereotype.Service; From 439dceb9ba4b9f213b04f3b2fc9dba14e10ec347 Mon Sep 17 00:00:00 2001 From: pigxcloud <2270033969@qq.com> Date: Wed, 22 May 2019 17:30:49 +0800 Subject: [PATCH 5/7] =?UTF-8?q?:sparkles:=20=E6=B7=BB=E5=8A=A0=E6=96=B0?= =?UTF-8?q?=E7=89=B9=E6=80=A7=E3=80=82=E6=97=A5=E5=BF=97=E8=87=AA=E5=8A=A8?= =?UTF-8?q?=E7=BB=B4=E6=8A=A4=E5=88=B0spring=20boot=20admin=20web=20consol?= =?UTF-8?q?e?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../init/ApplicationLoggerInitializer.java | 24 +++++++++++++++++++ .../main/resources/META-INF/spring.factories | 2 ++ .../src/main/resources/logback-spring.xml | 3 ++- 3 files changed, 28 insertions(+), 1 deletion(-) create mode 100644 pigx-common/pigx-common-log/src/main/java/com/pig4cloud/pigx/common/log/init/ApplicationLoggerInitializer.java diff --git a/pigx-common/pigx-common-log/src/main/java/com/pig4cloud/pigx/common/log/init/ApplicationLoggerInitializer.java b/pigx-common/pigx-common-log/src/main/java/com/pig4cloud/pigx/common/log/init/ApplicationLoggerInitializer.java new file mode 100644 index 000000000..66a8db320 --- /dev/null +++ b/pigx-common/pigx-common-log/src/main/java/com/pig4cloud/pigx/common/log/init/ApplicationLoggerInitializer.java @@ -0,0 +1,24 @@ +package com.pig4cloud.pigx.common.log.init; + +import org.springframework.context.ApplicationContextInitializer; +import org.springframework.context.ConfigurableApplicationContext; +import org.springframework.core.env.ConfigurableEnvironment; + +/** + * @author lengleng + * @date 2019-05-22 + *

+ * 初始化日志路径 + */ +public class ApplicationLoggerInitializer implements ApplicationContextInitializer { + @Override + public void initialize(ConfigurableApplicationContext applicationContext) { + ConfigurableEnvironment environment = applicationContext.getEnvironment(); + + String appName = environment.getProperty("spring.application.name"); + + String logBase = environment.getProperty("LOGGING_PATH", "logs"); + // spring boot admin 直接加载日志 + System.setProperty("logging.file", String.format("%s/%s/debug.log", logBase, appName)); + } +} diff --git a/pigx-common/pigx-common-log/src/main/resources/META-INF/spring.factories b/pigx-common/pigx-common-log/src/main/resources/META-INF/spring.factories index 0fa28a4dd..b9931ece1 100644 --- a/pigx-common/pigx-common-log/src/main/resources/META-INF/spring.factories +++ b/pigx-common/pigx-common-log/src/main/resources/META-INF/spring.factories @@ -1,2 +1,4 @@ org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ com.pig4cloud.pigx.common.log.LogAutoConfiguration +org.springframework.context.ApplicationContextInitializer=\ + com.pig4cloud.pigx.common.log.init.ApplicationLoggerInitializer \ No newline at end of file diff --git a/pigx-upms/pigx-upms-biz/src/main/resources/logback-spring.xml b/pigx-upms/pigx-upms-biz/src/main/resources/logback-spring.xml index c382f2059..964ca8735 100644 --- a/pigx-upms/pigx-upms-biz/src/main/resources/logback-spring.xml +++ b/pigx-upms/pigx-upms-biz/src/main/resources/logback-spring.xml @@ -8,7 +8,7 @@ 2. 注意修改 的value模块 --> - + @@ -65,5 +65,6 @@ + From 6b7ee871cf93b7cd4ed3ed01c7e3f0cfffcd58b7 Mon Sep 17 00:00:00 2001 From: pigxcloud <2270033969@qq.com> Date: Wed, 22 May 2019 17:31:08 +0800 Subject: [PATCH 6/7] =?UTF-8?q?:arrow=5Fup:=20Upgrading=20dependencies.=20?= =?UTF-8?q?=E5=8D=87=E7=BA=A7minio=20=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 55950c0bd..b06a2a2ba 100644 --- a/pom.xml +++ b/pom.xml @@ -59,7 +59,7 @@ 3.15 2.1.1 2.10.2 - 6.0.4 + 6.0.7 2.1.5 2.3.5.RELEASE 2.1.2.RELEASE From b2400e5cceaab27ed6ce300c6e9779c806dad827 Mon Sep 17 00:00:00 2001 From: pigxcloud <2270033969@qq.com> Date: Wed, 22 May 2019 17:31:28 +0800 Subject: [PATCH 7/7] =?UTF-8?q?:recycle:=20=E9=87=8D=E6=9E=84=E4=BB=A3?= =?UTF-8?q?=E7=A0=81=E3=80=82=20tenant=20=E5=8C=85=E5=90=8D=E9=87=8D?= =?UTF-8?q?=E6=9E=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/pig4cloud/pigx/admin/api}/entity/SysTenant.java | 2 +- .../pig4cloud/pigx/admin/controller/SysTenantController.java | 5 +---- .../com/pig4cloud/pigx/admin/mapper/SysTenantMapper.java | 2 +- .../com/pig4cloud/pigx/admin/service/SysTenantService.java | 2 +- .../pigx/admin/service/impl/SysTenantServiceImpl.java | 2 +- .../src/main/resources/mapper/SysTenantMapper.xml | 2 +- 6 files changed, 6 insertions(+), 9 deletions(-) rename pigx-upms/{pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin => pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api}/entity/SysTenant.java (97%) diff --git a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/entity/SysTenant.java b/pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/entity/SysTenant.java similarity index 97% rename from pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/entity/SysTenant.java rename to pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/entity/SysTenant.java index 1c7cb6482..6ba45ce7c 100755 --- a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/entity/SysTenant.java +++ b/pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/entity/SysTenant.java @@ -15,7 +15,7 @@ * Author: lengleng (wangiegie@gmail.com) */ -package com.pig4cloud.pigx.admin.entity; +package com.pig4cloud.pigx.admin.api.entity; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableLogic; diff --git a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/controller/SysTenantController.java b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/controller/SysTenantController.java index e804e7f89..d5383a05e 100755 --- a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/controller/SysTenantController.java +++ b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/controller/SysTenantController.java @@ -19,7 +19,7 @@ package com.pig4cloud.pigx.admin.controller; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; -import com.pig4cloud.pigx.admin.entity.SysTenant; +import com.pig4cloud.pigx.admin.api.entity.SysTenant; import com.pig4cloud.pigx.admin.service.SysTenantService; import com.pig4cloud.pigx.common.core.util.R; import com.pig4cloud.pigx.common.log.annotation.SysLog; @@ -29,8 +29,6 @@ import lombok.AllArgsConstructor; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.web.bind.annotation.*; -import java.time.LocalDate; - /** * 租户管理 @@ -114,7 +112,6 @@ public class SysTenantController { * * @return */ - @SysLog("查询全部有效的租户") @Inner(value = false) @GetMapping("/list") public R list() { diff --git a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/mapper/SysTenantMapper.java b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/mapper/SysTenantMapper.java index 3cdb0d784..5f49f77f4 100755 --- a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/mapper/SysTenantMapper.java +++ b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/mapper/SysTenantMapper.java @@ -18,7 +18,7 @@ package com.pig4cloud.pigx.admin.mapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper; -import com.pig4cloud.pigx.admin.entity.SysTenant; +import com.pig4cloud.pigx.admin.api.entity.SysTenant; /** * 租户 diff --git a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/SysTenantService.java b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/SysTenantService.java index 443b8315e..db658989a 100755 --- a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/SysTenantService.java +++ b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/SysTenantService.java @@ -18,7 +18,7 @@ package com.pig4cloud.pigx.admin.service; import com.baomidou.mybatisplus.extension.service.IService; -import com.pig4cloud.pigx.admin.entity.SysTenant; +import com.pig4cloud.pigx.admin.api.entity.SysTenant; import java.util.List; diff --git a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/impl/SysTenantServiceImpl.java b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/impl/SysTenantServiceImpl.java index 1f2cf2687..3d06fe8bc 100755 --- a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/impl/SysTenantServiceImpl.java +++ b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/impl/SysTenantServiceImpl.java @@ -19,7 +19,7 @@ package com.pig4cloud.pigx.admin.service.impl; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.pig4cloud.pigx.admin.api.entity.*; -import com.pig4cloud.pigx.admin.entity.SysTenant; +import com.pig4cloud.pigx.admin.api.entity.SysTenant; import com.pig4cloud.pigx.admin.mapper.SysTenantMapper; import com.pig4cloud.pigx.admin.service.*; import com.pig4cloud.pigx.common.core.constant.CommonConstants; diff --git a/pigx-upms/pigx-upms-biz/src/main/resources/mapper/SysTenantMapper.xml b/pigx-upms/pigx-upms-biz/src/main/resources/mapper/SysTenantMapper.xml index b3f725b47..5d238ff7d 100755 --- a/pigx-upms/pigx-upms-biz/src/main/resources/mapper/SysTenantMapper.xml +++ b/pigx-upms/pigx-upms-biz/src/main/resources/mapper/SysTenantMapper.xml @@ -23,7 +23,7 @@ - +