Java POI 多线程导入导出

1.多线程的导入导出。

导出的话是用JAVA POI excel导出,其中遇到的问题有两点。
其一:大量数据的导出
解决方案:用SXSSFWorkbook新excel可以导出超过6.5w条数据,而用03版的excel只能导出低于6.5w条的数据
其二:导出速度慢
解决方案:用分页和多线程的思想解决

1.Java Controller层,与前端对接

/**
 * @函数名称:export Control层<BR>
 * @创建日期:2018年9月10日<BR>
 * @功能说明:导出<BR>
 * @参数说明:<BR>
 * @返回说明:ModelAndView
 */
@RequestMapping("/export/{nti}")
public ModelAndView export(HttpServletRequest request, HttpServletResponse response, AwbQueryNewQ querys, @PathVariable("nti") Integer nti) {
	response.setContentType("application/vnd.ms-excel");
	response.setCharacterEncoding("UTF-8");
	//获取当前登录的账号信息
	UserAccount account = (UserAccount) SecurityUtils.getSubject().getPrincipal();
	try {
		// 查询所有操作日志
		List<AwbInfo> awbInfos = awbQueryNewService.findAllV2(querys.getNumPerPage(), querys.getPageNum(), null, generateWhere(querys), generateOrders(querys),account);
		awbInfos = flightRoute2CH(awbInfos);
		// 进行转码,使其支持中文文件名
		awbQueryNewService.export(nti, awbInfos, request, response, querys.getOperDateBeginQ(), querys.getOperDateEndQ());
		return null;
	} catch (Exception e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
		return ajaxDoneError("下载失败,如有问题请联系管理员");
	}
}

2.service层中多线程导出
其中start,end用到分页的思想

/**
 * 
 * @功能说明:查询运单表线程
 * @创建人员:HjwJames
 * @变更记录:<BR>
 * 1、2019年9月11日 HjwJames 新建类
 */
class Task implements Callable<List<AwbInfo>> {
	Integer start;
	Integer end;
	List<String> fields;
	List<Where> wheres;
	List<Order> orders;
	UserAccount account;

	Task(Integer start, Integer end, List<String> fields, List<Where> wheres, List<Order> orders, UserAccount account) {
		this.start = start;
		this.end = end;
		this.fields = fields;
		this.wheres = wheres;
		this.orders = orders;
		this.account = account;
	}

	@Override
	public List<AwbInfo> call() throws Exception {
		List<AwbInfo> list = null;
		try {
			list = awbInfoDao.getAwbInfosV2(start, end, fields, wheres, orders, account);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return list;
	}

}

3.启动多线程,3000条数据/线程。
其中用到了callable和future和线程池,最后排序

/**
 * 
 * @函数名称:findAllV2
 * @创建日期:2019年9月17日
 * @author HjwJames
 * @功能说明:运单查询多线程导出
 * @参数说明:
 * @返回说明:List<AwbInfo>
 */
@Override
@TargetDataSource(name = "cargo_market_slave")
public List<AwbInfo> findAllV2(int numPerPage, int pageNum, List<String> fields, List<Where> wheres, List<Order> orders, UserAccount account)
		throws Exception {
	// 数据总数
	Integer total = awbInfoDao.getAwbInfosTotal(wheres, orders, account);
	// 分页数
	Integer num = 3000;
	// 结果集合
	List<AwbInfo> result = new ArrayList<>();
	// 需要查询的次数
	int times = total / num;
	if (total % num != 0) {
		times = times + 1;
	}
	// Callable用于产生结果
	List<Callable<List<AwbInfo>>> tasks = new ArrayList<>();
	Integer start = 0;
	Integer end = total < num ? total : num;
	for (int i = 0; i < times; i++) {
		Callable<List<AwbInfo>> task = new Task(start, end, fields, wheres, orders, account);
		tasks.add(task);
		start = num * (i + 1);
		end = num;
	}
	// 定义固定长度的线程池 防止线程过多
	ExecutorService executorService = Executors.newFixedThreadPool(15);
	// Future用于获取结果
	List<Future<List<AwbInfo>>> futures = executorService.invokeAll(tasks);
	// 处理线程返回结果
	if (futures != null && futures.size() > 0) {
		for (Future<List<AwbInfo>> future : futures) {
			result.addAll(future.get());
		}
	}
	executorService.shutdown();// 关闭线程池
	Collections.sort(result, new Comparator<AwbInfo>() {
		@Override
		public int compare(AwbInfo o1, AwbInfo o2) {
			return o1.getRowNumber().compareTo(o2.getRowNumber());
		}
	});
	return result;
}

4.最后这是dao层

	/**
    *
    * @函数名称:getAwbInfosV2
    * @创建日期:2019年9月17日10:55:46
    * @功能说明:销售系统---->运单查询---->excel导出部分数据
    * @参数说明:
    * @返回说明:List<AwbInfo>
    */
   public List<AwbInfo> getAwbInfosV2(int start, int end, List<String> fields, List<Where> wheres, List<Order> orders, UserAccount account)
           throws Exception {
       Map<String, Object> whereMap = this.generateWhere(wheres); // Generate
       //StringBuffer whereSb = (StringBuffer) whereMap.get(WHERE_IDS);
       Object[] objects = whereMap.get(WHERE_OBJECTS) == null ? null : (Object[]) whereMap.get(WHERE_OBJECTS);
       StringBuilder sqlSb = new StringBuilder();

       sqlSb.append(generateAwbQuerySql(start, end, wheres, orders, account));
       log.debug("SQL: " + sqlSb.toString());
       List<AwbInfo> resultList = this.getDataList(getJdbcTemplate(), sqlSb.toString(), objects);
       return resultList;
   }

5.excel表格的绘制(写的不是很优秀)

/**
 * @throws Exception 
 * @函数名称:export<BR>
 * @创建日期:2018年9月10日<BR>
 * @功能说明:导出数据<BR>
 * @参数说明:<BR>
 * @返回说明:void
 */
@Override
public void export(Integer nti, List<AwbInfo> awbInfos, HttpServletRequest request, HttpServletResponse response, String operDateBeginQ,
		String operDateEndQ) throws Exception {
	try {
		// 产生工作簿对象
		SXSSFWorkbook workbook = new SXSSFWorkbook();
		// 产生工作表对象
		Sheet sheet = workbook.createSheet("运单查询导出");
		// 创建单元格样式,注意,这里只是声明,需要下面用到才可以
		CellStyle style = workbook.createCellStyle();
		style.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);// 垂直居中
		style.setAlignment(HSSFCellStyle.ALIGN_CENTER);// 水平居中
		CellStyle style_left = workbook.createCellStyle();
		style_left.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);
		style_left.setAlignment(HSSFCellStyle.ALIGN_LEFT);
		// 左对齐
		CellStyle style2 = workbook.createCellStyle();
		style2.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);// 垂直居中
		style2.setAlignment(HSSFCellStyle.ALIGN_LEFT);// 水平居左
		// 行是从0开始
		String[] str = { "前缀", "单号", "运单状态", "制单时间", "制单人", "代理人", "始发站", "目的站", "航程", "航班日期", "开单航班", "走货航班", "发货人", "收货人", "承运人", "储运事项", "品名",
				"舱位", "件数", "重量", "计费重量", "费率", "航空运费", "总金额", "运价代码", "处理代码", "支付方式", "运单类型", "运输件数差额", "运输重量差额", "运输件数", "运输重量", "集装器",
				"运单来源" };
		// s设置宽度
		sheet.setColumnWidth(3, 5000);
		sheet.setColumnWidth(8, 4000);
		sheet.setColumnWidth(12, 5000);
		sheet.setColumnWidth(13, 5000);
		sheet.setColumnWidth(15, 4000);
		sheet.setColumnWidth(16, 5000);
		Row rowTop = sheet.createRow(0);
		// 列是从0开始,
		for (int i = 0; i < str.length; i++) {
			Cell cellTop = rowTop.createCell(i);
			cellTop.setCellValue(str[i]);
			cellTop.setCellStyle(style_left);
		}
		Map<String, String> dictInfos = dictInfoRedisDao.findAll("CABIN_LEVEL", BoolStatus.Y.getId());
		// 合计
		Double piecesTotal = 0d;
		Double weightTotal = 0d;
		Double chargeWeightTotal = 0d;
		Double feeRateTotal = 0d;
		Double totalfeeRateTotal = 0d;
		Double totalAllFeeTotal = 0d;
		int i = 0;
		// 下面就是循环生成,主要的内容了 start
		if (CollectionUtils.isNotEmpty(awbInfos)) {
			for (i = 0; i < awbInfos.size(); i++) {
				Row row = sheet.createRow(i + 1);
				row.createCell(0).setCellValue(awbInfos.get(i).getAwbPrefix());
				row.createCell(1).setCellValue(awbInfos.get(i).getAwbNo()==null?null:Integer.parseInt(awbInfos.get(i).getAwbNo()));
				row.createCell(2).setCellValue(awbInfos.get(i).getStatus());
				row.createCell(3).setCellValue(DateUtil.formatDate(awbInfos.get(i).getOperDate(), DateUtil.LONGDATE_DATETIME));
				row.createCell(4).setCellValue(awbInfos.get(i).getOperName());
				row.createCell(5).setCellValue(awbInfos.get(i).getAgentCode());
				row.createCell(6).setCellValue(awbInfos.get(i).getDepCode());
				row.createCell(7).setCellValue(awbInfos.get(i).getDestCode());
				row.createCell(8).setCellValue(awbInfos.get(i).getFlightRoute() == null ? "" : awbInfos.get(i).getFlightRoute());
				row.createCell(9).setCellValue(awbInfos.get(i).getFlightDate());
				row.createCell(10).setCellValue(awbInfos.get(i).getFlightNo2());
				row.createCell(11).setCellValue(awbInfos.get(i).getFlightNo() == null ? "" : awbInfos.get(i).getFlightNo());
				row.createCell(12).setCellValue(sqlDecoding(awbInfos.get(i).getShpInfo()));
				row.createCell(13).setCellValue(sqlDecoding(awbInfos.get(i).getCneInfo()));
				row.createCell(14).setCellValue(sqlDecoding(awbInfos.get(i).getCarrierCode()));
				row.createCell(15).setCellValue(sqlDecoding(awbInfos.get(i).getTransNote()));
				row.createCell(16).setCellValue(sqlDecoding(awbInfos.get(i).getGoodsName()));
				row.createCell(17).setCellValue(dictInfos.get(awbInfos.get(i).getCabinLevel()));
				row.createCell(18).setCellValue(awbInfos.get(i).getPieces() == null ? 0.0 : awbInfos.get(i).getPieces());
				row.createCell(19).setCellValue(awbInfos.get(i).getWeight() == null ? 0.0 : awbInfos.get(i).getWeight());
				row.createCell(20).setCellValue(awbInfos.get(i).getChargeWeight() == null ? 0.0 : awbInfos.get(i).getChargeWeight());
				row.createCell(21).setCellValue(awbInfos.get(i).getFeeRate() == null ? 0.0 : awbInfos.get(i).getFeeRate());
				row.createCell(22).setCellValue(awbInfos.get(i).getTotalFee() == null ? 0.0 : awbInfos.get(i).getTotalFee());
				row.createCell(23).setCellValue(awbInfos.get(i).getTotalAllFee() == null ? 0.0 : awbInfos.get(i).getTotalAllFee());
				String aliasCode = StringUtils.isEmpty(awbInfos.get(i).getAliasCode()) ? "" : "(" + awbInfos.get(i).getAliasCode() + ")";
				row.createCell(24).setCellValue(awbInfos.get(i).getBillCode() + aliasCode);
				row.createCell(25).setCellValue(awbInfos.get(i).getDealCode());
				row.createCell(26).setCellValue(awbInfos.get(i).getPayType());
				row.createCell(27).setCellValue(awbInfos.get(i).getEawb());
				row.createCell(28).setCellValue(awbInfos.get(i).getPiecesDif() == null ? 0.0 : awbInfos.get(i).getPiecesDif());
				row.createCell(29).setCellValue(awbInfos.get(i).getWeightDif() == null ? 0.0 : awbInfos.get(i).getWeightDif());
				row.createCell(30).setCellValue(awbInfos.get(i).getTransPc() == null ? 0 : awbInfos.get(i).getTransPc());
				row.createCell(31).setCellValue(awbInfos.get(i).getTransWeight() == null ? 0.0 : awbInfos.get(i).getTransWeight());
				row.createCell(32).setCellValue(awbInfos.get(i).getActLocation() == null ? "" : awbInfos.get(i).getActLocation());
				row.createCell(33).setCellValue(awbInfos.get(i).getSourceName());
				// 合计
				if (awbInfos.get(i).getPieces() != null) {
					piecesTotal += awbInfos.get(i).getPieces();
				}
				if (awbInfos.get(i).getWeight() != null) {
					weightTotal += awbInfos.get(i).getWeight();
				}
				if (awbInfos.get(i).getChargeWeight() != null) {
					chargeWeightTotal += awbInfos.get(i).getChargeWeight();
				}
				if (awbInfos.get(i).getTotalFee() != null) {
					feeRateTotal += awbInfos.get(i).getTotalFee();
				}
				if (awbInfos.get(i).getTotalAllFee() != null) {
					totalfeeRateTotal += awbInfos.get(i).getTotalAllFee();
				}
				if (awbInfos.get(i).getTotalAllFee() != null) {
					totalAllFeeTotal += awbInfos.get(i).getTotalAllFee();
				}

				for (int j = 0; j < str.length; j++) {
					if (j == 3 || j == 12 || j == 13 || j == 15 || j == 16) {
						row.getCell(j).setCellStyle(style2);
					} else {
						row.getCell(j).setCellStyle(style);
					}
				}
			}
			// 合计
			Row row = sheet.createRow(i + 1);
			row.createCell(0).setCellValue("合计");
			row.getCell(0).setCellStyle(style);
			row.createCell(1).setCellValue("");
			row.getCell(1).setCellStyle(style);
			row.createCell(2).setCellValue("");
			row.getCell(2).setCellStyle(style);
			row.createCell(3).setCellValue("");
			row.getCell(3).setCellStyle(style);
			row.createCell(4).setCellValue("");
			row.getCell(4).setCellStyle(style);
			row.createCell(5).setCellValue("");
			row.getCell(5).setCellStyle(style);
			row.createCell(6).setCellValue("");
			row.getCell(6).setCellStyle(style);
			row.createCell(7).setCellValue("");
			row.getCell(7).setCellStyle(style);
			row.createCell(8).setCellValue("");
			row.getCell(8).setCellStyle(style);
			row.createCell(9).setCellValue("");
			row.getCell(9).setCellStyle(style);
			row.createCell(10).setCellValue("");
			row.getCell(10).setCellStyle(style);
			row.createCell(11).setCellValue("");
			row.getCell(11).setCellStyle(style);
			row.createCell(12).setCellValue("");
			row.getCell(12).setCellStyle(style);
			row.createCell(13).setCellValue("");
			row.getCell(13).setCellStyle(style);
			row.createCell(14).setCellValue("");
			row.getCell(14).setCellStyle(style);
			row.createCell(15).setCellValue("");
			row.getCell(15).setCellStyle(style);
			row.createCell(16).setCellValue("");
			row.getCell(16).setCellStyle(style);
			row.createCell(17).setCellValue("");
			row.getCell(17).setCellStyle(style);
			row.createCell(18).setCellValue(piecesTotal);
			row.getCell(18).setCellStyle(style);
			row.createCell(19).setCellValue(weightTotal);
			row.getCell(19).setCellStyle(style);
			row.createCell(20).setCellValue(chargeWeightTotal);
			row.getCell(20).setCellStyle(style);
			row.createCell(21).setCellValue("");
			row.getCell(21).setCellStyle(style);
			row.createCell(22).setCellValue(feeRateTotal);
			row.getCell(22).setCellStyle(style);
			row.createCell(23).setCellValue(totalfeeRateTotal);
			row.getCell(23).setCellStyle(style);
			row.createCell(24).setCellValue("");
			row.getCell(24).setCellStyle(style);
			row.createCell(25).setCellValue("");
			row.getCell(25).setCellStyle(style);
			row.createCell(26).setCellValue("");
			row.getCell(26).setCellStyle(style);
			row.createCell(27).setCellValue("");
			row.getCell(27).setCellStyle(style);
			row.createCell(28).setCellValue("");
			row.getCell(28).setCellStyle(style);
			row.createCell(29).setCellValue("");
			row.getCell(29).setCellStyle(style);
			row.createCell(30).setCellValue("");
			row.getCell(30).setCellStyle(style);
			row.createCell(31).setCellValue("");
			row.getCell(31).setCellStyle(style);
			row.createCell(32).setCellValue("");
			row.getCell(32).setCellStyle(style);
			row.createCell(33).setCellValue("");
			row.getCell(33).setCellStyle(style);
		}
		// 下面是封装好的方法,第一个参数,是文件名,第二个是上面的工作薄对象,
		new ExcelUtil().doExcel("AwbQueryExport", workbook, request, response);
	} catch (Exception e) {
		e.printStackTrace();
		throw new Exception("操作异常");
	}

}

6.excel工具类

/**
	 * 
	 * @函数名称:doExcel
	 * @创建日期:2019年9月23日
	 * @author HjwJames
	 * @功能说明:导出新版excel 可容纳多数据格式 xlsx,处理大量导出(超过6.5W条数据)
	 * @参数说明:
	 * @返回说明:void
	 */
	public void doExcel(String fileName, XSSFWorkbook workbookList, HttpServletRequest request, HttpServletResponse response) {
		// TODO Auto-generated method stub
		HttpSession session = request.getSession();
		session.setAttribute("state", null);
		// 生成提示信息
		OutputStream fOut = null;
		try {
			response.setCharacterEncoding("utf-8");
			response.setHeader("content-disposition", "attachment;filename=" + new String(fileName.getBytes("utf-8"), "ISO8859-1") + ".xlsx");
			// 产生工作簿对象
			XSSFWorkbook workbook = workbookList;
			fOut = response.getOutputStream();
			workbook.write(fOut);
		} catch (UnsupportedEncodingException e1) {

		} catch (Exception e) {

		} finally {
			try {
				fOut.flush();
				fOut.close();
			} catch (IOException e) {

			}
			session.setAttribute("state", "open");
		}
	}

2.多线程导入

1.首先Controller层与html对接,很普通没什么好讲解的

/**
 * 
 * @函数名称:importExcel<BR>
 * @创建日期:2019年4月30日<BR>
 * @功能说明:<BR>excel导入
 * @参数说明:<BR>
 * @返回说明:ModelAndView<BR>
 */
@RequestMapping(value = "/uploadify")
public ModelAndView importExcel(@RequestParam("file") MultipartFile file, HttpServletRequest request, boolean isCustFlag, boolean importflag)
		throws Exception {
	String errorMessage = null;// 错误信息
	if (file != null) {// 判断上传的文件是否为空
		String type = null;// 文件类型
		String fileName = file.getOriginalFilename();// 文件原名称
		type = fileName.indexOf(".") != -1 ? fileName.substring(fileName.lastIndexOf(".") + 1, fileName.length()) : null;// 文件类型
		if (type != null) {// 判断文件类型是否为空
			if ("XLS".equals(type.toUpperCase()) || "XLSX".equals(type.toUpperCase())) {
				errorMessage = dangerSpecialService.readFile(file, isCustFlag, importflag);// 读取excel文件 TODO
			} else {
				errorMessage = "请选择正确的excel文件!";
			}
		} else {
			errorMessage = "文件类型为空!";
		}
	} else {
		errorMessage = "请选择上传文件!";
	}
	if (StringUtils.isNotEmpty(errorMessage)) {
		return ajaxDoneError(errorMessage);
	} else {
		return ajaxDoneSuccess("文件上传成功!");
	}
}

2.service层,验证参数是否为空,是否合法。最后指引到多线程上传路层
详解:1.首先多线程导入需要用多Collections.synchronizedList ,多线程list
2.遍历excel和object的映射机制将数据并上传到List中
3.当数据处理好转换成list时交给下一步多线程上传

/**
	 * 用于excel导入
	 * 从file中读取数据到list
	 */
	@Override
	@Transactional(rollbackFor = Exception.class)
	public String readFile(MultipartFile file, boolean isCustFlag, boolean type) throws Exception {
		try {
			String[] fields = new String[] { "dsName", "goodName", "dealCode" };
			Workbook wb = WorkbookFactory.create(file.getInputStream());
			Sheet sheet = wb.getSheetAt(0);// 读取第一个sheet
			Row row = null;
			int index = 0;// 行号
			int lastRowNum = fields.length;// 总列数
			Iterator<Row> rowIterator = sheet.iterator();
			List<DangerSpecialXls> list = Collections.synchronizedList(new ArrayList<>());
			while (rowIterator.hasNext()) {
				index++;
				row = rowIterator.next();
				DangerSpecialXls hdgXls = new DangerSpecialXls();
				if (index == 1) {
					// 当index=1时,第一行为标题
					continue;
				}
				if (null == row) {
					// 当row为空时,为空行,跳过
					continue;
				}
				hdgXls.setRowId(index);// 设置行号
				for (int i = 0; i < lastRowNum; i++) {
					Integer columnIndex = 0;// 单元格号
					try {
						Cell cell = row.getCell(i);
						if (i == 0 && null == cell) {
							throw new Exception("导入错误,xls第" + hdgXls.getRowId() + "行第" + (i + 1) + "列为空单元格!");
						}
						String res = "";
						if (cell != null) {// 当cell为空时,给默认string “”
							columnIndex = cell.getColumnIndex();
							// 将数字或其他类型强制转化位string
							cell.setCellType(XSSFCell.CELL_TYPE_STRING);
							res = this.getCellValue(cell);
							// 双重验证
							if (columnIndex == 0 && StringUtils.isBlank(this.getCellValue(cell))) {
								// 校验必填项
								throw new Exception("导入错误,xls第" + hdgXls.getRowId() + "行第" + (columnIndex + 1) + "列为空单元格!");
							}
						} else {
							columnIndex = i;
							res = "";
						}
						objSetValue(hdgXls, fields[columnIndex], res);
					} catch (Exception e) {
						log.error("导入错误,xls第" + hdgXls.getRowId() + "行第" + (columnIndex + 1) + "列错误!", e);
						if (StringUtils.isEmpty(e.getMessage())) {
							throw new Exception("导入错误,xls第" + hdgXls.getRowId() + "行第" + (columnIndex + 1) + "列错误!");
						} else {
							throw new Exception(e.getMessage());
						}
					}
				}
				list.add(hdgXls);
			}
			String res = checkDataAndSave(list, isCustFlag, type);
			return res;
		} catch (Exception e) {
			e.printStackTrace();
			return e.getMessage();
		}
	}

3.映射基类

/**
 * @函数名称:objSetValue
 * @创建日期:
 * @功能说明:通过反射给Object设值
 * @参数说明:
 * @返回说明:void
 */
private void objSetValue(Object obj, String fieldName, String fieldValue) {
	try {
		Class class1 = obj.getClass();
		Field[] fields = class1.getDeclaredFields();
		for (Field field : fields) {
			field.setAccessible(true);
			String name = field.getName().toLowerCase();
			if (name.equals(fieldName.toLowerCase())) {
				field.set(obj, fieldValue);
				break;
			}
		}
	} catch (Exception e) {
		e.printStackTrace();
	}
}

4.多线程上传
详情解析:1.开启forkjoin线程池ForkJoinPool(32)
2.用java8 新特性stream写法遍历list myPool.submit(() -> list.parallelStream().forEach
获取单个xls类
3.xls进行数据校验
4.导入单条数据,并做好exception捕获

/**
 * 
 * @函数名称:checkDataAndSave
 * @创建日期:2019年4月17日
 * @功能说明:只用于导入 数据验证与输入
 * @参数说明:
 * @返回说明:void
 */
private String checkDataAndSave(List<DangerSpecialXls> list, boolean isCustFlag, boolean type) throws Exception {
	if (CollectionUtils.isEmpty(list)) {
		throw new Exception("导入数据不能为空!");
	}
	List<Integer> errorList = new ArrayList<Integer>();
	List<String> resList = new ArrayList<String>();
	ForkJoinPool myPool = new ForkJoinPool(32);
	Date date = new Date();
	Integer ver = dangerSpecialDao.getVerIdSequence();// 获取ver批次号
	myPool.submit(() -> list.parallelStream().forEach(xls -> {
		try {
			DangerSpecial hg = new DangerSpecial();
			// hg.setDangerId(Integer.parseInt(xls.getDangerId())); id 自增不需要填写
			if (xls.getGoodName().contains("!") || xls.getGoodName().contains("@") || xls.getGoodName().contains("#")
					|| xls.getGoodName().contains("*") || xls.getGoodName().contains("/") || xls.getGoodName().contains("$")
					|| xls.getGoodName().contains("%") || xls.getGoodName().contains("&") || xls.getGoodName().contains("'")
					|| xls.getGoodName().contains("\"") || xls.getGoodName().contains(";")) {

				resList.add("第" + xls.getRowId() + "行:存在特殊字符;");
			} else if (xls.getDsName().contains("!") || xls.getDsName().contains("@") || xls.getDsName().contains("#")
					|| xls.getDsName().contains("*") || xls.getDsName().contains("/") || xls.getDsName().contains("$")
					|| xls.getDsName().contains("%") || xls.getDsName().contains("&") || xls.getDsName().contains("'")
					|| xls.getDsName().contains("\"") || xls.getDsName().contains(";") || xls.getDsName().contains(",")) {

				resList.add("第" + xls.getRowId() + "行:存在特殊字符;");
			} else {

				// 导入单条数据
				String[] mes = iDangerSpecialService.importSingleDate(xls, type, isCustFlag, date, ver);
				String res = "";

				if (null != mes) {
					if (StringUtils.isNotEmpty(mes[0])) {
						res += "第" + xls.getRowId() + "行:配置品名[" + mes[0] + "]异常;";
					}
					if (StringUtils.isNotEmpty(mes[1])) {
						if (StringUtils.isEmpty(mes[0])) {
							res += "第" + xls.getRowId() + "行:";
						}
						mes[1] = mes[1].substring(0, mes[1].length() - 1);
						res += "处理代码[" + mes[1] + "]不存在或异常";
					}
				}

				if (StringUtils.isNotEmpty(res)) {
					resList.add(res);
				}

			}
		} catch (Exception e) {

			String error = e.getMessage();
			String res = "";
			if (error.equals("参数异常")) {
				res += "第" + xls.getRowId() + "行:" + e.getMessage();
			} else {
				res += "第" + xls.getRowId() + "行:" + "参数异常!";
			}
			if (StringUtils.isNotEmpty(res)) {
				resList.add(res);
			}

		}
	})).get();

	if (CollectionUtils.isNotEmpty(resList)) {
		Collections.sort(resList);
		StringBuffer msg = new StringBuffer("导入错误。");
		for (int i = 0; i < resList.size(); i++) {
			msg.append(resList.get(i));
		}
		// throw new Exception(msg.toString());
		return msg.toString();
	}

	return null;

}

5.Dao层importSingleDate数据添加(无关痛痒的Dao数据存储)

/**
	 * 
	 * @throws Exception 
	 * @函数名称:importSingleDate
	 * @创建日期:2019年5月15日
	 * @功能说明:用于批量导入中单条数据导入处理
	 * @参数说明:importflag true -->追加 / false -->替换  / ver--->version批次号
	 * @返回说明:DangerSpecial
	 */
	@Override
//	@Transactional(rollbackFor = Exception.class)
	public String[] importSingleDate(DangerSpecialXls xls, Boolean importflag, boolean isCustFlag, Date date, Integer verion) throws Exception {
		String mes1 = "";// SpecialGood 错误报告
		String mes2 = "";// DangerDeal 错误报告
		DangerSpecial hg = new DangerSpecial();
		String ver = Integer.toString(verion);// 版本批次号
		// 获取固定条件
		List<Where> wheres = new ArrayList<Where>();
		wheres.add(new Where("DS_NAME", xls.getDsName().toUpperCase()));
		try {
			UserAccount userAccount = (UserAccount) SecurityUtils.getSubject().getPrincipal();
			if (importflag == true) {
				// 追加导入
				DangerSpecial ds = dangerSpecialDao.find(wheres);
				if (null == ds) {// 主表不存在,导入主表,再导入从表

					// 主表新增
					Integer dsId = this.insertXls(xls, userAccount, isCustFlag, date, ver);
					// 新增到危险品及特种货物分类绑定品名表
					mes1 = this.insertMultiSpecialGood(xls, userAccount, date, ver, dsId);/// TODO
					// 新增到危险品及特种货物分类绑定处理代码
					mes2 = this.insertMultiDangerDeal(xls, userAccount, date, ver, dsId);// TODO
				} else {// 主表存在,更新主表,追加导入从表

					// 更新主表,追加导入
					String mes3 = this.updateAddXls(xls, userAccount, isCustFlag, date, ver, ds, wheres);

					// 新增到危险品及特种货物分类绑定品名表
					Integer dsId = ds.getDsId();
					mes1 = this.insertAddMultiSpecialGood(xls, userAccount, date, ver, dsId);
					// 新增到危险品及特种货物分类绑定处理代码
					mes2 = this.insertAddMultiDangerDeal(xls, userAccount, date, ver, dsId);
					/*
					 * if(StringUtils.isNotEmpty(mes3)) { mes2 += mes3; }
					 */
				}
			} else {
				// 替换导入

				DangerSpecial ds = dangerSpecialDao.find(wheres);
				if (null == ds) {// 主表不存在数据,导入主表,再导入从表

					// 主表新增
					Integer dsId = this.insertXls(xls, userAccount, isCustFlag, date, ver);
					// 先删除从表,新增到危险品及特种货物分类绑定品名表
					List<Where> tmpwhere = new ArrayList<Where>();
					tmpwhere.add(new Where("DS_ID", dsId));
					specialGoodDao.delete(tmpwhere);
					// 从表新增,批量新增multiInsert
					mes1 = this.insertMultiSpecialGood(xls, userAccount, date, ver, dsId);
					// 先删除从表,新增到危险品及特种货物分类绑定处理代码
					tmpwhere = new ArrayList<Where>();
					tmpwhere.add(new Where("DS_ID", dsId));
					dangerSpecialDealDao.delete(tmpwhere);
					// 从表新增
					mes2 = this.insertMultiDangerDeal(xls, userAccount, date, ver, dsId);

				} else {// 主表存在相同数据,主表更新数据,先删除从表数据,再导入从表

					// 更新主表,覆盖导入
					this.updateXls(xls, userAccount, isCustFlag, date, ver, ds, wheres);
					// 删除从表
					Integer dsId = ds.getDsId();
					List<Where> tmpwhere = new ArrayList<Where>();
					tmpwhere.add(new Where("DS_ID", dsId));
					dangerSpecialDealDao.delete(tmpwhere);
					specialGoodDao.delete(tmpwhere);
					// 新增到危险品及特种货物分类绑定品名表
					mes1 = this.insertMultiSpecialGood(xls, userAccount, date, ver, dsId);
					// 新增到危险品及特种货物分类绑定处理代码
					mes2 = this.insertMultiDangerDeal(xls, userAccount, date, ver, dsId);

				}
			}

			if (StringUtils.isNotEmpty(mes1) || StringUtils.isNotEmpty(mes2)) {
				String res = new String();
				res = mes1 + "///" + mes2;
				// throw new Exception(res);//TODO
				String[] s = new String[2];
				s[0] = mes1;
				s[1] = mes2;
				return s;
			}

			return null;
		} catch (Exception e) {
			e.printStackTrace();
			throw new Exception(e.getMessage());// TODO
		}
	}

版权声明:本文为qq_24075991原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
THE END
< <上一篇
下一篇>>