From 119d3fefa9fdd7a2657bf7327368642acf04b31b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E5=91=A8=E5=AE=87=E6=81=92?=
<13581426+zhou030824@user.noreply.gitee.com>
Date: Fri, 2 Feb 2024 21:24:36 +0800
Subject: [PATCH] =?UTF-8?q?=E5=AF=BC=E5=85=A5=E5=AF=BC=E5=87=BA?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
community-security-common/pom.xml | 17 +
.../com/zyh/common/Enum/WriteRowsOption.java | 8 +
.../java/com/zyh/common/domain/Person.java | 13 +-
.../com/zyh/common/domain/PersonTest.java | 69 +++
.../com/zyh/common/util/ImportExeclUtil.java | 413 ++++++++++++++++++
.../zyh/common/utils/ExcelContextUtil.java | 33 ++
.../common/utils/ExcelErrorFillHandler.java | 101 +++++
.../zyh/common/utils/ExcelImportListener.java | 77 ++++
.../com/zyh/common/utils/ExcelLineResult.java | 35 ++
.../java/com/zyh/common/utils/ExcelUtil.java | 86 ++++
.../com/zyh/common/utils/LyException.java | 64 +++
.../zyh/common/utils/LyValidationUtil.java | 31 ++
.../zyh/common/utils/RequestContextUtil.java | 40 ++
.../zyh/common/utils/SpringContextUtil.java | 38 ++
.../java/com/zyh/system/ShopApplication.java | 2 +
.../system/controller/PersonController.java | 89 ++++
.../com/zyh/system/mapper/PersonMapper.java | 16 +
.../com/zyh/system/service/PersonService.java | 10 +
.../system/service/impl/PersonServicempl.java | 360 +++++++++++++++
.../main/resources/mapper/PersonMapper.xml | 35 ++
20 files changed, 1532 insertions(+), 5 deletions(-)
create mode 100644 community-security-common/src/main/java/com/zyh/common/Enum/WriteRowsOption.java
create mode 100644 community-security-common/src/main/java/com/zyh/common/domain/PersonTest.java
create mode 100644 community-security-common/src/main/java/com/zyh/common/util/ImportExeclUtil.java
create mode 100644 community-security-common/src/main/java/com/zyh/common/utils/ExcelContextUtil.java
create mode 100644 community-security-common/src/main/java/com/zyh/common/utils/ExcelErrorFillHandler.java
create mode 100644 community-security-common/src/main/java/com/zyh/common/utils/ExcelImportListener.java
create mode 100644 community-security-common/src/main/java/com/zyh/common/utils/ExcelLineResult.java
create mode 100644 community-security-common/src/main/java/com/zyh/common/utils/ExcelUtil.java
create mode 100644 community-security-common/src/main/java/com/zyh/common/utils/LyException.java
create mode 100644 community-security-common/src/main/java/com/zyh/common/utils/LyValidationUtil.java
create mode 100644 community-security-common/src/main/java/com/zyh/common/utils/RequestContextUtil.java
create mode 100644 community-security-common/src/main/java/com/zyh/common/utils/SpringContextUtil.java
diff --git a/community-security-common/pom.xml b/community-security-common/pom.xml
index af54ebd..102a042 100644
--- a/community-security-common/pom.xml
+++ b/community-security-common/pom.xml
@@ -102,6 +102,23 @@
easyexcel
3.2.1
+
+ org.apache.tomcat.embed
+ tomcat-embed-core
+ 9.0.83
+
+
+
+
+ com.alibaba
+ easyexcel
+ 3.2.0
+
+
+
+
+
+
diff --git a/community-security-common/src/main/java/com/zyh/common/Enum/WriteRowsOption.java b/community-security-common/src/main/java/com/zyh/common/Enum/WriteRowsOption.java
new file mode 100644
index 0000000..11973db
--- /dev/null
+++ b/community-security-common/src/main/java/com/zyh/common/Enum/WriteRowsOption.java
@@ -0,0 +1,8 @@
+package com.zyh.common.Enum;
+
+public class WriteRowsOption {
+ public static final int TOTAL_COUNT = 10000000; // 总行数
+ public static final int SHEET_DATA_ROWS = 1000000; // 每个 Sheet 的行数
+ public static final int WRITE_DATA_ROWS = 1000000; // 每次写入的行数
+}
+
diff --git a/community-security-common/src/main/java/com/zyh/common/domain/Person.java b/community-security-common/src/main/java/com/zyh/common/domain/Person.java
index 02bbfc5..c70dd67 100644
--- a/community-security-common/src/main/java/com/zyh/common/domain/Person.java
+++ b/community-security-common/src/main/java/com/zyh/common/domain/Person.java
@@ -2,7 +2,10 @@ package com.zyh.common.domain;
import lombok.Data;
import com.alibaba.excel.annotation.ExcelProperty;
+
+import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotEmpty;
+import javax.validation.constraints.NotNull;
import java.util.Date;
@Data
@@ -16,7 +19,7 @@ public class Person {
@NotEmpty(message = "身份证号不能为空")
private String idcard;
@ExcelProperty("身份证类型编号")
- @NotEmpty(message = "身份证类型不能为空")
+ @NotNull(message = "身份证类型不能为空")
private Integer idcardType;
@ExcelProperty("出生日期")
@NotEmpty(message = "出生日期不能为空")
@@ -25,7 +28,7 @@ public class Person {
@NotEmpty(message = "民族不能为空")
private String nation;
@ExcelProperty("性别")
- @NotEmpty(message = "性别不能为空")
+ @NotNull(message = "性别不能为空")
private Integer sex;
@ExcelProperty("手机号")
@NotEmpty(message = "手机号不能为空")
@@ -37,13 +40,13 @@ public class Person {
@NotEmpty(message = "小区不能为空")
private String houseId;
@ExcelProperty("楼栋id")
- @NotEmpty(message = "楼栋不能为空")
+ @NotNull(message = "楼栋不能为空")
private Integer buildId;
@ExcelProperty("单元")
- @NotEmpty(message = "单元不能为空")
+ @NotNull(message = "单元不能为空")
private Integer unit;
@ExcelProperty("房号")
- @NotEmpty(message = "房号不能为空")
+ @NotNull(message = "房号不能为空")
private Integer holdId;
@ExcelProperty("身份证照片")
@NotEmpty(message = "身份证照片不能为空")
diff --git a/community-security-common/src/main/java/com/zyh/common/domain/PersonTest.java b/community-security-common/src/main/java/com/zyh/common/domain/PersonTest.java
new file mode 100644
index 0000000..ac91b66
--- /dev/null
+++ b/community-security-common/src/main/java/com/zyh/common/domain/PersonTest.java
@@ -0,0 +1,69 @@
+package com.zyh.common.domain;
+
+import com.alibaba.excel.annotation.ExcelProperty;
+import lombok.Data;
+
+import javax.validation.constraints.NotNull;
+
+
+@Data
+public class PersonTest {
+ @ExcelProperty("编号")
+ private Integer id;
+
+ @ExcelProperty("姓名")
+ @NotNull(message = "姓名不能为空")
+ private String name;
+
+ @ExcelProperty("身份证号")
+ @NotNull(message = "身份证号不能为空")
+ private String idcard;
+
+ @ExcelProperty("身份证类型编号")
+ @NotNull(message = "身份证类型不能为空")
+ private Integer idcardType;
+
+ @ExcelProperty("出生日期")
+ @NotNull(message = "出生日期不能为空")
+ private String birth;
+
+ @ExcelProperty("民族")
+ @NotNull(message = "民族不能为空")
+ private String nation;
+
+ @ExcelProperty("性别")
+ @NotNull(message = "性别不能为空")
+ private Integer sex;
+ @ExcelProperty("手机号")
+ @NotNull(message = "手机号不能为空")
+ private String phone;
+
+ @ExcelProperty("户籍")
+ @NotNull(message = "户籍不能为空")
+ private String address;
+
+ @ExcelProperty("小区id")
+ @NotNull(message = "小区不能为空")
+ private String houseId;
+
+ @ExcelProperty("楼栋id")
+ @NotNull(message = "楼栋不能为空")
+ private Integer buildId;
+
+ @ExcelProperty("单元")
+ @NotNull(message = "单元不能为空")
+ private Integer unit;
+
+ @ExcelProperty("房号")
+ @NotNull(message = "房号不能为空")
+ private Integer holdId;
+
+ @ExcelProperty("身份证照片")
+ @NotNull(message = "身份证照片不能为空")
+ private String pic;
+
+
+
+
+
+}
diff --git a/community-security-common/src/main/java/com/zyh/common/util/ImportExeclUtil.java b/community-security-common/src/main/java/com/zyh/common/util/ImportExeclUtil.java
new file mode 100644
index 0000000..0b27ea8
--- /dev/null
+++ b/community-security-common/src/main/java/com/zyh/common/util/ImportExeclUtil.java
@@ -0,0 +1,413 @@
+package com.zyh.common.util;
+
+import com.zyh.common.utils.StringUtils;
+import org.apache.poi.hssf.usermodel.HSSFDateUtil;
+import org.apache.poi.hssf.usermodel.HSSFWorkbook;
+import org.apache.poi.ss.usermodel.Cell;
+import org.apache.poi.ss.usermodel.Row;
+import org.apache.poi.ss.usermodel.Sheet;
+import org.apache.poi.ss.usermodel.Workbook;
+import org.apache.poi.ss.util.NumberToTextConverter;
+import org.apache.poi.xssf.usermodel.XSSFWorkbook;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.lang.reflect.Field;
+import java.math.BigDecimal;
+import java.text.DateFormat;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+import java.util.Locale;
+
+public class ImportExeclUtil {
+
+ private static int totalRows = 0;// 总行数
+
+ private static int totalCells = 0;// 总列数
+
+ private static String errorInfo;// 错误信息
+
+ /** 无参构造方法 */
+ public ImportExeclUtil()
+ {
+ }
+
+ public static int getTotalRows()
+ {
+ return totalRows;
+ }
+
+ public static int getTotalCells()
+ {
+ return totalCells;
+ }
+
+ public static String getErrorInfo()
+ {
+ return errorInfo;
+ }
+
+ /**
+ *
+ * 根据流读取Excel文件
+ *
+ *
+ * @param inputStream
+ * @param isExcel2003
+ * @return
+ * @see [类、类#方法、类#成员]
+ */
+ public List> read(InputStream inputStream, boolean isExcel2003) throws IOException {
+ List> dataLst = null;
+
+ /** 根据版本选择创建Workbook的方式 */
+ Workbook wb = null;
+
+ if (isExcel2003) {
+ // 修改为XSSFWorkbook处理Excel 2007+格式
+ wb = new XSSFWorkbook(inputStream);
+ } else {
+ wb = new XSSFWorkbook(inputStream);
+ }
+ dataLst = readDate(wb);
+
+ return dataLst;
+ }
+
+ /**
+ *
+ * 读取数据
+ *
+ * @param wb
+ * @return
+ * @see [类、类#方法、类#成员]
+ */
+ private List> readDate(Workbook wb)
+ {
+
+ List> dataLst = new ArrayList>();
+
+ /** 得到第一个shell */
+ Sheet sheet = wb.getSheetAt(0);
+
+ /** 得到Excel的行数 */
+ totalRows = sheet.getPhysicalNumberOfRows();
+
+ /** 得到Excel的列数 */
+ if (totalRows >= 1 && sheet.getRow(0) != null)
+ {
+ totalCells = sheet.getRow(0).getPhysicalNumberOfCells();
+ }
+
+ /** 循环Excel的行 */
+ for (int r = 1; r < totalRows; r++)
+ {
+ Row row = sheet.getRow(r);
+ if (row == null)
+ {
+ continue;
+ }
+
+ List rowLst = new ArrayList();
+
+ /** 循环Excel的列 */
+ for (int c = 0; c < getTotalCells(); c++)
+ {
+
+ Cell cell = row.getCell(c);
+ String cellValue = "";
+
+ if (null != cell)
+ {
+ // 以下是判断数据的类型
+ switch (cell.getCellTypeEnum())
+ {
+ case NUMERIC: // 数字
+ //如果是日期的话
+ if(cell != null && HSSFDateUtil.isCellDateFormatted(cell)){
+ Date d = cell.getDateCellValue();
+ DateFormat formater = new SimpleDateFormat("yyyy/MM/dd");
+ String da = formater.format(d);
+ cellValue = da;
+ break;
+ }
+ cellValue = NumberToTextConverter.toText(cell.getNumericCellValue());
+ break;
+
+ case STRING: // 字符串
+ cellValue = cell.getStringCellValue();
+ break;
+
+ case BOOLEAN: // Boolean
+ cellValue = cell.getBooleanCellValue() + "";
+ break;
+
+ case FORMULA: // 公式
+ cellValue = cell.getCellFormula() + "";
+ break;
+
+ case BLANK: // 空值
+ cellValue = "";
+ break;
+
+ case ERROR: // 故障
+ cellValue = "非法字符";
+ break;
+
+ default:
+ cellValue = "未知类型";
+ break;
+ }
+ }
+
+ rowLst.add(cellValue);
+ }
+
+ /** 保存第r行的第c列 */
+ dataLst.add(rowLst);
+ }
+
+ return dataLst;
+ }
+
+ /**
+ *
+ * 根据Excel表格中的数据判断类型得到值
+ *
+ * @param cell
+ * @return
+ * @see [类、类#方法、类#成员]
+ */
+ /*private static String getCellValue(Cell cell)
+ {
+ String cellValue = "";
+
+ if (null != cell)
+ {
+ // 以下是判断数据的类型
+ switch (cell.getCellType())
+ {
+ case HSSFCell.CELL_TYPE_NUMERIC: // 数字
+ ;: // 数字
+ if (org.apache.poi.ss.usermodel.DateUtil.isCellDateFormatted(cell))
+ {
+ Date theDate = cell.getDateCellValue();
+ SimpleDateFormat dff = new SimpleDateFormat("yyyy-MM-dd");
+ cellValue = dff.format(theDate);
+ }
+ else
+ {
+ DecimalFormat df = new DecimalFormat("0");
+ cellValue = df.format(cell.getNumericCellValue());
+ }
+ break;
+ case HSSFCell.CELL_TYPE_STRING: // 字符串
+ cellValue = cell.getStringCellValue();
+ break;
+
+ case HSSFCell.CELL_TYPE_BOOLEAN: // Boolean
+ cellValue = cell.getBooleanCellValue() + "";
+ break;
+
+ case HSSFCell.CELL_TYPE_FORMULA: // 公式
+ cellValue = cell.getCellFormula() + "";
+ break;
+
+ case HSSFCell.CELL_TYPE_BLANK: // 空值
+ cellValue = "";
+ break;
+
+ case HSSFCell.CELL_TYPE_ERROR: // 故障
+ cellValue = "非法字符";
+ break;
+
+ default:
+ cellValue = "未知类型";
+ break;
+ }
+
+ }
+ return cellValue;
+ }*/
+
+ /**
+ *
+ * 根据实体成员变量的类型得到成员变量的值
+ *
+ * @param realValue
+ * @param fields
+ * @param f
+ * @param cellValue
+ * @return
+ * @see [类、类#方法、类#成员]
+ */
+ private static Object getEntityMemberValue(Object realValue, Field[] fields, int f, String cellValue)
+ {
+ String type = fields[f].getType().getName();
+ switch (type)
+ {
+ case "char":
+ case "java.lang.Character":
+ case "java.lang.String":
+ realValue = cellValue;
+ break;
+ case "java.util.Date":
+ realValue = StringUtils.isBlank(cellValue) ? null : DateUtil.strToDate(cellValue, DateUtil.YYYY_MM_DD);
+ break;
+ case "java.lang.Integer":
+ realValue = StringUtils.isBlank(cellValue) ? null : Integer.valueOf(cellValue);
+ break;
+ case "int":
+ case "float":
+ case "double":
+ case "java.lang.Double":
+ case "java.lang.Float":
+ case "java.lang.Long":
+ case "java.lang.Short":
+ case "java.math.BigDecimal":
+ realValue = StringUtils.isBlank(cellValue) ? null : new BigDecimal(cellValue);
+ break;
+ default:
+ break;
+ }
+ return realValue;
+ }
+
+ /**
+ *
+ * 根据路径或文件名选择Excel版本
+ *
+ *
+ * @param filePathOrName
+ * @param in
+ * @return
+ * @throws IOException
+ * @see [类、类#方法、类#成员]
+ */
+ public static Workbook chooseWorkbook(String filePathOrName, InputStream in) throws IOException {
+ /** 根据版本选择创建Workbook的方式 */
+ Workbook wb = null;
+ boolean isExcel2003 = ExcelVersionUtil.isExcel2003(filePathOrName);
+
+ if (isExcel2003) {
+ // 修改为XSSFWorkbook处理Excel 2007+格式
+ wb = new XSSFWorkbook(in);
+ } else {
+ wb = new XSSFWorkbook(in);
+ }
+
+ return wb;
+ }
+
+ static class ExcelVersionUtil
+ {
+
+ /**
+ *
+ * 是否是2003的excel,返回true是2003
+ *
+ *
+ * @param filePath
+ * @return
+ * @see [类、类#方法、类#成员]
+ */
+ public static boolean isExcel2003(String filePath)
+ {
+ return filePath.matches("^.+\\.(?i)(xls)$");
+
+ }
+
+ /**
+ *
+ * 是否是2007的excel,返回true是2007
+ *
+ *
+ * @param filePath
+ * @return
+ * @see [类、类#方法、类#成员]
+ */
+ public static boolean isExcel2007(String filePath)
+ {
+ return filePath.matches("^.+\\.(?i)(xlsx)$");
+
+ }
+
+ }
+
+ public static class DateUtil
+ {
+
+ // ======================日期格式化常量=====================//
+
+ public static final String YYYY_MM_DDHHMMSS = "yyyy-MM-dd HH:mm:ss";
+
+ public static final String YYYY_MM_DD = "yyyy-MM-dd";
+
+ public static final String YYYY_MM = "yyyy-MM";
+
+ public static final String YYYY = "yyyy";
+
+ public static final String YYYYMMDDHHMMSS = "yyyyMMddHHmmss";
+
+ public static final String YYYYMMDD = "yyyyMMdd";
+
+ public static final String YYYYMM = "yyyyMM";
+
+ public static final String YYYYMMDDHHMMSS_1 = "yyyy/MM/dd HH:mm:ss";
+
+ public static final String YYYY_MM_DD_1 = "yyyy/MM/dd";
+
+ public static final String YYYY_MM_1 = "yyyy/MM";
+
+ /**
+ *
+ * 自定义取值,Date类型转为String类型
+ *
+ * @param date 日期
+ * @param pattern 格式化常量
+ * @return
+ * @see [类、类#方法、类#成员]
+ */
+ public static String dateToStr(Date date, String pattern)
+ {
+ SimpleDateFormat format = null;
+
+ if (null == date)
+ return null;
+ format = new SimpleDateFormat(pattern, Locale.getDefault());
+
+ return format.format(date);
+ }
+
+ /**
+ * 将字符串转换成Date类型的时间
+ *
+ *
+ * @param s 日期类型的字符串
+ * datePattern :YYYY_MM_DD
+ * @return java.util.Date
+ */
+ public static Date strToDate(String s, String pattern)
+ {
+ if (s == null)
+ {
+ return null;
+ }
+ Date date = null;
+ SimpleDateFormat sdf = new SimpleDateFormat(pattern);
+ try
+ {
+ date = sdf.parse(s);
+ }
+ catch (ParseException e)
+ {
+ e.printStackTrace();
+ }
+ return date;
+ }
+ }
+
+}
diff --git a/community-security-common/src/main/java/com/zyh/common/utils/ExcelContextUtil.java b/community-security-common/src/main/java/com/zyh/common/utils/ExcelContextUtil.java
new file mode 100644
index 0000000..29ba5c0
--- /dev/null
+++ b/community-security-common/src/main/java/com/zyh/common/utils/ExcelContextUtil.java
@@ -0,0 +1,33 @@
+package com.zyh.common.utils;
+
+
+import javax.servlet.http.HttpServletResponse;
+import java.net.URLEncoder;
+import java.nio.charset.StandardCharsets;
+
+/**
+ * excel导入导出过程中用到的工具类
+ *
+ * @author xuyingfa
+ */
+public class ExcelContextUtil {
+ private static final String SUFFIX = ".xlsx";
+
+ /**
+ * 为下载文件设置响应头
+ *
+ * @param response 响应
+ * @param filename 文件名
+ */
+ public static void setDownloadHeader(HttpServletResponse response, String filename) {
+ if (!filename.endsWith(SUFFIX)) {
+ filename += SUFFIX;
+ }
+ response.setCharacterEncoding("utf-8");
+ filename = URLEncoder.encode(filename, StandardCharsets.UTF_8).replace("\\+", "%20");
+ // axios下载时获取文件名
+ response.setHeader("filename",filename);
+ response.setHeader("Content-Disposition", "attachment; filename=" + filename);
+ response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
+ }
+}
diff --git a/community-security-common/src/main/java/com/zyh/common/utils/ExcelErrorFillHandler.java b/community-security-common/src/main/java/com/zyh/common/utils/ExcelErrorFillHandler.java
new file mode 100644
index 0000000..08846d3
--- /dev/null
+++ b/community-security-common/src/main/java/com/zyh/common/utils/ExcelErrorFillHandler.java
@@ -0,0 +1,101 @@
+package com.zyh.common.utils;
+
+import com.alibaba.excel.write.handler.RowWriteHandler;
+import com.alibaba.excel.write.handler.SheetWriteHandler;
+import com.alibaba.excel.write.handler.context.SheetWriteHandlerContext;
+import com.alibaba.excel.write.metadata.holder.WriteSheetHolder;
+import com.alibaba.excel.write.metadata.holder.WriteWorkbookHolder;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.poi.ss.usermodel.*;
+
+import java.util.List;
+import java.util.stream.Collectors;
+
+/**
+ * @author ly-chn
+ */
+@Slf4j
+@RequiredArgsConstructor
+public class ExcelErrorFillHandler implements SheetWriteHandler, RowWriteHandler {
+ /**
+ * 错误结果集
+ */
+ private final List> resultList;
+ /**
+ * 标题所在行, 从1开始
+ */
+ private final Integer titleLineNumber;
+
+ /**
+ * 结果列序号
+ */
+ private int resultColNum;
+
+ /**
+ * 默认导入成功的提示
+ */
+ private static final String SUCCESS_MSG = "导入成功";
+
+
+ private static void setCellStyle(Cell cell, IndexedColors color) {
+ Workbook workbook = cell.getSheet().getWorkbook();
+ CellStyle style = workbook.createCellStyle();
+ Font font = workbook.createFont();
+ font.setColor(color.getIndex());
+ style.setFont(font);
+ cell.setCellStyle(style);
+ }
+
+ @Override
+ public void afterSheetCreate(SheetWriteHandlerContext context) {
+ SheetWriteHandler.super.afterSheetCreate(context);
+ }
+
+ @Override
+ public void afterSheetCreate(WriteWorkbookHolder writeWorkbookHolder, WriteSheetHolder writeSheetHolder) {
+ Sheet cachedSheet = writeSheetHolder.getCachedSheet();
+ for (int i = 1; i <= cachedSheet.getLastRowNum() + 1; i++) {
+ // 空白数据, 不做处理
+ if (i < titleLineNumber) {
+ continue;
+ }
+ Row row = cachedSheet.getRow(i - 1);
+ // 标题行, 创建标题
+ if (i == titleLineNumber) {
+ this.resultColNum = row.getLastCellNum();
+ Cell cell = row.createCell(row.getLastCellNum(), CellType.STRING);
+ setCellStyle(cell, IndexedColors.BLACK);
+ cell.setCellValue("导入结果");
+ continue;
+ }
+ // 结果行
+ Cell cell = row.createCell(this.resultColNum, CellType.STRING);
+ String errMsg = convertErrMsg(resultList.get(i - titleLineNumber - 1));
+ if (errMsg == null) {
+ setCellStyle(cell, IndexedColors.GREEN);
+ cell.setCellValue(SUCCESS_MSG);
+ continue;
+ }
+ setCellStyle(cell, IndexedColors.RED);
+ cell.setCellValue(errMsg);
+ }
+ }
+
+ /**
+ * 解析每行的错误信息
+ *
+ * @param result 读取结果
+ * @return 错误信息
+ */
+ private String convertErrMsg(ExcelLineResult result) {
+ if (result.getBizError() != null) {
+ return result.getBizError();
+ }
+ if (result.getViolation().isEmpty()) {
+ return null;
+ }
+ return result.getViolation().stream().map(LyValidationUtil::getMessage)
+ .collect(Collectors.joining(";\n"));
+ }
+}
diff --git a/community-security-common/src/main/java/com/zyh/common/utils/ExcelImportListener.java b/community-security-common/src/main/java/com/zyh/common/utils/ExcelImportListener.java
new file mode 100644
index 0000000..94499ad
--- /dev/null
+++ b/community-security-common/src/main/java/com/zyh/common/utils/ExcelImportListener.java
@@ -0,0 +1,77 @@
+package com.zyh.common.utils;
+
+import com.alibaba.excel.context.AnalysisContext;
+import com.alibaba.excel.read.listener.ReadListener;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+
+import javax.validation.ConstraintViolation;
+import javax.validation.Validator;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+import java.util.function.Consumer;
+
+/**
+ * excel导入校验
+ *
+ * @author ly-chn
+ */
+@Slf4j
+@RequiredArgsConstructor
+class ExcelImportListener implements ReadListener {
+ private final List> excelLineResultList = new ArrayList<>();
+ public static String defaultBizError = "未知异常";
+
+ /**
+ * 业务处理, 入库, 解析等
+ */
+ private final Consumer consumer;
+
+ /**
+ * 每次读取, 记录读取信息
+ */
+ @Override
+ public void invoke(T t, AnalysisContext analysisContext) {
+ if (log.isDebugEnabled()) {
+ log.debug("读取到数据: {}", t);
+ }
+ ExcelLineResult build = ExcelLineResult.builder()
+ .rowIndex(analysisContext.readRowHolder().getRowIndex())
+ .target(t)
+ .build();
+ excelLineResultList.add(build);
+ }
+
+ /**
+ * 读取完毕后执行校验
+ */
+ @Override
+ public void doAfterAllAnalysed(AnalysisContext analysisContext) {
+ if (excelLineResultList.isEmpty()) {
+ return;
+ }
+ Validator validator = SpringContextUtil.getBean(Validator.class);
+ excelLineResultList.forEach(it -> {
+ Set> validate = validator.validate(it.getTarget());
+ it.setViolation(validate);
+ // 校验不通过, 不必执行业务逻辑
+ if (!validate.isEmpty()) {
+ return;
+ }
+ try {
+ consumer.accept(it.getTarget());
+ } catch (LyException e) {
+ log.error("解析数据失败: {}, 异常信息: {}", it, e.getMessage());
+ it.setBizError(e.getMessage());
+ } catch (Exception e) {
+ log.error("解析数据失败", e);
+ it.setBizError(defaultBizError);
+ }
+ });
+ }
+
+ public List> getExcelLineResultList() {
+ return excelLineResultList;
+ }
+}
diff --git a/community-security-common/src/main/java/com/zyh/common/utils/ExcelLineResult.java b/community-security-common/src/main/java/com/zyh/common/utils/ExcelLineResult.java
new file mode 100644
index 0000000..c5e38ff
--- /dev/null
+++ b/community-security-common/src/main/java/com/zyh/common/utils/ExcelLineResult.java
@@ -0,0 +1,35 @@
+package com.zyh.common.utils;
+
+import lombok.Builder;
+import lombok.Data;
+
+import javax.validation.ConstraintViolation;
+import java.util.Set;
+
+
+/**
+ * Excel按行导入结果
+ *
+ * @author ly-chn
+ */
+@Data
+@Builder
+class ExcelLineResult {
+
+ /**
+ * 行号, 从0开始
+ */
+ private Integer rowIndex;
+ /**
+ * 导入的数据
+ */
+ private T target;
+ /**
+ * 校验结果
+ */
+ private Set> violation;
+ /**
+ * 业务异常错误信息
+ */
+ private String bizError;
+}
diff --git a/community-security-common/src/main/java/com/zyh/common/utils/ExcelUtil.java b/community-security-common/src/main/java/com/zyh/common/utils/ExcelUtil.java
new file mode 100644
index 0000000..d69b004
--- /dev/null
+++ b/community-security-common/src/main/java/com/zyh/common/utils/ExcelUtil.java
@@ -0,0 +1,86 @@
+package com.zyh.common.utils;
+
+
+import com.alibaba.excel.EasyExcel;
+import lombok.Cleanup;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.web.multipart.MultipartFile;
+
+import javax.servlet.http.HttpServletResponse;
+import javax.validation.constraints.NotNull;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.Objects;
+import java.util.function.Consumer;
+
+/**
+ * excel工具
+ *
+ * @author ly-chn
+ */
+@Slf4j
+public class ExcelUtil {
+ /**
+ * 导入, 标题行默认为1
+ *
+ * @param file 文件
+ * @param pojoClass 实体类
+ * @param consumer 消费数据, 执行SQL逻辑或其他逻辑等等,
+ * 如果抛出LyException异常, 则异常message将作为Excel导入失败原因
+ * 否则为未知异常导致导入失败
+ * @param 对应类型
+ */
+ public static void read(@NotNull MultipartFile file, @NotNull Class pojoClass, @NotNull Consumer consumer) {
+ read(file, pojoClass, consumer, 1);
+ }
+
+ /**
+ * 导入
+ *
+ * @param file 文件
+ * @param pojoClass 实体类
+ * @param consumer 消费数据, 执行SQL逻辑或其他逻辑等等,
+ * 如果抛出LyException异常, 则异常message将作为Excel导入失败原因
+ * 否则为未知异常导致导入失败
+ * @param titleLineNumber 标题所在行, 从1开始
+ * @param 对应类型
+ */
+ public static void read(@NotNull MultipartFile file,
+ @NotNull Class pojoClass,
+ @NotNull Consumer consumer,
+ @NotNull Integer titleLineNumber) {
+ try {
+ ExcelImportListener listener = new ExcelImportListener<>(consumer);
+ @Cleanup InputStream inputStream = file.getInputStream();
+ EasyExcel.read(inputStream, pojoClass, listener)
+ .headRowNumber(titleLineNumber)
+ .sheet().doRead();
+ List> resultList = listener.getExcelLineResultList();
+ boolean allSuccess = resultList.stream()
+ .allMatch(it -> it.getViolation().isEmpty() && Objects.isNull(it.getBizError()));
+ if (allSuccess) {
+ log.info("Excel 数据已全部导入: {}", resultList);
+ return;
+ }
+ log.error("Excel校验失败, 读取结果: {}", resultList);
+ HttpServletResponse response = RequestContextUtil.getResponse();
+ @Cleanup InputStream templateIs = file.getInputStream();
+ ExcelContextUtil.setDownloadHeader(response, "文件导入失败.xlsx");
+
+ EasyExcel.write(response.getOutputStream(), pojoClass)
+ .withTemplate(templateIs)
+ .autoCloseStream(false)
+ .registerWriteHandler(new ExcelErrorFillHandler(resultList, titleLineNumber))
+ .needHead(false)
+ .sheet()
+ .doWrite(Collections.emptyList());
+ } catch (Exception e) {
+ log.error("文件读取失败", e);
+ throw new LyException.Normal("文件读取失败, 请检查文件格式");
+ }
+ throw new LyException.None();
+ }
+}
diff --git a/community-security-common/src/main/java/com/zyh/common/utils/LyException.java b/community-security-common/src/main/java/com/zyh/common/utils/LyException.java
new file mode 100644
index 0000000..2c3b8fa
--- /dev/null
+++ b/community-security-common/src/main/java/com/zyh/common/utils/LyException.java
@@ -0,0 +1,64 @@
+package com.zyh.common.utils;
+
+import lombok.Getter;
+
+/**
+ * 全局异常
+ *
+ * @author ly-chn
+ */
+@Getter
+public class LyException extends RuntimeException {
+
+ private LyException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ /**
+ * 寻常的异常, 用户无法解决(操作方式不合理, 账号封禁, 删除不存在的东西)的问题, 但无需开发人员介入
+ */
+ public static class Normal extends LyException {
+ public Normal(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ public Normal(String message) {
+ this(message, null);
+ }
+ }
+
+ /**
+ * 严重的异常, 如连接中断等, 用户无法解决的问题, 需要联系网站维护者/开发人员, 一般由系统自动捕获
+ */
+ public static class Panic extends LyException {
+ public Panic(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ public Panic(String message) {
+ this(message, null);
+ }
+ }
+
+ /**
+ * 微小的异常, 如参数校验等, 用户可以解决的问题, 一般由用户自己处理
+ */
+ public static class Minor extends LyException {
+ public Minor(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ public Minor(String message) {
+ this(message, null);
+ }
+ }
+
+ /**
+ * 不做处理的异常, 由于一些场景不得不抛出异常, 以避免全局异常处理或全局响应处理来添加额外信息
+ */
+ public static class None extends LyException {
+ public None() {
+ super(null, null);
+ }
+ }
+}
diff --git a/community-security-common/src/main/java/com/zyh/common/utils/LyValidationUtil.java b/community-security-common/src/main/java/com/zyh/common/utils/LyValidationUtil.java
new file mode 100644
index 0000000..258d3da
--- /dev/null
+++ b/community-security-common/src/main/java/com/zyh/common/utils/LyValidationUtil.java
@@ -0,0 +1,31 @@
+package com.zyh.common.utils;
+
+import com.alibaba.excel.annotation.ExcelProperty;
+import org.apache.commons.lang3.reflect.FieldUtils;
+
+import javax.validation.ConstraintViolation;
+import java.lang.reflect.Field;
+import java.util.Objects;
+
+/**
+ * @author ly-chn
+ */
+public class LyValidationUtil {
+ public static String getMessage(ConstraintViolation> constraintViolation) {
+ String message = constraintViolation.getMessage();
+ if (!message.contains("{fieldTitle}")) {
+ return message;
+ }
+ String fieldTitle = "";
+ Class> rootBeanClass = constraintViolation.getRootBeanClass();
+ if (Objects.nonNull(rootBeanClass)) {
+ Field field = FieldUtils
+ .getField(rootBeanClass, constraintViolation.getPropertyPath().toString(), true);
+ ExcelProperty excelProperty = field.getAnnotation(ExcelProperty.class);
+ if (Objects.nonNull(excelProperty) && excelProperty.value().length != 0) {
+ fieldTitle = excelProperty.value()[0];
+ }
+ }
+ return message.replace("{fieldTitle}", fieldTitle);
+ }
+}
diff --git a/community-security-common/src/main/java/com/zyh/common/utils/RequestContextUtil.java b/community-security-common/src/main/java/com/zyh/common/utils/RequestContextUtil.java
new file mode 100644
index 0000000..9b862c7
--- /dev/null
+++ b/community-security-common/src/main/java/com/zyh/common/utils/RequestContextUtil.java
@@ -0,0 +1,40 @@
+package com.zyh.common.utils;
+
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.web.context.request.RequestAttributes;
+import org.springframework.web.context.request.RequestContextHolder;
+import org.springframework.web.context.request.ServletRequestAttributes;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.util.Optional;
+
+/**
+ * spring上下文相关工具类
+ *
+ * @author ly-chn
+ */
+@Slf4j
+public class RequestContextUtil {
+ /**
+ * @return 获取当前请求
+ */
+ public static HttpServletRequest getRequest() {
+ return getRequestAttributes().getRequest();
+ }
+
+ /**
+ * @return 获取当前响应
+ */
+ public static HttpServletResponse getResponse() {
+ return getRequestAttributes().getResponse();
+ }
+
+ private static ServletRequestAttributes getRequestAttributes() {
+ RequestAttributes attributes = Optional.ofNullable(RequestContextHolder.getRequestAttributes()).orElseThrow(() -> {
+ log.error("非web上下文无法获取请求属性, 异步操作请在同步操作内获取所需信息");
+ return new LyException.Panic("请求异常");
+ });
+ return ((ServletRequestAttributes) attributes);
+ }
+}
diff --git a/community-security-common/src/main/java/com/zyh/common/utils/SpringContextUtil.java b/community-security-common/src/main/java/com/zyh/common/utils/SpringContextUtil.java
new file mode 100644
index 0000000..ba430da
--- /dev/null
+++ b/community-security-common/src/main/java/com/zyh/common/utils/SpringContextUtil.java
@@ -0,0 +1,38 @@
+package com.zyh.common.utils;
+
+import org.springframework.beans.BeansException;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.ApplicationContextAware;
+import org.springframework.stereotype.Component;
+
+/**
+ * @author ly-chn
+ */
+@Component
+public class SpringContextUtil implements ApplicationContextAware {
+ private static ApplicationContext context;
+ @Override
+ public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
+ context = applicationContext;
+ }
+
+ public static T getBean(Class clazz) {
+ if (context == null) {
+ // 可以抛出异常或者做其他处理
+ throw new IllegalStateException("Spring context is not initialized");
+ }
+ return context.getBean(clazz);
+ }
+
+
+ public static T getBean(String name, Class requiredType) {
+ return context.getBean(name, requiredType);
+ }
+
+ /**
+ * @return application name
+ */
+ public static String getId() {
+ return context.getId();
+ }
+}
diff --git a/community-security-modules/community-security-modules-shop/src/main/java/com/zyh/system/ShopApplication.java b/community-security-modules/community-security-modules-shop/src/main/java/com/zyh/system/ShopApplication.java
index 897017c..3101e79 100644
--- a/community-security-modules/community-security-modules-shop/src/main/java/com/zyh/system/ShopApplication.java
+++ b/community-security-modules/community-security-modules-shop/src/main/java/com/zyh/system/ShopApplication.java
@@ -4,10 +4,12 @@ import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
+import org.springframework.context.annotation.ComponentScan;
import org.springframework.scheduling.annotation.EnableScheduling;
@SpringBootApplication
@EnableScheduling
+@ComponentScan(basePackages = "com.zyh")
public class ShopApplication {
public static void main(String[] args) {
diff --git a/community-security-modules/community-security-modules-shop/src/main/java/com/zyh/system/controller/PersonController.java b/community-security-modules/community-security-modules-shop/src/main/java/com/zyh/system/controller/PersonController.java
index f3ea323..84b6586 100644
--- a/community-security-modules/community-security-modules-shop/src/main/java/com/zyh/system/controller/PersonController.java
+++ b/community-security-modules/community-security-modules-shop/src/main/java/com/zyh/system/controller/PersonController.java
@@ -1,16 +1,39 @@
package com.zyh.system.controller;
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.nacos.common.utils.CollectionUtils;
import com.zyh.common.domain.House;
import com.zyh.common.domain.Person;
+import com.zyh.common.domain.PersonTest;
import com.zyh.common.result.Result;
+import com.zyh.common.util.ImportExeclUtil;
+import com.zyh.common.utils.ExcelUtil;
+import com.zyh.common.utils.LyException;
+import com.zyh.common.utils.StringUtils;
import com.zyh.system.service.PersonService;
+import lombok.extern.log4j.Log4j2;
+import org.apache.poi.ss.usermodel.Cell;
+import org.apache.poi.ss.usermodel.Row;
+import org.apache.poi.ss.usermodel.Sheet;
+import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
+import javax.servlet.http.HttpServletResponse;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.ArrayList;
import java.util.List;
+import java.util.Objects;
+import java.util.regex.Pattern;
+import java.util.stream.Collectors;
@RestController
@RequestMapping("person")
+@Log4j2
public class PersonController {
@Autowired
private PersonService personService;
@@ -66,4 +89,70 @@ public class PersonController {
+ @GetMapping(value = "/importPersonInfo")
+ public Result uuApplyUserInfo(@RequestParam(value = "file",required = false) MultipartFile file) {
+ try {
+ //工具类
+ ImportExeclUtil readExcelUtil = new ImportExeclUtil();
+ List> read = readExcelUtil.read(file.getInputStream(), true);
+
+ if (CollectionUtils.isNotEmpty(read)){
+
+ List importList = read.stream().map(e -> {
+ PersonTest importDto = new PersonTest();
+ importDto.setId(StringUtils.isNotEmpty(e.get(0)) ? Integer.valueOf(e.get(0)) : null);
+ importDto.setName(e.get(1));
+ importDto.setIdcard(e.get(2));
+ importDto.setIdcardType(StringUtils.isNotEmpty(e.get(3)) ? Integer.valueOf(e.get(3)) : null);
+ importDto.setBirth(e.get(4));
+ importDto.setNation(e.get(5));
+ importDto.setSex(StringUtils.isNotEmpty(e.get(6)) ? Integer.valueOf(e.get(6)) : null);
+ importDto.setPhone(e.get(7));
+ importDto.setAddress(e.get(8));
+ importDto.setHouseId(e.get(9));
+ importDto.setBuildId(StringUtils.isNotEmpty(e.get(10)) ? Integer.valueOf(e.get(10)) : null);
+ importDto.setUnit(StringUtils.isNotEmpty(e.get(11)) ? Integer.valueOf(e.get(11)) : null);
+ importDto.setHoldId(StringUtils.isNotEmpty(e.get(12)) ? Integer.valueOf(e.get(12)) : null);
+ importDto.setPic(e.get(13));
+
+ return importDto;
+ }).collect(Collectors.toList());
+
+ if (CollectionUtils.isEmpty(importList)){
+ return Result.error("不能导入空文件");
+ }
+
+ //最多导入1W条
+ final int maxInt = 10000;
+ if (importList.size() > maxInt){
+ return Result.error("导入最多修改1W条");
+ }
+
+ Result result = personService.uuApplyUserInfo(importList);
+
+ return result;
+
+ }else{
+ return Result.error("不能导入空文件");
+ }
+
+ } catch (Exception e) {
+ e.printStackTrace();
+ return Result.error("导入失败,更新数据库时报错!报错信息:" + e.toString());
+ }
+ }
+
+
+
+
+
+
+
+ @PostMapping("derive")
+ public String derive() throws IOException {
+ return personService.derive();
+ }
+
+
+
}
diff --git a/community-security-modules/community-security-modules-shop/src/main/java/com/zyh/system/mapper/PersonMapper.java b/community-security-modules/community-security-modules-shop/src/main/java/com/zyh/system/mapper/PersonMapper.java
index 9b6ac04..dc9c41e 100644
--- a/community-security-modules/community-security-modules-shop/src/main/java/com/zyh/system/mapper/PersonMapper.java
+++ b/community-security-modules/community-security-modules-shop/src/main/java/com/zyh/system/mapper/PersonMapper.java
@@ -2,6 +2,7 @@ package com.zyh.system.mapper;
import com.zyh.common.domain.House;
import com.zyh.common.domain.Person;
+import com.zyh.common.domain.PersonTest;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
@@ -29,4 +30,19 @@ public interface PersonMapper {
void updatepersonNum(@Param("buildId") String buildId, @Param("unit") Integer unit, @Param("holdId") String holdId);
void updatepersonNumjia(@Param("buildId") Integer buildId, @Param("unit") Integer unit, @Param("holdId") Integer holdId);
+
+ Integer addPersonTest(PersonTest personTest);
+
+ List searchAdmin(Person person);
+
+ List stuListWithLimit(@Param("offset") int offset, @Param("limit") int limit);
+
+ int selectHouseId(@Param("houseId") String houseId);
+
+ Integer selectBuildId(@Param("buildId") Integer buildId);
+
+ Integer selectUnit(@Param("buildId") Integer buildId, @Param("unit") Integer unit);
+
+ Integer selectHoldId(@Param("buildId") Integer buildId, @Param("unit") Integer unit, @Param("holdId") Integer holdId);
+
}
diff --git a/community-security-modules/community-security-modules-shop/src/main/java/com/zyh/system/service/PersonService.java b/community-security-modules/community-security-modules-shop/src/main/java/com/zyh/system/service/PersonService.java
index 296a747..efecfd9 100644
--- a/community-security-modules/community-security-modules-shop/src/main/java/com/zyh/system/service/PersonService.java
+++ b/community-security-modules/community-security-modules-shop/src/main/java/com/zyh/system/service/PersonService.java
@@ -2,8 +2,10 @@ package com.zyh.system.service;
import com.zyh.common.domain.House;
import com.zyh.common.domain.Person;
+import com.zyh.common.domain.PersonTest;
import com.zyh.common.result.Result;
+import java.io.IOException;
import java.util.List;
public interface PersonService {
@@ -22,4 +24,12 @@ public interface PersonService {
Result> getHouseId();
Result updatePerson(Person person);
+
+ Result uuApplyUserInfo(List importList);
+
+ List searchAdmin(Person person);
+
+ String derive() throws IOException;
+
+
}
diff --git a/community-security-modules/community-security-modules-shop/src/main/java/com/zyh/system/service/impl/PersonServicempl.java b/community-security-modules/community-security-modules-shop/src/main/java/com/zyh/system/service/impl/PersonServicempl.java
index e6dc5fa..4163414 100644
--- a/community-security-modules/community-security-modules-shop/src/main/java/com/zyh/system/service/impl/PersonServicempl.java
+++ b/community-security-modules/community-security-modules-shop/src/main/java/com/zyh/system/service/impl/PersonServicempl.java
@@ -1,19 +1,39 @@
package com.zyh.system.service.impl;
+import com.alibaba.excel.EasyExcel;
+import com.alibaba.excel.ExcelWriter;
+import com.alibaba.excel.write.metadata.WriteSheet;
+import com.alibaba.excel.write.style.column.LongestMatchColumnWidthStyleStrategy;
+import com.zyh.common.Enum.WriteRowsOption;
import com.zyh.common.domain.House;
import com.zyh.common.domain.Person;
+import com.zyh.common.domain.PersonTest;
import com.zyh.common.result.Result;
+import com.zyh.common.util.ImportExeclUtil;
+import com.zyh.common.utils.StringUtils;
import com.zyh.system.mapper.PersonMapper;
import com.zyh.system.service.PersonService;
+import lombok.extern.log4j.Log4j2;
+import org.apache.poi.ss.usermodel.Cell;
+import org.apache.poi.ss.usermodel.Row;
+import org.apache.poi.ss.usermodel.Sheet;
+import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
+import javax.servlet.http.HttpServletResponse;
+import java.io.*;
+import java.util.ArrayList;
import java.util.List;
+import java.util.regex.Pattern;
@Service
+@Log4j2
public class PersonServicempl implements PersonService {
@Autowired
private PersonMapper personMapper;
+ @Autowired
+ private HttpServletResponse response;
@Override
public Result addPerson(Person person) {
Integer add = personMapper.addPerson(person);
@@ -75,4 +95,344 @@ public class PersonServicempl implements PersonService {
}
return Result.error("更新失败");
}
+
+ @Override
+ public Result uuApplyUserInfo(List importList) {
+ int i = 0;
+ List importResultColumn = new ArrayList<>(); // 新列,用于存储导入结果
+ List resultList = createResultList(importList);
+ if (resultList.size() == 0) {
+ for (PersonTest personTest : importList) {
+ try {
+ Integer add = personMapper.addPersonTest(personTest);
+
+ // 修改房间人数
+ personMapper.updatepersonNumjia(personTest.getBuildId(), personTest.getUnit(), personTest.getHoldId());
+ i++;
+
+ log.info("第" + i + "条导入成功");
+ importResultColumn.add("导入成功");
+ } catch (Exception e) {
+ i++;
+ log.error("第" + i + "条导入失败,失败原因:" + e.getMessage());
+ importResultColumn.add("导入失败,原因:" + e.getMessage());
+ }
+ }
+ }else{
+ for (String s : resultList) {
+ importResultColumn.add(s);
+ }
+ }
+
+
+ // 向原始Excel文件添加新列
+ updateOriginalExcel(importList, importResultColumn);
+
+ return Result.success("导入完毕");
+ }
+
+ private void updateOriginalExcel(List importList, List importResultColumn) {
+ String fileName = "PersonTest";
+ try {
+ // 加载原始Excel文件
+ ImportExeclUtil readExcelUtil = new ImportExeclUtil();
+ List> originalData = readExcelUtil.read(new FileInputStream("D:/2104A/daochu/" + fileName + ".xlsx"), true);
+
+
+
+ // 将导入结果值添加到每一行
+ for (int i = 0; i < importList.size(); i++) {
+ originalData.get(i).add(importResultColumn.get(i)); // 注意索引的调整
+ }
+
+ // 将更新后的数据写回原始Excel文件
+ writeDataToOriginalExcel(originalData, "D:/2104A/daochu/" + fileName + ".xlsx");
+ } catch (IOException e) {
+ log.error("更新原始Excel文件时出错:" + e.getMessage());
+ }
+ }
+
+ private void writeDataToOriginalExcel(List> data, String filePath) {
+ try {
+ Workbook wb = ImportExeclUtil.chooseWorkbook(filePath, new FileInputStream(filePath));
+ Sheet sheet = wb.getSheetAt(0);
+
+ // 清空第一行以下的所有行,保留第一行标题
+ for (int i = sheet.getLastRowNum(); i > 0; i--) {
+ Row row = sheet.getRow(i);
+ if (row != null) {
+ sheet.removeRow(row);
+ }
+ }
+
+ // 将数据写入表格,从第二行开始
+ for (int i = 0; i < data.size(); i++) {
+ Row row = sheet.createRow(i + 1); // 注意这里是 i + 1
+ for (int j = 0; j < data.get(i).size(); j++) {
+ Cell cell = row.createCell(j);
+
+ // 将空值用空字符串代替,你也可以使用其他默认值
+ String cellValue = data.get(i).get(j) != null ? data.get(i).get(j) : "";
+ cell.setCellValue(cellValue);
+ }
+ }
+
+ // 将更改写回文件
+ try (FileOutputStream fileOut = new FileOutputStream(filePath)) {
+ wb.write(fileOut);
+ }
+
+ // 关闭工作簿
+ wb.close();
+ } catch (IOException e) {
+ log.error("将数据写入原始Excel文件时出错:" + e.getMessage());
+ }
+ }
+
+
+
+ @Override
+ public List searchAdmin(Person person) {
+ return personMapper.searchAdmin(person);
+ }
+
+ @Override
+ public String derive() throws IOException {
+ download();
+ return null;
+ }
+
+
+
+
+
+ public void download() throws IOException {
+ log.info("*********导出开始!**************");
+ long startTime = System.currentTimeMillis();
+ String fileName = "PersonTest";
+ OutputStream outputStream = null;
+
+ try {
+ int totalCount = WriteRowsOption.TOTAL_COUNT; // 总行数
+ int sheetDataRows = WriteRowsOption.SHEET_DATA_ROWS; // 每个 Sheet 的行数
+ int writeDataRows = WriteRowsOption.WRITE_DATA_ROWS; // 每次写入的行数
+
+ // 获取路径
+ String filePath = "D:/2104A/daochu/" + fileName + ".xlsx";
+
+ // 计算需要的 Sheet 数量
+ Integer sheetNum = totalCount % sheetDataRows == 0 ? (totalCount / sheetDataRows) : (totalCount / sheetDataRows + 1);
+ // 计算一般情况下每一个 Sheet 需要写入的次数
+ Integer oneSheetWriteCount = sheetDataRows / writeDataRows;
+ // 计算最后一个 Sheet 需要写入的次数
+ Integer lastSheetWriteCount = totalCount % sheetDataRows == 0 ?
+ oneSheetWriteCount :
+ (totalCount % sheetDataRows % writeDataRows == 0 ?
+ (totalCount / sheetDataRows / writeDataRows) :
+ (totalCount / sheetDataRows / writeDataRows + 1));
+ outputStream = new FileOutputStream(filePath);
+ ExcelWriter excelWriter = EasyExcel.write(outputStream).build();
+
+ for (int i = 0; i < sheetNum; i++) {
+ // 创建 Sheet
+ WriteSheet sheet = new WriteSheet();
+ sheet.setSheetName("Sheet" + i);
+ sheet.setSheetNo(i);
+
+ for (int j = 0; j < (i != sheetNum - 1 ? oneSheetWriteCount : lastSheetWriteCount); j++) {
+ // 创建 WriteSheet
+ WriteSheet writeSheet = EasyExcel.writerSheet(i, "Sheet" + (i + 1)).head(PersonTest.class)
+ .registerWriteHandler(new LongestMatchColumnWidthStyleStrategy()).build();
+
+ // 从数据库中提取数据
+ List data = fetchDataFromDatabase(i * sheetDataRows + j * writeDataRows, writeDataRows);
+ // 将数据写入 Excel
+ excelWriter.write(data, writeSheet);
+ }
+ }
+
+ long endTime = System.currentTimeMillis();
+ long elapsedTime = endTime - startTime;
+ log.info("*********导出结束!导出耗时:" + elapsedTime + "毫秒**************");
+
+ // 关闭 ExcelWriter
+ excelWriter.finish();
+ outputStream.flush();
+ outputStream.close();
+
+ // 返回给前端的响应
+ response.setContentType("application/octet-stream");
+ response.setCharacterEncoding("utf-8");
+ response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");
+
+ // 从生成的文件读取内容并写入响应输出流
+ try (InputStream inputStream = new FileInputStream(filePath);
+ OutputStream responseOutputStream = response.getOutputStream()) {
+ byte[] buffer = new byte[1024];
+ int bytesRead;
+ while ((bytesRead = inputStream.read(buffer)) != -1) {
+ responseOutputStream.write(buffer, 0, bytesRead);
+ }
+ }
+
+ // 删除生成的文件
+// File file = new File(filePath);
+// if (file.exists()) {
+// file.delete();
+// }
+
+ } catch (Exception e) {
+ e.printStackTrace();
+ } finally {
+ if (outputStream != null) {
+ outputStream.close();
+ }
+ }
+ }
+
+ /**
+ * 从数据库中获取数据
+ *
+ * @param offset 偏移量
+ * @param limit 限制数量
+ * @return 数据列表
+ */
+ public List fetchDataFromDatabase(int offset, int limit) {
+ // 调用数据库查询方法以检索数据,注意在 SQL 查询中使用 offset 和 limit
+ return personMapper.stuListWithLimit(offset, limit);
+ }
+
+
+ private List createResultList(List importList) {
+ List resultList = new ArrayList<>();
+ for (PersonTest personTest : importList) {
+ StringBuilder ret=new StringBuilder();
+ //姓名验证
+ if (StringUtils.isEmpty(personTest.getName())) {
+ ret.append("姓名不能为空"+" ");
+ }
+
+ //身份证号验证
+ if (StringUtils.isEmpty(personTest.getIdcard())) {
+ ret.append("身份证号不能为空" + " ");
+ }else{
+ if (!idcardRule(personTest.getIdcard())) {
+ ret.append("身份证号格式有误" + " ");
+ }
+
+ }
+
+ //身份证号编号验证
+ if (personTest.getIdcardType()==null) {
+ ret.append("身份证类型编号不能为空" + " ");
+ }else {
+ if (personTest.getIdcardType() != 1 && personTest.getIdcardType() != 2 && personTest.getIdcardType() != 3 && personTest.getIdcardType() != 4) {
+ ret.append("身份证类型编号必须1-4数字(1居民身份证 2军官证 3警官证 4普通护照)" + " ");
+
+ }
+ }
+
+
+ //出生日期验证
+ if (StringUtils.isEmpty(personTest.getBirth())) {
+ ret.append("出生日期不能为空" + " ");
+ }
+
+ //民族验证
+ if (StringUtils.isEmpty(personTest.getNation())) {
+ ret.append("民族不能为空" + " ");
+ }
+
+ //性别验证
+ if (personTest.getSex()==null) {
+ ret.append("性别不能为空" + " ");
+ }else{
+ if (personTest.getSex() != 1 && personTest.getSex() != 2 && personTest.getSex() != 3) {
+ ret.append("性别必须1-3数字(1男2女3未知)" + " ");
+ }
+ }
+
+
+ //手机号验证
+ if (StringUtils.isEmpty(personTest.getPhone())) {
+ ret.append("手机号不能为空" + " ");
+ }else{
+ if (!telRule(personTest.getPhone())) {
+ ret.append("手机号格式有误" + " ");
+ }
+ }
+
+
+ //户籍验证
+ if (StringUtils.isEmpty(personTest.getAddress())) {
+ ret.append("地址不能为空" + " ");
+ }
+
+ //小区编号验证
+ if (StringUtils.isEmpty(personTest.getHouseId())) {
+ ret.append("小区编号不能为空" + " ");
+ }else{
+ int re= personMapper.selectHouseId(personTest.getHouseId());
+ if (re<=0) {
+ ret.append("小区编号不存在" + " ");
+ }
+ }
+
+ //楼栋编号验证
+ if (personTest.getBuildId()==null) {
+ ret.append("楼栋编号不能为空" + " ");
+ }else{
+ Integer buildId = personMapper.selectBuildId(personTest.getBuildId());
+ if (buildId<=0 || buildId==null) {
+ ret.append("楼栋编号不存在" + " ");
+ }
+ }
+
+ //单元编号验证
+ if (personTest.getUnit()==null) {
+ ret.append("单元编号不能为空" + " ");
+ }else{
+ if (personTest.getBuildId() != null) {
+ Integer unit = personMapper.selectUnit(personTest.getBuildId(),personTest.getUnit());
+ if (unit<=0 || unit==null) {
+ ret.append("单元编号不存在" + " ");
+ }
+ }
+
+ }
+
+ //房号编号验证
+ if (personTest.getHoldId()==null) {
+ ret.append("房号编号不能为空" + " ");
+ }else{
+ if (personTest.getBuildId() != null && personTest.getUnit() != null) {
+ Integer holdId = personMapper.selectHoldId(personTest.getBuildId(),personTest.getUnit(),personTest.getHoldId());
+ if (holdId<=0 || holdId==null) {
+ ret.append("房号编号不存在" + " ");
+ }
+ }
+
+ }
+
+ //身份证照片验证
+ if (StringUtils.isEmpty(personTest.getPic())) {
+ ret.append("身份证照片不能为空" + " ");
+ }
+
+ resultList.add(ret.toString());
+ }
+ return resultList;
+ }
+ private boolean telRule(String phone) {
+ Pattern compile = Pattern.compile("^(?:(?:\\+|00)86)?1(?:(?:3[\\d])|(?:4[5-7|9])|(?:5[0-3|5-9])|(?:6[5-7])|(?:7[0-8])|(?:8[\\d])|(?:9[1|8|9]))\\d{8}$");
+
+ return compile.matcher(phone).matches();
+ }
+
+ private boolean idcardRule(String idcard) {
+ Pattern compile = Pattern.compile("^[1-9]\\\\d{5}(18|19|20)\\\\d{2}(0[1-9]|1[0-2])(0[1-9]|[12]\\\\d|3[01])\\\\d{3}(\\\\d|X|x)$");
+
+ return compile.matcher(idcard).matches();
+ }
+
}
diff --git a/community-security-modules/community-security-modules-shop/src/main/resources/mapper/PersonMapper.xml b/community-security-modules/community-security-modules-shop/src/main/resources/mapper/PersonMapper.xml
index dbe368f..7a6402a 100644
--- a/community-security-modules/community-security-modules-shop/src/main/resources/mapper/PersonMapper.xml
+++ b/community-security-modules/community-security-modules-shop/src/main/resources/mapper/PersonMapper.xml
@@ -20,6 +20,23 @@
#{holdId},
#{pic})
+
+ insert into person values
+ (0,
+ #{name},
+ #{idcard},
+ #{idcardType},
+ #{birth},
+ #{sex},
+ #{nation},
+ #{phone},
+ #{address},
+ #{houseId},
+ #{buildId},
+ #{unit},
+ #{holdId},
+ #{pic})
+
update person set
name = #{name},
@@ -67,6 +84,24 @@
+
+
+
+
+
+