首页 > 技术文章 > angluarjs+springmvc实现excel上传并解析,对个别字段进行非空校验,txt生成,txt生成的条件为某列必须为某值且只提供固定的几列发送到ftp

songyunxinQQ529616136 2017-03-30 14:50 原文

业务场景:

angluarjs+springmvc实现excel上传并解析,对个别字段进行非空校验,txt生成,txt生成的条件为某列必须为某值且只提供固定的几列发送到ftp

 

html:

<div ng-controler="custemerListMainCtroller">
<div class="col-md-12">
<label for="file" class="btn btn-primary">选择文件</label>
<input type="file" id="file" style="display: none" file-upload multiple/><br/>
<div ng-show="files.length > 0">
<table class="table table-hover table-bordered table-striped">
<thead>
<tr>
<th>序号</th>
<th>文件名</th>
<th>文件大小</th>
<th>操作</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="file in files">
<td>{{$index+1}}</td>
<td>{{file.name}}</td>
<td>{{file.size/1024/1024|number:2 }} MB</td>
<td><button class="btn btn-danger btn-xs" ng-click="removeFile(file)">删除</button></td>
</tr>
</tbody>
</table>
<button ng-click="uploadShipTo(files)">upload Ship To</button>
</div>
<br/><br/><br/>

<div ng-hide="result">
<div ng-hide="visibleMsg">
<p><span style="color:red;" >{{mes}}</span></p>
</div>

<div ng-hide="visible">
<table class="table table-hover table-bordered table-striped">
<thead>
<tr>
<th colspan="4" style="color:red;" >these data must not be null,please fix them and then upload again</th>
</tr>
</thead>
<thead>
<tr>
<th>row</th>
<th>cel</th>
<th>titleName</th>
<th>error</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="map in data.resultData">
<td>{{map.row}}</td>
<td>{{map.cel}}</td>
<td>{{map.title}}</td>
<td>{{map.reson}}</td>
</tr>
</tbody>
</table>
</div>
</div>


</div>

 

service.js

/**
* NkBuyMainService
*/
myApp.factory('custemerListMainService', [ '$resource', '$http', function($resource, $http) {
return new custemerListMainService($resource, $http);
}]);

function custemerListMainService(resource, http) {
// 使用resource进行访问
var actions = {
'get' : {
method : 'GET',
},
'query' : {
method : 'POST',
isArray : true
},
'save' : {
method : 'POST',
isArray : true,
},
'update' : {
method : 'PUT',
isArray : true,
},
'remove' : {
method : 'DELETE',
isArray : true
}
};

/**
* import ship to
*/

this.uploadShipTo=function(scope,files){
console.log("#############uploadShipTo.start######service#################");
http({
method : 'POST',
url : "custemerList/uploadCustListShipTo",
headers : {
'Content-Type' : undefined
},
data : {
flag : "0",
files : scope.files
},
transformRequest : function(data) {
var formData = new FormData();
formData.append("flag",angular.toJson(data.flag));
for (var i = 0; i < data.files.length; i++) {
formData.append("myfiles",data.files[i]);
}
return formData;
}
}).success(function(data, status,headers, config) {
console.log("success.status"+status+"..headers:"+headers+"..data:"+data.resultCode);
var resultCode=data.resultCode;

//返回500的情况,非catch捕获到的500异常,说明excel数据校验有空的情况
if(resultCode==="501"){
scope.visible=false;
scope.data=data;
}else{//200 500

scope.visibleMsg=false;
scope.visible=true;
}
scope.result=false;
scope.mes=data.resultMsg;
// flg=data.resultData.flag;
// if(flg=="1"){
// //错误数据显示
// scope.visible=false;
// scope.result=false;
// scope.mes="Excel content is wrong, please upload again after modification";
// }
// scope.data=data;
}).error(function(data, status,headers, config) {
console.log("failed.status..."+status+"....");
//所有榀预知异常在success中捕获,不在此处再次进行捕获
if(status===404){
console.log("1");
scope.visibleMsg=false;
scope.visible=true;
scope.mes="404 File upload failed, please contact your administrator";
}else {
console.log("2");
}
scope.result=false;
})
console.log("#############uploadShipTo.end######service#################");
};



this.uploadCustList=function(scope){
console.log("#############uploadCustList.start######service#################");
var FunctionResource = resource('custemerList/uploadCustList', {},actions);
FunctionResource.get(function(data) {
scope.statuses = data.resultData;
console.log("..........nk_buy_service.js......exportNkBuy.导出结果为...data.resultMsg"+data.resultMsg);

}, function(error) {
alert(error)
});

console.log("#############uploadCustList.end######service#################");
};
};

 

controller.java

package cn.com.nike.controller;
import java.io.File;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;

import cn.com.nike.service.CustemerListService;
import cn.com.nike.util.UtilDateTime;
import cn.com.nike.util.UtilFile;
import cn.com.nike.util.Constants.ConstantsData;
import cn.com.nike.util.Constants.ConstantsResult;
import cn.com.nike.util.common.ResultModel;
/**
* @author soya.song
* 2017.3.16
*/
@Controller
@RequestMapping("/custemerList")
@SuppressWarnings("unused")
public class CustemerListController implements Serializable{
private static final long serialVersionUID = 2732216546553695880L;
private static final Logger log = LoggerFactory.getLogger(CustemerListController.class);
@Resource
private CustemerListService custemerListService;


/**
* custList的excel文件导入后
* 1)保存数据库
* 2)转为txt文件格式
* 3)将txt文件传到sftp
* 说明:该方法为多文件上传,在该业务中,实际只允许传入一个文件
*
* 注意:本方法用来读取excel
* Read excel fail,contact the administrator,please!java.lang.IllegalStateException: The hyperlink for cell X108 references relation rId40, but that didn't exist
* 出现这个错误是因为excel中存在了无效超链接。
* cell X108 是指出了这个无效超链接所在的行与列,X列108行
* 测试时,发现客户提供的文件数据有问题,但这个错误数据并非客户想要我们读取的这个sheet,客户提供一个完整的excel,其中只有CLC是我们该业务需要读取的,但错误数据是Golf中存在的。
* 上线后,需要提醒客户先将该Golf的X行108列无效超链接问题解决再测试
* @param id
* @return
* @throws Exception
*/
@RequestMapping(value = "/uploadCustListShipTo",method = RequestMethod.POST)
@ResponseBody
public ResultModel uploadCustListShipTo(@RequestParam MultipartFile[] myfiles, HttpServletRequest request) throws Exception {
ResultModel resultModel=new ResultModel();
Map<String,Object> resultMap=new HashMap<String,Object>();
//FileMain file=new FileMain();
log.info(this.getClass().getName()+".uploadCustList.start");
String originalFilename="";//上传的文件的文件名
String path="";
//校验上传文件上否为空
if(null==myfiles || myfiles.length<=0){
resultModel.setResultMsg(ConstantsResult.SERVICE_ERROR_CODE);//500
resultModel.setResultMsg(ConstantsResult.FILE_NULL_ERROR);//upload file is null
return resultModel;
}

//List<FileMain> resultList=new ArrayList<FileMain>();
int i=1;
for (MultipartFile myfile : myfiles) {
if (!myfile.isEmpty()) {
//获得文件后缀名
String suffix=UtilFile.getSuffix(myfile);

//检查文件格式是否正确.lsx(2003) .xlsx(2007)
if(!UtilFile.checkSuffix(suffix)){
resultModel.setResultCode(ConstantsResult.SERVICE_SUCCESS_CODE);//200
resultModel.setResultMsg(ConstantsResult.CHECK_EXCEL_NOT_EXIST_MSG);//the file must be excel
return resultModel;
};

//获得文件源名
originalFilename=UtilFile.getOriginalFilename(myfile);

//服务器生成一个文件路径,将客户端MultipartFile复制到服务器转换为File类型
path=request.getSession().getServletContext().getRealPath("/file/upload/");//生成一个目录
log.info(this.getClass().getName()+".uploadCustList.txt生成路径。。。。。"+path);
System.out.print("uploadCustList.txt生成路径。。。。。"+path);
//生成txt文件名
String txtName=ConstantsData.CONS_TXT_PREFIX+UtilDateTime.nowDateToString()+ConstantsData.CONS_TXT_SUFFIX;//customer_YYYYMMDDHHMM.txt (时间为24小时)
String txtFullName=path+txtName;//..../file/upload/customer_YYYYMMDDHHMM.txt txt文件保存的全路径=路径+文件名
File f= UtilFile.getFile(path,suffix);//文件路径,上传的excel文件的后缀

//如果path路径不存在,创建一个文件夹
if(!f.exists()){
f.mkdirs();
}
try {
myfile.transferTo(f);//没有这句话,生成的文件就是一个文件夹。有了以后,就会在path路径下,生成一个文件
//1.将文件信息保存到数据库,同时生成txt文件
Map<String,Object> map=custemerListService.saveExcelAndToTxt(f,txtFullName);

//返回不为200,表示未抛异常的可预知错误,获取信息后,返回
if(!ConstantsResult.SERVICE_SUCCESS_CODE.equals(map.get("resultCode"))){
if(ConstantsResult.DATA_ERROR_CODE.equals(map.get("resultCode"))){//501数据校验不通过
resultModel.setResultData(map.get("errList"));
}
resultModel.setResultCode((String)map.get("resultCode"));//500 501都返回错误code
resultModel.setResultMsg((String)map.get("resultMsg"));//500 501都返回错误信息
log.info(this.getClass().getName()+".uploadCustList.....501异常..读写输出参数:resultModel="+resultModel+"\n"+"文件路径:path="+path);
return resultModel;
}

//否则说明返回的是200,将txt发送到sftp

} catch (Exception e) {
log.error(this.getClass().getName()+".uploadCustList.end.上传excel文件controller报错",e);
resultModel.setResultCode(ConstantsResult.SERVICE_ERROR_CODE);//500
resultModel.setResultMsg(e.getMessage().substring(3));//返回异常信息
log.info(this.getClass().getName()+".uploadCustList.end.上传excel文件controller报错..e.getMessage()",e.getMessage());
return resultModel;
// throw new Exception(ConstantsResult.SERVICE_ERROR_CODE+resultModel+e.getMessage());//excel文件导入失败
}
/**
* 如果导入成功一个文件,记录一次 实际该业务中只允许上传一个文件,固该处可暂不处理
* file.setName(originalFilename);
file.setNum(i);
resultList.add(file);//对象装入list
i++;
*/

}
}
resultModel.setResultCode(ConstantsResult.SERVICE_SUCCESS_CODE);//200
resultModel.setResultMsg(ConstantsResult.SERVICE_SUCCESS_MSG);//Congratulations, you succeeded
log.info(this.getClass().getName()+".uploadCustList.......读写输出参数:resultModel="+resultModel+"\n"+"文件路径:path="+path);
return resultModel;
}


public void test() {
System.out.print("*****************test controller");
custemerListService.testService();
}

}

 

service.java

package cn.com.nike.service.impl;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import cn.com.nike.model.CustomerListMain;
import cn.com.nike.model.CustomerListShipToMain;
import cn.com.nike.service.CustemerListService;
import cn.com.nike.util.UtilCheckEmpty;
import cn.com.nike.util.UtilDateTime;
import cn.com.nike.util.UtilEncapsulated;
import cn.com.nike.util.UtilExcelToTxt;
import cn.com.nike.util.UtilString;
import cn.com.nike.util.Constants.ConstantsData;
import cn.com.nike.util.Constants.ConstantsResult;
/**
* @author soya.song
* 2017.3.16
*
*/
@Service("custemerListService")
@SuppressWarnings("unused")
public class CustemerListServiceImpl implements CustemerListService{//class start
private static final Logger log = LoggerFactory.getLogger(CustemerListServiceImpl.class);




/**
* 读取excel文件的sheet为CLC的内容保存到数据库
* @throws Exception
* @throws SecurityException
* @throws NoSuchFieldException
* @throws IllegalAccessException
* @throws IllegalArgumentException
*/
@SuppressWarnings({ "rawtypes", "unchecked" })
@Override
public Map<String, Object> saveExcelAndToTxt(File file,String path) throws Exception{////saveExcel start
/*
* 定义变量区域
* */
FileOutputStream out = null;
List oList=new ArrayList();
StringBuffer sBuffer =null;
String flag="0";//excel数据无异常
String flagCels="0";//该行数据为空(所有列都无数据)
int rowTotalNumFirst=0;//初定总行数(有可能行中无数据,总行数会将空行过滤)--产生空行空列的原因是因为输入的数据被删除,但是单元格行或列未被删除引起的
int realTotalRow=0;//真实总行数
int celTotalNumFirst=0;//初定总列数(有可能标题无值,但是被计算入总数,这种情况需要过滤空列)--产生空行空列的原因是因为输入的数据被删除,但是单元格行或列未被删除引起的
int celRealTotalNum=0;//真实的列总数
XSSFRow xssfRow =null;//一个行对象
int oNum=0;//对象总计次数
XSSFCell xssfcell =null;//一个列对象
int sheetNums=0;//sheet总数
Map<Integer,String> titlMap=new HashMap<Integer,String>();//标题map
Map<String,Object> resultMap=new HashMap<String,Object>();//方法结束返回结果对象
List outList=new ArrayList();
XSSFWorkbook xssfWorkbook=null;////获取excel文件
XSSFSheet xssfSheet=null;//sheet
FileInputStream fileStream;
String flgSheet="0";//sheet是否存在 0不存在 1存在
int sheetIndex=0;
List errorList=new ArrayList();
List rowErrorList=null;
List txtTile=ConstantsData.getTxt();
List checkTitle=ConstantsData.getTitle();
String sendTxtFlag="0";//是否发送txt到ftp 0发送 1 不发送 另外: 如果txtFlag="1";时,表示txt中至少有1行数据,且checkExcelFilai=“0”时,才发送txt到ftp
String checkExcelFilai="1";//excel字段校验结果:1 :初始化无异常 0:特殊字段校验不通过 此时txt不再读取,对象不再记录,也不入库,只循环检查错误信息并记录后返回客户端显示
int bufferCount=0;//txt读取到的ownergrp="belle"的行数
/*
* 读取excel文件
*/
try {//try start
log.info(this.getClass().getName()+".saveExcelAndToTxt.creatBook .....start"+UtilDateTime.nowDateString());
xssfWorkbook = new XSSFWorkbook(new BufferedInputStream(new FileInputStream(file)));
log.info(this.getClass().getName()+".saveExcelAndToTxt.creatBook .....end"+UtilDateTime.nowDateString());
//sheetNums=xssfWorkbook.getNumberOfSheets();
//循环所有sheet,根据下标注查找指定sheet的名字,匹配要查找的指定sheet(“CLC”)

for (int numSheet = 0; numSheet < xssfWorkbook.getNumberOfSheets(); numSheet++) {//for sheet start
String sheetNam=xssfWorkbook.getSheetName(numSheet);
log.info(this.getClass().getName()+".saveExcelAndToTxt.得到的sheetNam"+sheetNam+"..要读取的sheet为:"+ConstantsData.SHEET_SHIP_TO.trim()+"..拿到的sheet为:"+UtilString.getNewString(sheetNam));
//循环sheet不存在,不做任何操作,继续下一次循环
if(!ConstantsData.SHEET_SHIP_TO.trim().equalsIgnoreCase(UtilString.getNewString(sheetNam) )){
continue;
}else{//如果存在,终止对其他sheet的循环
flgSheet="1";//sheet存在
xssfSheet=xssfWorkbook.getSheetAt(numSheet);//获得sheet
log.info(this.getClass().getName()+".saveExcelAndToTxt..读取到sheet:"+sheetNam+"第"+numSheet+"个");
break;
}

}//for sheet end


//根据标志判断sheet的循环中是否查找到所需sheet,如果为0说明查未找到,指定sheet不存在,否则己找到
if("0".equals(flgSheet)){//如果sheet不存在
resultMap.put("resultCode", ConstantsResult.SERVICE_ERROR_CODE);//500
resultMap.put("resultMsg", ConstantsResult.CHECK_SHEET_NOT_EXIST_MSG);//CLC不存在
return resultMap;
}

//获取要验证的title

out=new FileOutputStream(path);//该流将excel内容写入txt中
//获得总行数
rowTotalNumFirst= xssfSheet.getLastRowNum()+1;
for (int rowNum = 0; rowNum < rowTotalNumFirst; rowNum++) {//for row start
String oFlag="1";//行对象保存标志 0不保存 1保存
String txtFlag="1";//txt导出标志 0 不导出 1导出
StringBuffer rowBuffer=new StringBuffer();
String rowBufferFlag="1";//该行是否记录到txt中 0 不记录 1记录
realTotalRow++;//真实总行数
log.info(this.getClass().getName()+".saveExcelAndToTxt."+rowNum+"行..............start");
//CustomerListShipToMain customerListShipToMain=new CustomerListShipToMain();
Map map=new HashMap();
sBuffer=new StringBuffer();//行内有效,用来拼接所有列
//第一行:循环标题
if(rowNum==0){//rowNum==0 start
xssfRow = xssfSheet.getRow(0);//第一行的行对象
celTotalNumFirst= xssfRow.getLastCellNum();//初定总列数
//循环遍历第一行的所有列
for(int cel=0;cel<celTotalNumFirst;cel++){//for cel start
xssfcell = xssfRow.getCell((short)cel);//获得列对象
log.info(this.getClass().getName()+".saveExcelAndToTxt....获取单元格数据......xssfcell="+xssfcell);
String strCel=xssfcell != null ? xssfcell.toString().trim():"";
//规定excel中所有的列是从第1列开始,并且所有的列中间不能有空列。如果出现空列,会造成后续数据与标题对应错误问题
if(strCel==null || "".equals(strCel)){
break;
}
celRealTotalNum++;
//将列对象存入titlMap,key为列的index value为列对象
String newTitle=UtilString.getNewString(strCel);
titlMap.put(cel,newTitle);
//将标题写入txt
if(ConstantsData.getTxt().contains(newTitle)){
sBuffer=UtilExcelToTxt.appendBuffer(sBuffer, xssfcell+"");
}
}//for cel end
log.info(this.getClass().getName()+".saveExcelAndToTxt....标题为:titlMap="+titlMap);
//读完所有标题以后,txt中换行,程序继续excel的下一行循环
sBuffer.append(UtilExcelToTxt.EXCEL_LINE);
UtilExcelToTxt.bufferToTxt(out,sBuffer);
continue;//继续下一行的所有列的循环

}//rowNum==0 end

//第二行起循环读取数据
rowErrorList=new ArrayList();
int errorCelNum=0;
for(int cel=0;cel<celRealTotalNum;cel++){//for cel start
log.info(this.getClass().getName()+".saveExcelAndToTxt."+rowNum+"行"+cel+"列。。。。。。。。。。。start");
xssfRow = xssfSheet.getRow(rowNum);//第N行的行对象(rowNum>0)
xssfcell = xssfRow.getCell((short)cel);//获得列对象
String titleStr=titlMap.get(cel);//根据列序号得到标题
log.info(this.getClass().getName()+".saveExcelAndToTxt.the cell detail is \n 行:"+rowNum+"列:"+cel+"列名:"+titleStr+"..列值:"+xssfcell+"");
Object oCel="";
if(xssfcell!=null && !"".equals(xssfcell+"")){ //xssfcell!=null start
switch (xssfcell.getCellType()){
case XSSFCell.CELL_TYPE_NUMERIC: // 数字 问题:此处日期格式也被处理为数字类型
String str=xssfcell+"";
String last2=str.substring(str.length()-2);
log.info(this.getClass().getName()+".saveExcelAndToTxt.."+rowNum+"行"+cel+"列"+str+"的数字类型最后两位:"+last2);
if(".0".equals(last2)){
oCel=str.substring(0,str.length()-2);
}else{
oCel=xssfcell+"";
}
break;
case XSSFCell.CELL_TYPE_STRING: // 字符串
oCel=xssfcell.getStringCellValue()+"";
break;
case XSSFCell.CELL_TYPE_BOOLEAN: // Boolean
oCel=xssfcell.getBooleanCellValue()+"";
break;
case XSSFCell.CELL_TYPE_FORMULA: // 公式
oCel=xssfcell.getCellFormula()+"";
break;
case XSSFCell.CELL_TYPE_BLANK: // 空值
oCel="";
break;
case XSSFCell.CELL_TYPE_ERROR: // 故障
oCel=xssfcell+"";
break;
default:
oCel=xssfcell+"";
break;
}
} //xssfcell!=null end
String strCel=oCel+"".trim();

log.info(this.getClass().getName()+".saveExcelAndToTxt....获取单元格数据......xssfcell="+xssfcell);

/**
*1.如果该列为空,判断该列的标题是否在要校验的标题中,
* 01)如果在,则记录错误信息,
* 02)不在,则保存该列的值到对象与txt中
*
* 2.如果该列不为空,,则保存该列的值到对象与txt中
*/
if(UtilCheckEmpty.isBlank(strCel)){//UtilCheckEmpty.isBlank(strCel) start 该列为空,记录错误信息
//如果cel值为空,保存对象,但不生成txt
errorCelNum++;//有空值就++ 为了控制列全为空的情况,该行对象不添加到oll
if(checkTitle.contains(titleStr)){//如果该空数据所在的列标题存在于要检验的集合中,需要提示用户校验失败,在此记录为空列的行,列,标题名等错误信息
//如果以上几列值为空,无需进行以下操作,直接保存错误信息,将将flag转为false,继续循环
//只在该列的循环中有效
Map<String,Object> celError=new HashMap<String,Object>();
celError.put("row", rowNum+1);
celError.put("cel", cel+1);
celError.put("title", titleStr);
celError.put("reson", ConstantsResult.CEL_NULL_ERROR);//该列数据不得为空
rowErrorList.add(celError);
//如果有空值,对象不保存
oFlag="0";//该行对象是否保存?0:不保存 1:保存
checkExcelFilai="0";//excel字段校不通过,不再记录对象,此时exce信息不入库,只记录该行对象的错误信息,txt不发送
sendTxtFlag="1";//不发送txt
log.info(this.getClass().getName()+".saveExcelAndToTxt..对象有空值,不保存对象:"+celError);
if(titleStr.equals("ownergrp")){//如果标题为ownergrp 此时又是空值,则标识该行rowBuffer="
rowBufferFlag="0";//该行不追加oBuffer中
}
continue;//如果检查出特殊字段空值情况,下列代码不再继续,继续下一个cel的检查
}
//如果没有continue,说明excel校验通过
if("1".equals(checkExcelFilai)){
//则该列记录到临时对象中
// UtilEncapsulated.setObject(titleStr,strCel,customerListShipToMain);
map.put(titleStr, strCel);
//如果空值,excel检查没有不通过情况,且允许追加情况,本行临时buffer追加 后续一旦出现rowBufferFlag=”0“在行结束后,就不会将本rowBuffer追加
if(txtTile.contains(titleStr) && "1".equals(rowBufferFlag)){
rowBuffer=UtilExcelToTxt.appendBuffer(rowBuffer, strCel);
}


}else{
continue;//如果checkExcelFilai="0",又没有在上面被continue到,说明该列未检查出问题,但是前面有检查出问题,此时直接continue,执行下一列的检查,不再对行对象与rowBuffer进行保存
}

}//UtilCheckEmpty.isBlank(strCel) end 该列为空,记录错误信息
/*数据是否为空,都要在txt中
* 1 如果数据为bellle,标记为记录,该行的有关列值记录并输出
* (不能在原来的buffer中追加,需要new一个新的rowBuffer,如果Ownergrp=‘BELLE’,标志记录1则将该行的rowBuffer追加到buffer中,
* 如果没有,则记录0,rowBuffer不会追加到rowBuffer)==对标志要在循环完一行以后再判断是否追加
* 2 在行中对每一列的循环中,要选择Sold-To Ship-To PSST Name Channel Distributionchannel Street(Fullname)列追加到rowBuffer中
* */
//如果该列不为空,无需非空检查,如果前面检查出现过特殊字段为空情况,则不再对txt的ownergrp=“belle”进行筛选
if("0".equals(checkExcelFilai)){
rowBufferFlag="0";//该行txt的Buffer不追加,checkExcelFilai=”0“表示也不对行对象进行设置
continue;
}
//如果前面未出现过excel检查出问题情况,cel又不为空,此时对txt的ownergrp=“belle”进行筛选
if(!"0".equals(checkExcelFilai)){//如果没有校验不通过情况
//将该列赋值到行对象customerListMain的该列中
//UtilEncapsulated.setObject(titleStr,strCel,customerListShipToMain);//临时对象,在该行结束后根据oFlag来确定是否添加到oList中 oFlag="1"时才添加
map.put(titleStr, strCel);
//如果列名在导出的范围内,则将列存入该行临时buffer
if(txtTile.contains(titleStr)){
rowBuffer=UtilExcelToTxt.appendBuffer(rowBuffer, strCel);
}
//循环到ownergrp列的时候,检查该列的值是否是belle,如果是,则允许该临时rowBuffer追加到buffer中,否则不允许
if(titleStr.equals("ownergrp") && !strCel.equalsIgnoreCase(ConstantsData.TXT_OWNERGRP)){
rowBufferFlag="0";//不允许该临时rowBuffer追加到buffer中,否则不允许
}
}else{
rowBufferFlag="0";//不允许该临时rowBuffer追加到buffer中,否则不允许
continue;//如果excel检查不通过,直接下一次循环
}

log.info(this.getClass().getName()+".saveExcelAndToTxt."+rowNum+"行"+cel+"列。。。。。。。。。。。over");
}//for cel end

log.info(this.getClass().getName()+".saveExcelAndToTxt."+rowNum+"行..............over");

//
/**
* 数据读取完一行后
* 1.txt文件要立马换行
* 2.
*/
//1.rowBufferFlag="1"该行记录txt,=“0”该行不记录txt
if(!"0".equals(rowBufferFlag)){
bufferCount++;//表示txt中数据行数(标题行除外)
sBuffer.append(rowBuffer);
sBuffer.append(UtilExcelToTxt.EXCEL_LINE);
UtilExcelToTxt.bufferToTxt(out,sBuffer);
}

//2.如果没有错误记录,将对象保存到List中则继续下一行的循环;
if(errorCelNum==0){//说明没有空值
// oList.add(customerListShipToMain);
oList.add(map);
continue;
}else if(errorCelNum<celRealTotalNum){//如果有空值,但不代表就是我们要筛选的那几列
if(!"0".equals(oFlag)){//不保存对象
oList.add(map);
}
errorList.addAll(rowErrorList);
}else if(errorCelNum==celRealTotalNum){//如果空列数=总列数,说明该行为空,上面的错误记录失败,不再记录,因excel中不未结束文档中途不可出现全部为空的现象,所以遇到全行为空,中止所有行的循环
break;
}
}//for row end


} catch (Exception e) {//try end,catch start
log.error("#################"+this.getClass().getName()+".saveExcelAndToTxt.exception.文件读取不可预知异常......可能是excel数据中引入了无效超链接,可以尝试将shee:Golf的列:E-packing list address列中无效超链接清除以后尝试"+e);
throw new Exception(ConstantsResult.SERVICE_ERROR_CODE+"\n\t"+ConstantsResult.FILE_EXCELTODB_ERROR+e);//文件读取异常
}//catch end
finally{
try {
if(out!=null){
out.close();
}
} catch (Exception e) {
log.error("#################"+this.getClass().getName()+".saveExcelAndToTxt.exception.读取成功,关闭流异常........."+e);
throw new Exception(ConstantsResult.SERVICE_ERROR_CODE+"\n\t"+ConstantsResult.FILE_EXCELTODB_ERROR+e);//文件读取异常
}
}

log.info(this.getClass().getName()+".saveExcelAndToTxt....exce读取完毕,对象总数:"+oList.size()+"txt导出行数:"+bufferCount);
//判断errorList.size如果>0则返回501,标志数据校验有问题,否则返回200
if(errorList.size()>0){
resultMap.put("resultCode", ConstantsResult.DATA_ERROR_CODE);//501
resultMap.put("resultCode", ConstantsResult.DATA_ERROR_CODE);//
resultMap.put("errList", errorList);
}else{
resultMap.put("resultCode", ConstantsResult.SERVICE_SUCCESS_CODE);//200
//如果以下条件均满足,才可以发送txt到ftp(标志为允许发送,excel校验通过,)
if("0".equals(sendTxtFlag) && "1".equals(checkExcelFilai) && bufferCount>0){
//发送txt到ftp
try{
log.info(this.getClass().getName()+".saveExcelAndToTxt....发送txt到ftp....start");
}catch(Exception e){

}

}
if(oList.size()>0){//如果对象>0存入db
//保存对象到数据库
try{
log.info(this.getClass().getName()+".saveExcelAndToTxt....保存excel到DB....start");
}catch(Exception e){

}
}
}

return resultMap;
}








// /**
// * 读取excel文件的sheet为CLC的内容保存到数据库
// * @throws Exception
// * @throws SecurityException
// * @throws NoSuchFieldException
// * @throws IllegalAccessException
// * @throws IllegalArgumentException
// */
// @SuppressWarnings({ "rawtypes", "unchecked" })
// @Override
// public Map<String, Object> saveExcelAndToTxt2(File file,String path) throws Exception{////saveExcel start
// /*
// * 定义变量区域
// * */
// FileOutputStream out = null;
// List<CustomerListMain> oList=new ArrayList<CustomerListMain>();
// StringBuffer sBuffer =null;
// String flag="0";//excel数据无异常
// String flagCels="0";//该行数据为空(所有列都无数据)
// int rowTotalNumFirst=0;//初定总行数(有可能行中无数据,总行数会将空行过滤)--产生空行空列的原因是因为输入的数据被删除,但是单元格行或列未被删除引起的
// int realTotalRow=0;//真实总行数
// int celTotalNumFirst=0;//初定总列数(有可能标题无值,但是被计算入总数,这种情况需要过滤空列)--产生空行空列的原因是因为输入的数据被删除,但是单元格行或列未被删除引起的
// int celRealTotalNum=0;//真实的列总数
// XSSFRow xssfRow =null;//一个行对象
// int oNum=0;//对象总计次数
// XSSFCell xssfcell =null;//一个列对象
// int sheetNums=0;//sheet总数
// Map<Integer,String> titlMap=new HashMap<Integer,String>();//标题map
// Map<String,Object> resultMap=new HashMap<String,Object>();//方法结束返回结果对象
// List outList=new ArrayList();
// XSSFWorkbook xssfWorkbook=null;////获取excel文件
// XSSFSheet xssfSheet=null;//sheet
// FileInputStream fileStream;
// String flgSheet="0";//sheet是否存在 0不存在 1存在
// int sheetIndex=0;
// List errorList=new ArrayList();
// List rowErrorList=null;
//
// /*
// * 读取excel文件
// */
// try {//try start
// log.info(this.getClass().getName()+".saveExcelAndToTxt.creatBook .....start"+UtilDateTime.nowDateString());
// xssfWorkbook = new XSSFWorkbook(new BufferedInputStream(new FileInputStream(file)));
// log.info(this.getClass().getName()+".saveExcelAndToTxt.creatBook .....end"+UtilDateTime.nowDateString());
// sheetNums=xssfWorkbook.getNumberOfSheets();
// //循环所有sheet,根据下标注查找指定sheet的名字,匹配要查找的指定sheet(“CLC”)
// for (int numSheet = 0; numSheet < sheetNums; numSheet++) {//for sheet start
// String sheetNam=xssfWorkbook.getSheetName(numSheet);
// //循环sheet不存在,不做任何操作,继续下一次循环
// if(!UtilString.getNewString(ConstantsData.SHEET_SHIP_TO.trim()).equalsIgnoreCase(UtilString.getNewString(sheetNam) )){
// continue;
// }else{//如果存在,终止对其他sheet的循环
// flgSheet="1";//sheet存在
// xssfSheet=xssfWorkbook.getSheetAt(numSheet);//获得sheet
// break;
// }
//
// }//for sheet end
//
//
// //根据标志判断sheet的循环中是否查找到所需sheet,如果为0说明查未找到,指定sheet不存在,否则己找到
// if("0".equals(flgSheet)){//如果sheet不存在
// resultMap.put("resultCode", ConstantsResult.SERVICE_ERROR_CODE);//500
// resultMap.put("resultMsg", ConstantsResult.CHECK_SHEET_NOT_EXIST_MSG);//CLC不存在
// return resultMap;
// }
//
// //获取要验证的title
// List checkTitle=ConstantsData.getTitle();
// out=new FileOutputStream(path);//该流将excel内容写入txt中
// //获得总行数
// rowTotalNumFirst= xssfSheet.getLastRowNum()+1;
// for (int rowNum = 0; rowNum < rowTotalNumFirst; rowNum++) {//for row start
// String oFlag="1";//行对象保存标志 0不保存 1保存
// String txtFlag="1";//txt导出标志 0 不导出 1导出
// realTotalRow++;//真实总行数
// log.info(this.getClass().getName()+".saveExcelAndToTxt."+rowNum+"行..............start");
// CustomerListMain customerListMain=new CustomerListMain();//当前行有效
// sBuffer=new StringBuffer();//行内有效,用来拼接所有列
// //第一行:循环标题
// if(rowNum==0){//rowNum==0 start
// xssfRow = xssfSheet.getRow(0);//第一行的行对象
// celTotalNumFirst= xssfRow.getLastCellNum();//初定总列数
// //循环遍历第一行的所有列
// for(int cel=0;cel<celTotalNumFirst;cel++){//for cel start
// xssfcell = xssfRow.getCell((short)cel);//获得列对象
// log.info(this.getClass().getName()+".saveExcelAndToTxt....获取单元格数据......xssfcell="+xssfcell);
// String strCel=xssfcell != null ? xssfcell.toString().trim():"";
// //规定excel中所有的列是从第1列开始,并且所有的列中间不能有空列。如果出现空列,会造成后续数据与标题对应错误问题
// if(strCel==null || "".equals(strCel)){
// break;
// }
// celRealTotalNum++;
// //将列对象存入titlMap,key为列的index value为列对象
// titlMap.put(cel, strCel);
// //将标题写入txt
// sBuffer=UtilExcelToTxt.appendBuffer(sBuffer, strCel);
//
// }//for cel end
//
// //读完所有标题以后,txt中换行,程序继续excel的下一行循环
// sBuffer.append(UtilExcelToTxt.EXCEL_LINE);
// UtilExcelToTxt.bufferToTxt(out,sBuffer);
// continue;//继续下一行的所有列的循环
//
// }//rowNum==0 end
//
// //第二行起循环读取数据
// rowErrorList=new ArrayList();
// int errorCelNum=0;
// for(int cel=0;cel<celRealTotalNum;cel++){//for cel start
// log.info(this.getClass().getName()+".saveExcelAndToTxt."+rowNum+"行"+cel+"列。。。。。。。。。。。start");
// xssfRow = xssfSheet.getRow(rowNum);//第N行的行对象(rowNum>0)
// xssfcell = xssfRow.getCell((short)cel);//获得列对象
// String titleStr=titlMap.get(cel);//根据列序号得到标题
// log.info(this.getClass().getName()+".saveExcelAndToTxt.the cell detail is \n 行:"+rowNum+"列:"+cel+"列名:"+titleStr+"..列值:"+xssfcell+"");
//
// Object oCel="";
// if(xssfcell!=null && !"".equals(xssfcell+"")){ //xssfcell!=null start
// switch (xssfcell.getCellType()){
// case XSSFCell.CELL_TYPE_NUMERIC: // 数字 问题:此处日期格式也被处理为数字类型
// String str=xssfcell+"";
// String last2=str.substring(str.length()-2);
// log.info(this.getClass().getName()+".saveExcelAndToTxt.."+rowNum+"行"+cel+"列"+str+"的数字类型最后两位:"+last2);
// if(".0".equals(last2)){
// oCel=str.substring(0,str.length()-2);
// }else{
// oCel=xssfcell+"";
// }
// break;
// case XSSFCell.CELL_TYPE_STRING: // 字符串
// oCel=xssfcell.getStringCellValue()+"";
// break;
// case XSSFCell.CELL_TYPE_BOOLEAN: // Boolean
// oCel=xssfcell.getBooleanCellValue()+"";
// break;
// case XSSFCell.CELL_TYPE_FORMULA: // 公式
// oCel=xssfcell.getCellFormula()+"";
// break;
// case XSSFCell.CELL_TYPE_BLANK: // 空值
// oCel="";
// break;
// case XSSFCell.CELL_TYPE_ERROR: // 故障
// oCel=xssfcell+"";
// break;
// default:
// oCel=xssfcell+"";
// break;
// }
// } //xssfcell!=null end
// String strCel=oCel+"".trim();
//
//
//
// log.info(this.getClass().getName()+".saveExcelAndToTxt....获取单元格数据......xssfcell="+xssfcell);
//
//
//
//
// /**
// *1.如果该列为空,判断该列的标题是否在要校验的标题中,
// * 01)如果在,则记录错误信息,
// * 02)不在,则保存该列的值到对象与txt中
// *
// * 2.如果该列不为空,,则保存该列的值到对象与txt中
// */
// if(UtilCheckEmpty.isBlank(strCel)){//UtilCheckEmpty.isBlank(strCel) start 该列为空,记录错误信息
// if(!UtilCheckEmpty.isBlank(titleStr)){//如果title不为空时再校验
// //如果cel值为空,保存对象,但不生成txt
// // UtilEncapsulated.setObject(titleStr,strCel,customerListMain);
// errorCelNum++;//有空值就++
// if(checkTitle.contains(titleStr)){//如果该空数据所在的列标题存在于要检验的集合中,需要提示用户校验失败,在此记录为空列的行,列,标题名等错误信息
// //如果以上几列值为空,无需进行以下操作,直接保存错误信息,将将flag转为false,继续循环
// //只在该列的循环中有效
// Map<String,Object> celError=new HashMap<String,Object>();
// celError.put("row", rowNum+1);
// celError.put("cel", cel+1);
// celError.put("title", titleStr);
// celError.put("reson", ConstantsResult.CEL_NULL_ERROR);//该列数据不得为空
// rowErrorList.add(celError);
// continue;
// }
//
//
//
// /*
// * 如果标题不为空,进行赋值
// * 除id以外,其余属性均为String类型(以下代码为flag=true的时候才能执行到的情况)
// */
// if(!"id".equals(titleStr)){
// //将该列赋值到行对象customerListMain的该列中
// // UtilEncapsulated.setObject(titleStr,strCel,customerListMain);
// sBuffer=UtilExcelToTxt.appendBuffer(sBuffer, strCel);
// }
//
//
//
// }
// }else{//UtilCheckEmpty.isBlank(strCel) end
//
// //如果值为空,保存对象
// UtilEncapsulated.setObject(titleStr,strCel,customerListMain);
//
// //如果该列不为空,将该列保存到对象,写入txt中
// sBuffer=UtilExcelToTxt.appendBuffer(sBuffer, strCel);
//
// }
//
// log.info(this.getClass().getName()+".saveExcelAndToTxt."+rowNum+"行"+cel+"列。。。。。。。。。。。over");
// }//for cel end
//
// //
// /**
// * 数据读取完一行后
// * 1.txt文件要立马换行
// * 2.
// */
// //1.txt文件要立马换行
// sBuffer.append(UtilExcelToTxt.EXCEL_LINE);
// log.info(this.getClass().getName()+".saveExcelAndToTxt.sBuffer....."+sBuffer);
// UtilExcelToTxt.bufferToTxt(out,sBuffer);
// //2.如果没有错误记录,则继续下一行的循环;
// if(errorCelNum==0){
// continue;
// }else if(errorCelNum<celRealTotalNum){//如果错误数量<总列数,说明该行不为空,数据不能为空校验出问题,提示用户补充数据后再上传(将列的错误信息添加到erroList)
// errorList.addAll(rowErrorList);
// }else if(errorCelNum==celRealTotalNum){//如果空列数=总列数,说明该行为空,上面的错误记录失败,不再记录,因excel中不未结束文档中途不可出现全部为空的现象,所以遇到全行为空,中止所有行的循环
// break;
// }
//
// log.info(this.getClass().getName()+".saveExcelAndToTxt."+rowNum+"行..............over");
// }//for row end
//
// } catch (Exception e) {//try end,catch start
// log.error("#################"+this.getClass().getName()+".saveExcelAndToTxt.exception.文件读取未定义异常......可能是excel数据中引入了无效超链接,可以尝试将shee:Golf的列:E-packing list address列中无效超链接清除以后尝试"+e);
// throw new Exception(ConstantsResult.SERVICE_ERROR_CODE+"\n\t"+ConstantsResult.FILE_EXCELTODB_ERROR+e);//文件读取异常
//// resultMap.put("resultCode", ConstantsResult.DATA_ERROR_CODE);//500
//// resultMap.put("resultMsg", e.getMessage());//
// }//catch end
// finally{
// try {
// if(out!=null){
//
// out.close();
// }
// } catch (Exception e) {
// log.error("#################"+this.getClass().getName()+".saveExcelAndToTxt.exception.读取成功,关闭流异常........."+e);
// throw new Exception(ConstantsResult.SERVICE_ERROR_CODE+"\n\t"+ConstantsResult.FILE_EXCELTODB_ERROR+e);//文件读取异常
// }
// }
//
// //判断errorList.size如果>0则返回501,标志数据校验有问题,否则返回200
// if(errorList.size()>0){
// resultMap.put("resultCode", ConstantsResult.DATA_ERROR_CODE);//501
// resultMap.put("resultCode", ConstantsResult.DATA_ERROR_CODE);//
// resultMap.put("errList", errorList);
// }else{
// resultMap.put("resultCode", ConstantsResult.SERVICE_SUCCESS_CODE);//200
// }
// log.info(this.getClass().getName()+".saveExcelAndToTxt....exce读取完毕,总行数据:"+realTotalRow+"对象总行数:"+oList.size()+"初定总行数:"+rowTotalNumFirst);
// return resultMap;
// }//saveExcel end
@Override
public void sendTxtToSFTP(String pathTxt) {
// TODO Auto-generated method stub

}

@Override
public void testService() {
// TODO Auto-generated method stub

}
}//class end

 

 

contansData.java

package cn.com.nike.util.Constants;

import java.util.ArrayList;
import java.util.List;

@SuppressWarnings("rawtypes")
public class ConstantsData {
public static final String CONS_SUFFIX_2003 = ".lsx";
public static final String CONS_SUFFIX_2007 = ".xlsx";
public static final String CONS_TXT_PREFIX = "customer_";
public static final String CONS_TXT_SUFFIX = ".txt";
public static final String SHEE_TCLC="CLC";//要读取的excel文件
public static final String SHEET_SHIP_TO="shipTo";//要读取的excel文件
public static final String TXT_OWNERGRP="belle";//txt中只导出

//exce要检查的非空字段
public static List getTitle(){
List<String> list=new ArrayList<String> ();
list.add("region");
list.add("soldto");
list.add("shipto");
list.add("ownergrp");
return list;
}
//txt只保留的字段
public static List getTxt(){
List<String> list=new ArrayList<String> ();
list.add("soldto");
list.add("shipto");
list.add("psst");
list.add("name");
list.add("channel");
list.add("distributionchannel");
list.add("streetfullname");
list.add("ownergrp");
return list;
}
}

 

UtilString.java

package cn.com.nike.util;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
* 对String进行操作
* @author soya.song
*2017.3.21
*/
public class UtilString {
private static final Logger log = LoggerFactory.getLogger(UtilString.class);
/**
* 去除空格,下划线,全部转小写
* 应用场景:将excel列名转换为对象属性名
* 对象属性名使命规则:列名去除空格,下划线,全部小写以后即为属性名,该处对象不采取驼峰命名规则,因动态取值,赋值,固需遵循该规则
* @param str
* @return
*/
public static String newString(String str){
return str.toLowerCase().replaceAll("\\s*", "").replaceAll("_", "");//全部小写,去除空格,去除下划线
}
/**
* 全部转小写
* @param str
* @return
*/
public static String allLowercase(String str){
return str.toLowerCase();
}
/**
* 去除空格
* @param str
* @return
*/
public static String RemoveBlankSpace(String str){
return str.replaceAll("\\s*", "");
}
/**
* 去除下划线
* @param str
* @return
*/
public static String RemoveUnderline(String str){
return str.replaceAll("_", "");
}
/**
* 去除斜杠
* @param str
* @return
*/
public static String RemoveSlash(String str){
return str.replaceAll("/", "");
}

/**
* 去除所有空格,所有特殊符号,首字母小写,这个方法把数字也去除了
* 应用场景:将excel列名改为java对象属性名
* 1 去除/ _ () 所有空格
* 2 全部转小写
* @param str
* @return
*/

public static String getNewString(String str){
log.info("UtilString.getNewString.转换前为。。。。。。。。。。"+str);
String newStr=allLowercase(str.trim().replaceAll("_", "").replaceAll("/", "").replaceAll("\\(|\\)", "").replaceAll("\\s*", ""));
log.info("UtilString.getNewString.转换后为。。。。。。。。。。"+newStr);
return newStr;
}
//首字母转小写
public static String toLowerCaseFirstOne(String s){
if(Character.isLowerCase(s.charAt(0)))
return s;
else
return (new StringBuilder()).append(Character.toLowerCase(s.charAt(0))).append(s.substring(1)).toString();
}
// //首字母转大写
public String toUpperCaseFirstOne(String s){
if(Character.isUpperCase(s.charAt(0)))
return s;
else
return (new StringBuilder()).append(Character.toUpperCase(s.charAt(0))).append(s.substring(1)).toString();
}

/**
* 去除所有空格,所有特殊符号,首字母小写
* 该方法去除了一切特殊符号,包括数字
* @param str
* @return
*/
public static String getNewStringNoNum(String str){
log.info("UtilString.getNewString.转换前为。。。。。。。。。。"+str);
char[] chars = str.toCharArray();
StringBuffer buffer=new StringBuffer();
for(int i = 0; i < chars.length; i ++) {
if((chars[i] >= 19968 && chars[i] <= 40869) || (chars[i] >= 97 && chars[i] <= 122) || (chars[i] >= 65 && chars[i] <= 90)) {
// buffer.append(chars[i]);
if (chars[0] >= 'A' && chars[0] <= 'Z') {//当为字母时,则转换为小写
buffer.append(chars[i]);
}
}
}
System.out.print(toLowerCaseFirstOne(buffer.toString()));
log.info("UtilString.getNewString.转换后为。。。。。。。。。。"+toLowerCaseFirstOne(buffer.toString()));
return toLowerCaseFirstOne(buffer.toString());
}
}

推荐阅读