Commit 4e48a3eb by yukang

物料导入

parent d423d2ab
...@@ -155,6 +155,12 @@ ...@@ -155,6 +155,12 @@
<artifactId>poi-ooxml</artifactId> <artifactId>poi-ooxml</artifactId>
<version>5.2.3</version> <version>5.2.3</version>
</dependency> </dependency>
<dependency>
<groupId>net.sourceforge.jexcelapi</groupId>
<artifactId>jxl</artifactId>
<version>2.6.12</version>
</dependency>
</dependencies> </dependencies>
<build> <build>
......
package com.baosight.hpjx.common;
/**
* ErrorCodeEnum
*
* @author 张弘毅
* @date 2018-10-31 14:21
*/
public enum ErrorCodeEnum {
//数据库常见异常列表
DB_ERROR_CODE_F803("-803","数据库中已有相同主键的条目,错误编码:-803"),//不能插入行,因为这将违反唯一索引的约束
DB_ERROR_CODE_Z204("+204","命名的对象未在DB2中定义,错误编码:+204"),
DB_ERROR_CODE_F204("-204","没有定义的对象名,错误编码:-204"),
DB_ERROR_CODE_F302("-302","新增或修改中有数据不符合要求,错误编码:-302"),//输入的变量值对指定的列无效
DB_ERROR_CODE_F402("-402","算术函数不能用于字符或日期时间数据,错误编码:-402"),
DB_ERROR_CODE_F119("-119","HAVING语句中的列的列表与GROUP BY语句中的列列表不匹配,错误编码:-119"),
DB_ERROR_CODE_F117("-117","待插入的数值的个数于被插入的行中的列数不相等,错误编码:-117"),
DB_ERROR_CODE_F407("-407","主键不能有空或全为空,错误编码:-407"),
;
private String code;
private String description;
ErrorCodeEnum(String code, String description) {
this.code = code;
this.description = description;
}
public String getCode() {
return code;
}
public String getDescription() {
return description;
}
}
...@@ -54,5 +54,9 @@ public class HPConstants { ...@@ -54,5 +54,9 @@ public class HPConstants {
/** 前后台交互下拉框字段 字段名 dzg */ /** 前后台交互下拉框字段 字段名 dzg */
public static final String VALUE_FIELD = "valueField"; public static final String VALUE_FIELD = "valueField";
public static final String PARAM_FILENAME = "fileName";
/** domain字段 PARAM_FILENAME 导入文件暂存路径 LC*/
public static final String PARAM_CLASSNAME = "className";
} }
package com.baosight.hpjx.hp.ff.service;
import com.baosight.hpjx.common.HPConstants;
import com.baosight.hpjx.hp.sc.domain.HPSC002;
import com.baosight.hpjx.util.ExcelUtils;
import com.baosight.iplat4j.core.ei.EiInfo;
import com.baosight.iplat4j.core.service.impl.ServiceEPBase;
import java.util.HashMap;
import java.util.Map;
public class ServiceHPFF001 extends ServiceEPBase {
/**
* 根据模板导入数据
*/
public EiInfo importDate(EiInfo inInfo) {
String fileName = inInfo.getString(HPConstants.PARAM_FILENAME);
String className = inInfo.getString(HPConstants.PARAM_CLASSNAME);
//解析文件,将文件中数据传入到inInfo中
switch (className){
/**
* 物料
*/
case "HPSC002":
String parentId = inInfo.getString("parentId");
String parentPrdtName = inInfo.getString("parentPrdtName");
String projCode = inInfo.getString("projCode");
String projName = inInfo.getString("projName");
int lv = inInfo.getInt("lv");
Map map = new HashMap<>();
map.put("parentId",parentId);
map.put("parentPrdtName",parentPrdtName);
map.put("projCode",projCode);
map.put("projName",projName);
map.put("lv",lv+1);
ExcelUtils.importFromExcel(inInfo, fileName,map, new HPSC002());
break;
}
return inInfo;
}
}
package com.baosight.hpjx.util;
import com.baosight.hpjx.common.ErrorCodeEnum;
import com.baosight.iplat4j.core.ei.EiConstant;
import com.baosight.iplat4j.core.ei.EiInfo;
/**
* ErrorCodeUtils
*
* @author 张弘毅
* @date 2018-10-31 14:01
*/
public class ErrorCodeUtils {
/**
* 返回处理的错误信息
* @param info 存放有系统报错日志的EiInfo对象,注意返回时要返回该对象
* @return
*/
public static int getErrorMessage(EiInfo info){
//防止再次进入
if("error".equals(info.getString("errorFlag"))){
return EiConstant.STATUS_FAILURE;
}
info.setStatus(EiConstant.STATUS_FAILURE);
if(info.getMsg().indexOf(SQL_ERROR_WORD1) != -1){
SQLErrorMessage(info,SQL_ERROR_WORD1);
return EiConstant.STATUS_SUCCESS;
}else if(info.getMsg().indexOf(SQL_ERROR_WORD2) != -1){
SQLErrorMessage(info,SQL_ERROR_WORD2);
return EiConstant.STATUS_SUCCESS;
}else{
info.setMsg("未知错误");
info.setDetailMsg("信息:系统出现异常错误,请联系系统管理员。");
}
info.set("errorFlag","error");
return EiConstant.STATUS_FAILURE;
}
/**
* 提供给com.baosight.sgca.utils.ErrorAspect使用的方法
* @param info 处理报错json数据
* @return
*/
public static String getErrorMessage(String info){
if(info.indexOf(SQL_ERROR_WORD1) != -1){
return SQLErrorMessage(info,SQL_ERROR_WORD1);
}else if(info.indexOf(SQL_ERROR_WORD2) != -1){
return SQLErrorMessage(info,SQL_ERROR_WORD2);
}
return info;
}
/**
* sql错误信息处理
* @param info
* @param ErrorWord
* @return
*/
private static void SQLErrorMessage(EiInfo info,String ErrorWord){
String detail = "信息:";
boolean falg = false;
String code = info.getMsg().substring(info.getMsg().indexOf(ErrorWord)+ErrorWord.length(),info.getMsg().indexOf(ErrorWord)+ErrorWord.length()+4);
ErrorCodeEnum[] errorCodeEnums = ErrorCodeEnum.values();
for (ErrorCodeEnum errorCodeEnum : errorCodeEnums){
if(errorCodeEnum.getCode().equals(code)){
detail+=errorCodeEnum.getDescription()+"\n";
falg=true;
}
}
//替换掉框架中的报错信息
String title = "数据库错误";
info.setMsg(title);
if(falg){
info.setDetailMsg(detail);
}else{
info.setDetailMsg(detail+"数据库出现异常错误,请联系系统管理员。错误代码:"+code);
}
}
private static String SQLErrorMessage(String errorInfo,String ErrorWord){
String detail = "数据库错误\n";
String errorMessageBody = "";
boolean falg = false;
String code = errorInfo.substring(errorInfo.indexOf(ErrorWord)+ErrorWord.length(),errorInfo.indexOf(ErrorWord)+ErrorWord.length()+4);
ErrorCodeEnum[] errorCodeEnums = ErrorCodeEnum.values();
for (ErrorCodeEnum errorCodeEnum : errorCodeEnums){
if(errorCodeEnum.getCode().equals(code)){
errorMessageBody=errorCodeEnum.getDescription();
falg=true;
}
}
//替换掉框架中的报错信息
detail += "信息:";
if(falg){
detail+=errorMessageBody;
}else{
detail+="数据库出现异常错误,请联系系统管理员。";
}
return detail;
}
private static final String SQL_ERROR_WORD1 = "SQLCODE=";
private static final String SQL_ERROR_WORD2 = "Error Code:";
}
\ No newline at end of file
package com.baosight.hpjx.util; package com.baosight.hpjx.util;
import com.baosight.hpjx.core.constant.CommonConstant;
import com.baosight.hpjx.hp.pz.tools.HPPZTools;
import com.baosight.hpjx.hp.sc.domain.HPSC002;
import com.baosight.hpjx.util.importer.Importer;
import com.baosight.hpjx.util.importer.impl.XlsImporter;
import com.baosight.iplat4j.core.data.DaoEPBase;
import com.baosight.iplat4j.core.data.ibatis.SqlMapClientTemplate;
import com.baosight.iplat4j.core.ei.EiBlock;
import com.baosight.iplat4j.core.ei.EiConstant;
import com.baosight.iplat4j.core.ei.EiInfo;
import com.baosight.iplat4j.core.exception.PlatException;
import com.baosight.iplat4j.core.ioc.spring.PlatApplicationContext;
import com.baosight.iplat4j.core.web.threadlocal.UserSession;
import com.ibatis.sqlmap.client.SqlMapClient;
import org.apache.commons.collections.MapUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.poi.hssf.usermodel.HSSFWorkbook; import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import java.io.IOException; import java.io.IOException;
import java.io.OutputStream; import java.io.OutputStream;
import java.math.BigDecimal;
import java.net.URLEncoder; import java.net.URLEncoder;
import java.sql.SQLException;
import java.text.DecimalFormat;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/** /**
* @author:songx * @author:songx
...@@ -13,6 +36,37 @@ import java.net.URLEncoder; ...@@ -13,6 +36,37 @@ import java.net.URLEncoder;
*/ */
public class ExcelUtils { public class ExcelUtils {
public static final String SQL_OK_BLOCK = "sql_ok_block";
public static final String CHECK_OK_BLOCK = "check_ok_block";
/**
* 数据重复或数据主键为空的错误数据
*/
public static final String DATA_ERROR_BLOCK = "data_error_block";
/**
* 插入时sql错误的错误数据
*/
public static final String SQL_ERROR_BLOCK = "sql_error_block";
/**
* 主键空值判断标记名称
*/
public static final String FLAG_NOT_NULL = "flagNotNull";
/**
* 主键全部不为空flag
*/
public static final String FLAG_ALL_NOT_NULL = "allNotNull";
/**
* 无主键flag
*/
public static final String FLAG_NOT_PK = "notPK";
/**
* 主键不全为空flag(缺省值)
*/
public static final String FLAG_ONLY_NOT_NULL = "onlyNotNull";
public static final String SQL_OK_LINE = "sql_ok_line";
private static SqlMapClientTemplate sqlMapClientTemplate = new SqlMapClientTemplate();
protected static Logger logger = LogManager.getLogger(ExcelUtils.class);
/** /**
* 下载文件 * 下载文件
* *
...@@ -34,4 +88,156 @@ public class ExcelUtils { ...@@ -34,4 +88,156 @@ public class ExcelUtils {
os.close(); os.close();
} }
/**
*
* Excel导入功能(可以自定义默认值)创建人信息和修改人信息已经自动填充,不需要再次自定义
*
* @param inInfo info
* @param excelFilePath 文件路径
* @param bean bean对象
* @return EiInfo
*/
public static EiInfo importFromExcel(EiInfo inInfo, String excelFilePath, Map params, DaoEPBase bean) throws PlatException {
return importFromExcel(inInfo,excelFilePath,bean.getClass().getSimpleName() + ".insert",params,bean);
}
/**
*
* Excel导入功能(可以自定义默认值)创建人信息和修改人信息已经自动填充,不需要再次自定义
*
* @param inInfo info
* @param excelFilePath 文件路径
* @param insertSql 新增语句
* @param params 自定义默认值
* @param bean bean对象
* @throws PlatException
*/
public static EiInfo importFromExcel(EiInfo inInfo, String excelFilePath, String insertSql, Map params, DaoEPBase bean) throws PlatException{
return importFromExcel(inInfo,excelFilePath,insertSql,params,bean,(map)->{});
}
/**
*
* Excel导入功能(可以自定义默认值)创建人信息和修改人信息已经自动填充,不需要再次自定义
*
* @param inInfo info
* @param excelFilePath 文件路径
* @param insertSql 新增语句
* @param params 自定义默认值
* @param bean bean对象
* @param filterExcelFunction 自定义校验函数
* @throws PlatException
*/
public static EiInfo importFromExcel(EiInfo inInfo ,String excelFilePath ,String insertSql ,Map params, DaoEPBase bean,FilterExcelFunction filterExcelFunction) throws PlatException{
if(MapUtils.isNotEmpty(params)){
inInfo = readFromExcel(inInfo,excelFilePath,params, bean);
}else{
inInfo = readFromExcel(inInfo,excelFilePath,null, bean);
}
if (inInfo.getStatus() == EiConstant.STATUS_FAILURE){
return inInfo;
}
int result = 0;
//函数验证 数据大与1w时,启用并行计算
if(inInfo.getBlock(SQL_OK_BLOCK).getRowCount()<=10_000){
inInfo.getBlock(SQL_OK_BLOCK).getRows().forEach(filterExcelFunction);
}else{
inInfo.getBlock(SQL_OK_BLOCK).getRows().parallelStream().forEach(filterExcelFunction);
}
logger.info("the path of the import Excel : "+ excelFilePath);
if(inInfo.getBlock(SQL_OK_BLOCK).getRowCount()==0){
inInfo.setStatus(EiConstant.STATUS_FAILURE);
inInfo.setMsg("导入失败");
inInfo.setDetailMsg("数据不符合要求,导入0条");
return inInfo;
}
String className = insertSql.substring(0,8);
List arrayList = inInfo.getBlock(SQL_OK_BLOCK).getRows();
// 数据校验
switch (className){
/**
* 物料
*/
case "HPSC002":
materialCheck(inInfo);
break;
}
return inInfo;
}
/**
* 导入beans逻辑
* @param inInfo
* @param filename
* @param params
* @param daoEPBase
* @return
* @throws PlatException
* @throws Exception
*/
private static EiInfo readFromExcel(EiInfo inInfo,String filename,Map params, DaoEPBase daoEPBase) {
inInfo.setStatus(EiConstant.STATUS_DEFAULT);
EiBlock userAttribute = new EiBlock("userAttribute");
userAttribute.setCell(0, "recCreator", UserSession.getLoginName() + "-" + UserSession.getLoginCName());
inInfo.addBlock(userAttribute);
String fileType = filename.substring(filename.lastIndexOf(".") + 1).toLowerCase();
switch (fileType)
{
case "xls":
case "xlsx":
Importer Importer = new XlsImporter();
Importer.importData(inInfo,filename,params,daoEPBase);
break;
default:
inInfo.setStatus(EiConstant.STATUS_FAILURE);
inInfo.setMsg("请导入xls或xlsx文件类型的文件");
}
return inInfo;
}
private static EiInfo materialCheck(EiInfo inInfo) {
StringBuffer sb = new StringBuffer();
Boolean checkStatus = false;
List arrayList = inInfo.getBlock(SQL_OK_BLOCK).getRows();
EiBlock checkOkBlock = inInfo.addBlock(ExcelUtils.CHECK_OK_BLOCK);
checkOkBlock.setBlockMeta(new HPSC002().eiMetadata);
for (int i = 0;i < arrayList.size(); i++) {
// 层级与部件类型对应关系
HPSC002 HPSC002 = (HPSC002)arrayList.get(i);
//层级2
if (HPSC002.getLv() == 2 && HPSC002.getPrdtType() != 4) {
sb.append("导入失败:数据错误"+(i+1)+"条,层级关系错误,当前层级只能导入部件清单!!");
checkStatus = true;
} else if (HPSC002.getLv() == 3 && HPSC002.getPrdtType() != 3) {
sb.append("导入失败:数据错误"+(i+1)+"条,层级关系错误,当前层级只能导入零件清单!!");
checkStatus = true;
}
//完善数据
HPSC002.setLeaf("1");
// 计算总重
BigDecimal num = HPSC002.getNum();
BigDecimal unitWt = HPSC002.getUnitWt();
DecimalFormat decimalFormat = new DecimalFormat("#.000");
BigDecimal totalWt = new BigDecimal(decimalFormat.format(Math.round(num.multiply(unitWt).floatValue())));
HPSC002.setDelStatus(CommonConstant.YesNo.NO_0.intValue());
HPSC002.setTotalWt(totalWt);
HPSC002.setSpec(HPPZTools.jointSpec(HPSC002.getLength(),HPSC002.getWidth(),HPSC002.getThick()));
HPSC002.setPrdtCode(HPPZTools.checkAndSavePZ04(HPSC002.getPrdtType(),HPSC002.getPrdtName()));
if (checkStatus) {
checkOkBlock.addRow(HPSC002.toMap());
}
}
if (!checkStatus) {
inInfo.setStatus(EiConstant.STATUS_FAILURE);
inInfo.setMsg(sb.toString());
}
inInfo.set("checkStatus",checkStatus);
return inInfo;
}
} }
package com.baosight.hpjx.util;
import java.util.Map;
import java.util.function.Consumer;
/**
* 导入校验函数体
* @implSpec
* <p> 使用方法(在需要导入自定义校验的地方):
* <pre>
* {@code
* FilterExcelFuction filterExcelFuction = (map)->{
* map.get("key");
* };
* importFromExcel(inInfo,excelFilePath,params,bean,filterExcelFuction);
* }
* </pre>
* <p>或
* <pre>
* {@code
* importFromExcel(inInfo,excelFilePath,params,bean,(map)->{
* map.get("key");
* });
* }
* </pre>
*
* @author Jerry
* @date 2019年7月8日
*/
@FunctionalInterface
public interface FilterExcelFunction extends Consumer<Map>{
}
package com.baosight.hpjx.util.importer;
import com.baosight.iplat4j.core.data.DaoEPBase;
import com.baosight.iplat4j.core.ei.EiInfo;
import java.util.Map;
/**
* Importer
* 导入接口类 提供定制化导入接口
*
* @author 张弘毅
* @date 2019-08-12 7:55 AM
*/
public interface Importer {
/**
* 需要实现的导入具体方法
* @param inInfo
* @param filename
* @param params
* @param daoEPBase
* @return
*/
public void importData(EiInfo inInfo, String filename, Map params, DaoEPBase daoEPBase);
}
package com.baosight.hpjx.util.importer.impl;
import com.baosight.hpjx.util.ExcelUtils;
import com.baosight.hpjx.util.importer.Importer;
import com.baosight.iplat4j.core.data.DaoEPBase;
import com.baosight.iplat4j.core.ei.EiBlock;
import com.baosight.iplat4j.core.ei.EiColumn;
import com.baosight.iplat4j.core.ei.EiConstant;
import com.baosight.iplat4j.core.ei.EiInfo;
import com.baosight.iplat4j.core.exception.PlatException;
import com.baosight.iplat4j.core.util.DateUtils;
import com.baosight.iplat4j.core.util.NumberUtils;
import com.baosight.iplat4j.core.util.StringUtils;
import com.baosight.iplat4j.core.web.threadlocal.UserSession;
import jxl.Cell;
import jxl.CellType;
import jxl.NumberCell;
import jxl.read.biff.BiffException;
import org.apache.commons.collections.MapUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import java.io.File;
import java.io.IOException;
import java.util.*;
/**
* XlsImporter
*
* @author 张弘毅
* @date 2019-08-12 7:55 AM
*/
public class XlsImporter implements Importer {
protected static Logger logger = LogManager.getLogger(XlsImporter.class);
@Override
public void importData(EiInfo inInfo, String filename, Map params, DaoEPBase daoEPBase) {
EiBlock dataErrorBlock = inInfo.addBlock(ExcelUtils.DATA_ERROR_BLOCK);
EiBlock sqlErrorBlock = inInfo.addBlock(ExcelUtils.SQL_ERROR_BLOCK);
EiBlock sqlOkBlock = inInfo.addBlock(ExcelUtils.SQL_OK_BLOCK);
dataErrorBlock.setBlockMeta(daoEPBase.eiMetadata);
sqlErrorBlock.setBlockMeta(daoEPBase.eiMetadata);
sqlOkBlock.setBlockMeta(daoEPBase.eiMetadata);
jxl.Workbook workbook = null;
jxl.Sheet sheet = null;
try {
jxl.WorkbookSettings workbookSettings = new jxl.WorkbookSettings();
//关键代码,解决中文乱码
workbookSettings.setEncoding("GBK");
workbook = jxl.Workbook.getWorkbook(new File(filename), workbookSettings);
} catch (IOException e) {
inInfo.setStatus(EiConstant.STATUS_FAILURE);
inInfo.setMsg(e.toString());
throw new PlatException(e);
} catch (BiffException e) {
inInfo.setStatus(EiConstant.STATUS_FAILURE);
inInfo.setMsg(e.toString());
throw new PlatException(e);
}
sheet = workbook.getSheet(0);
//从第二行开始,第一行为标题
Cell[] columnList = sheet.getRow(0);
int sqlNumber = 0;
for (int rows = 1; rows < sheet.getRows(); rows++) {
DaoEPBase bean = null;
Cell cell1 = sheet.getCell(0,rows);
if (cell1 == null || cell1.getType().equals(CellType.EMPTY)) {
continue;
}
try {
bean = (DaoEPBase) Class.forName(daoEPBase.getClass().getName()).newInstance();
} catch (InstantiationException e) {
inInfo.setStatus(EiConstant.STATUS_FAILURE);
inInfo.setMsg(e.toString());
throw new PlatException(e);
} catch (IllegalAccessException e) {
inInfo.setStatus(EiConstant.STATUS_FAILURE);
inInfo.setMsg(e.toString());
throw new PlatException(e);
} catch (ClassNotFoundException e) {
inInfo.setStatus(EiConstant.STATUS_FAILURE);
inInfo.setMsg(e.toString());
throw new PlatException(e);
}
//获得bean中列名列表
Map metas = daoEPBase.eiMetadata.getMetas();
Map beanValue = new LinkedHashMap(16);
Iterator keys = metas.keySet().iterator();
for (int i = 0; i < metas.size(); i++) {
Object key = keys.next();
EiColumn column = (EiColumn) metas.get(key);
String keyValue = column.getName();
String keyCname = column.getCname();
//在第一行进行搜索
Cell cell = sheet.findCell(keyCname,0,0,100,1,false);
if(cell==null){
continue;
}
//将表格第一行与元数据中的中文进行匹配
String columnValue = sheet.getCell(cell.getColumn(), rows).getContents();
if (MapUtils.isNotEmpty(params)&&params.get(key)!=null){
if(StringUtils.isNotEmpty(params.get(key).toString())){
columnValue = params.get(key).toString();
}
}
if(keyCname.equals(cell.getContents())){
//处理字典
if (columnValue.indexOf("-") > 0) {
beanValue.put(keyValue, columnValue.split("-")[0]);
continue;
}
//数字进行特定转换
if (column.getType()=="N"){
try {
beanValue.put(keyValue, ((NumberCell)sheet.getCell(cell.getColumn(), rows)).getValue());
} catch (Exception e) {
beanValue.put(keyValue, 0);
}
}else{
if(columnValue.endsWith(".0")){
columnValue = columnValue.substring(0,columnValue.length()-2);
}
beanValue.put(keyValue, columnValue);
}
continue;
}
}
//自定义默认值
if (MapUtils.isNotEmpty(params)){
Iterator paramsKeys = params.keySet().iterator();
paramsKeys.forEachRemaining((Object key)-> {
String keyValue = key.toString();
String value = params.get(key).toString();
beanValue.put(keyValue, value);
});
}
//直接进行插入动作 防止空白列插入
boolean flagB = false;
String str;
Collection collection;
try {
collection = beanValue.values();
for (Object item:collection) {
if(item==null){
flagB=true;
}else {
str = item.toString();
str.replace(" ", "");
if(NumberUtils.toint(str)!=0){
flagB=false;
}else{
if(str.length()==0){
flagB=true;
}else{
flagB=false;
break;
}
}
}
}
}catch (NullPointerException e){
logger.info("this is null record!");
break;
}
if(flagB){
continue;
}
bean.fromMap(beanValue);
sqlOkBlock.addRow(bean);
sqlNumber++;
}
inInfo.set(ExcelUtils.SQL_OK_LINE,sqlNumber);
}
}
package com.baosight.hpjx.util.importer.impl;
import com.baosight.hpjx.util.ExcelUtils;
import com.baosight.hpjx.util.importer.Importer;
import com.baosight.iplat4j.core.data.DaoEPBase;
import com.baosight.iplat4j.core.ei.EiBlock;
import com.baosight.iplat4j.core.ei.EiColumn;
import com.baosight.iplat4j.core.ei.EiConstant;
import com.baosight.iplat4j.core.ei.EiInfo;
import com.baosight.iplat4j.core.exception.PlatException;
import com.baosight.iplat4j.core.util.DateUtils;
import com.baosight.iplat4j.core.util.NumberUtils;
import com.baosight.iplat4j.core.util.StringUtils;
import org.apache.commons.collections.MapUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
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.xssf.usermodel.XSSFWorkbook;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.*;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.ForkJoinTask;
import java.util.concurrent.RecursiveTask;
/**
* XlsxImporter
*
* @author 张弘毅
* @date 2019-08-12 7:55 AM
*/
public class XlsxImporter implements Importer {
protected static Logger logger = LogManager.getLogger(XlsxImporter.class);
@Override
public void importData(EiInfo inInfo, String filename, Map params, DaoEPBase daoEPBase) {
EiBlock dataErrorBlock = inInfo.addBlock(ExcelUtils.DATA_ERROR_BLOCK);
EiBlock sqlErrorBlock = inInfo.addBlock(ExcelUtils.SQL_ERROR_BLOCK);
EiBlock sqlOkBlock = inInfo.addBlock(ExcelUtils.SQL_OK_BLOCK);
dataErrorBlock.setBlockMeta(daoEPBase.eiMetadata);
sqlErrorBlock.setBlockMeta(daoEPBase.eiMetadata);
sqlOkBlock.setBlockMeta(daoEPBase.eiMetadata);
Workbook workbook = null;
Sheet sheet = null;
try {
workbook = new XSSFWorkbook(new FileInputStream(filename));
} catch (IOException e) {
inInfo.setStatus(EiConstant.STATUS_FAILURE);
inInfo.setMsg(e.toString());
throw new PlatException(e);
}
sheet = workbook.getSheetAt(0);
int sqlNumber = 0;
//运行并行任务
XlsxReadTask xlsxReadTask = new XlsxReadTask(1,sheet.getLastRowNum(),sheet,inInfo,params,daoEPBase);
ForkJoinPool forkJoinPool = new ForkJoinPool();
ForkJoinTask<List> result = forkJoinPool.submit(xlsxReadTask);
try {
sqlOkBlock.setRows(result.get());
} catch (Exception e) {
inInfo.setStatus(EiConstant.STATUS_FAILURE);
inInfo.setMsg(e.toString());
throw new PlatException(e);
}
inInfo.set(ExcelUtils.SQL_OK_LINE,sqlNumber);
}
}
class XlsxReadTask extends RecursiveTask<List> {
private int start;
private int end;
Sheet sheet;
DaoEPBase daoEPBase;
EiInfo inInfo;
Map params;
Row columnList;
private List result;
/**
* 每五万条做拆分
*/
private static final int MAX_VALUE = 50_000;
public XlsxReadTask(int start, int end,Sheet sheet,EiInfo inInfo,Map params,DaoEPBase daoEPBase) {
this.start = start;
this.end = end;
this.sheet = sheet;
this.inInfo = inInfo;
this.params = params;
this.daoEPBase = daoEPBase;
//从第二行开始,第一行为标题
this.columnList = sheet.getRow(0);
result = new ArrayList();
}
@Override
protected List compute() {
if(Math.abs(start-end)<=MAX_VALUE){
for (int rows = start; rows <= end; rows++) {
//空行判断逻辑和主键空值的数据
boolean flag;
if(ExcelUtils.FLAG_NOT_PK.equals(inInfo.get(ExcelUtils.FLAG_NOT_NULL))) {
flag = false;
}else{
if (ExcelUtils.FLAG_ALL_NOT_NULL.equals(inInfo.get(ExcelUtils.FLAG_NOT_NULL))) {
flag = false;
} else {
flag = true;
}
}
//获得bean中列名列表
Map metas = daoEPBase.eiMetadata.getMetas();
Map beanValue = new LinkedHashMap(16);
Iterator keys = metas.keySet().iterator();
for (int i = 0; i < metas.size(); i++) {
Object key = keys.next();
EiColumn column = (EiColumn) metas.get(key);
String keyValue = column.getName();
String keyCname = column.getCname();
//将表格第一行与元数据中的中文进行匹配
for (int j = 0; j< columnList.getLastCellNum();j++) {
Cell cell = columnList.getCell(j);
if (keyCname.equals(cell.getStringCellValue())) {
Cell valueCell = sheet.getRow(rows).getCell(cell.getColumnIndex());
//有时候这里会拿到空,很奇怪
if(valueCell==null){
beanValue.put(keyValue, "");
}else {
if (column.getType()=="N"){
try {
beanValue.put(keyValue, valueCell.getNumericCellValue());
} catch (Exception e) {
beanValue.put(keyValue, 0);
}
}else{
switch (valueCell.getCellType()) {
case Cell.CELL_TYPE_STRING:
beanValue.put(keyValue, StringUtils.toString(valueCell.getRichStringCellValue().getString()));
break;
case Cell.CELL_TYPE_NUMERIC:
String columnValue = String.valueOf(valueCell.getNumericCellValue());
if(columnValue.endsWith(".0")){
columnValue = columnValue.substring(0,columnValue.length()-2);
}
beanValue.put(keyValue, columnValue);
break;
default:
beanValue.put(keyValue, "");
break;
}
}
break;
}
//自定义数值覆盖
if (MapUtils.isNotEmpty(params) && params.get(key) != null) {
if (StringUtils.isNotEmpty(params.get(key).toString())) {
beanValue.put(keyValue, params.get(key).toString());
}
}
//主键为空判断
if (!ExcelUtils.FLAG_NOT_PK.equals(inInfo.get(ExcelUtils.FLAG_NOT_NULL))) {
if (ExcelUtils.FLAG_ALL_NOT_NULL.equals(inInfo.get(ExcelUtils.FLAG_NOT_NULL))) {
if (column.isPrimaryKey() && !StringUtils.isNotEmpty(beanValue.get(keyValue).toString())) {
flag = true;
}
} else {
if (column.isPrimaryKey() && StringUtils.isNotEmpty(beanValue.get(keyValue).toString())) {
flag = false;
}
}
}
}
}
}
//自定义默认值
if (MapUtils.isNotEmpty(params)){
Iterator paramsKeys = params.keySet().iterator();
paramsKeys.forEachRemaining((Object key)-> {
String keyValue = key.toString();
String value = params.get(key).toString();
beanValue.put(keyValue, value);
});
}
//不符合要求的数据不进行插入动作
if(flag){
continue;
}
//直接进行插入动作 防止空白列插入
boolean flagB = false;
String str;
Collection collection;
try {
collection = beanValue.values();
for (Object item:collection) {
if(item==null){
flagB=true;
}else {
str = item.toString();
str.replace(" ", "");
if(NumberUtils.toint(str)!=0){
flagB=false;
}else{
if(str.length()==0){
flagB=true;
}else{
flagB=false;
break;
}
}
}
}
}catch (NullPointerException e){
break;
}
if(flagB){
continue;
}
String recId = UUID.randomUUID().toString().replace("-", "");
beanValue.put("recId", recId);
beanValue.put("recCreator", inInfo.getCell("userAttribute", 0, "recCreator"));
// beanValue.put("recCreatorCname", UserInfoSession.getUserName());
beanValue.put("recCreateTime", DateUtils.curDateTimeStr14());
// beanValue.put("recRevisor", UserSession.getLoginName());
//beanValue.put("recRevisorCname", UserInfoSession.getUserName());
// beanValue.put("recReviseTime", DateUtils.curDateTimeStr14());
result.add(beanValue);
}
}else{
//大于5w使用二分法分配任务
int middle = Math.round(Math.abs(start-end)/2);
XlsxReadTask xlsxReadTaskLeft = new XlsxReadTask(start,middle,sheet,inInfo,params,daoEPBase);
XlsxReadTask xlsxReadTaskRight = new XlsxReadTask(middle+1,end,sheet,inInfo,params,daoEPBase);
xlsxReadTaskLeft.fork();
xlsxReadTaskRight.fork();
result.addAll(xlsxReadTaskLeft.join());
result.addAll(xlsxReadTaskRight.join());
}
return result;
}
}
...@@ -342,7 +342,70 @@ $(function () { ...@@ -342,7 +342,70 @@ $(function () {
] ]
}, },
}; };
IPLATUI /**
* 导入
*/
$("#IMPORT").on("click", function (e) {
var logic = IPLATUI.EFTree.materialTree.selectTreeNode.nodeId ? false : true;
if (logic) { // 通过业务逻辑判断, 控制是否进行新增
IPLAT.alert({
message: '<b>请选择项目列表</b>',
okFn: function (e) {
},
title: '提示'
});
e.preventDefault();
} else {
openFileWindow.open();
}
});
IPLATUI.EFUpload = {
fileUpload: {
showFileList: false,
upload: function (e) {
openFileWindow.close();
IPLAT.progress($("body"), true);
},
success: function (e) {
debugger;
var src = e.response.docUrl;
var className = e.response.docTag;
var parentId = IPLATUI.EFTree.materialTree.selectTreeNode.nodeId;
var parentPrdtName = IPLATUI.EFTree.materialTree.selectTreeNode.prdtName;
var projCode = IPLATUI.EFTree.materialTree.selectTreeNode.projCode;
var projName = IPLATUI.EFTree.materialTree.selectTreeNode.projName;
var lv = IPLATUI.EFTree.materialTree.selectTreeNode.lv;
var eiInfo = new EiInfo();
eiInfo.set("fileName", src);
eiInfo.set("className", className);
eiInfo.set("parentId", parentId);
eiInfo.set("parentPrdtName", parentPrdtName);
eiInfo.set("projCode", projCode);
eiInfo.set("projName", projName);
eiInfo.set("lv", lv);
EiCommunicator.send("HPFF001", "importDate", eiInfo, {
onSuccess: function (ei) {
if (ei.status == "-1") {
NotificationUtil({msg: ei.msg, detailMsg: ei.detailMsg}, "error");
} else {
NotificationUtil(ei.msg);
}
},
onFail: function (ei) {
NotificationUtil("调用失败,原因[" + ei + "]", "error");
}
}, {
async: false
});
IPLAT.progress($("body"), false);
},
fail: function (e) {
IPLAT.NotificationUtil('导入失败!', "error");// 失败提示信息
}
}
}
// 关闭事件 // 关闭事件
IPLATUI.EFWindow = { IPLATUI.EFWindow = {
......
...@@ -102,6 +102,12 @@ ...@@ -102,6 +102,12 @@
<%-- EEDM8010页面加载时,不会加载EEDM6000 (lazyload="true") --%> <%-- EEDM8010页面加载时,不会加载EEDM6000 (lazyload="true") --%>
<EF:EFWindow id="uploadFile" url="${ctx}/web/HPSC099" lazyload="true" refresh="true"> <EF:EFWindow id="uploadFile" url="${ctx}/web/HPSC099" lazyload="true" refresh="true">
</EF:EFWindow> </EF:EFWindow>
<EF:EFWindow id="openFile">
<EF:EFRegion id="upload" title="文件导入区">
<div id="button"></div>
<EF:EFUpload ename="fileUpload" cname="导入" docTag="HPSC002" path="upload"/>
</EF:EFRegion>
</EF:EFWindow>
</EF:EFPage> </EF:EFPage>
<script> <script>
let ctx="${ctx}"; let ctx="${ctx}";
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment