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 extends Map, ?>> 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 extends Map, ?>> 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 extends Map, ?>>) 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
+ * | | |