EXCL模板报盘数据导入

jsp页面


<body>
<div>
<a href="javascript:void(0)" style="background-color: #ff6600;margin-left: 0px;" onclick="importData()">导入</a>

</div>
</body>	

<script type="text/javascript">
function importData() {

                       
			$.ajaxFileUpload({
				url: "${base!}/w/t/wt_importdata.html?Id=${dto?if_exists.Id!''}",            
				secureuri:false,
				fileElementId: 'textfield',
				dataType: 'json',
				success: function (data, status){
					if(data.hasError == "true"){
						var errors = [];
						for(var key in data){
							if(key != "hasError"){
								errors.push("第" + key + data[key]);
							}
						}
						//alert("上传失败!");
						mbox({
							title : "系统提示",
							message : errors.join("<br>")
							
						}); 
					}else if(data.status == "2"){
						///alert("上传失败!");
						 mbox({
							title : "系统提示",
							message : data.message
						
						}); 
					}else if(data.status == "4"){
						//alert("上传成功!");
						 mbox({
							title : "系统提示",
							message : data.message
							
						}); 
					}
					refreshPage();
				},
				error: function (data, status, e){
					
					alert("上传失败!");
					
				}
			});
	}

</script>


ExcelBean,处理excl表格数据:

import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import java.util.regex.Pattern;

import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFDateUtil;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;

/**
 * @description <h3>regex</h3>
 * <p>int 校验整型数据</p>
 * <p>number 校验数字</p>
 * <p>date,dateformat,date/date,dateformat,string 校验日期</p>
 * <p>code 校验选择项</p>
 * <p>cardid 校验身份证号</p>
 * <p>自定义校验规则或为空不做校验</p>
 * <h3>properties</h3>
 * <p>bean属性property数组</p>
 * <h3>proLength</h3>
 * <p>bean属性值最大长度数组</p>
 * @author 
 */
//EXCEL中数据都转为String类型处理
public final class ExcelBean<T> {

	private String[] properties;//字段名称
	private int[] proLength;//字段长度
	private int sheetno; //sheetno 当前处理的sheet页
	private int rowno; //rowno 起始行
	private int headerrowno; //标题行
	private int i; //i 起始列
	private Class<T> clazz;//bean的Class
	
	private String[] regepx;//正则校验
	private boolean[] notnull;
	private AbstractSpecialProperties specialProperties;
	
	/**
	 * @description 需要特殊处理的属性
	 * <p>需要自定义类并继承AbstractSpecialProperties抽象类,并实现特殊处理属性的方法dealSpecialMethod</p>
	 * @param specialProperties
	 * @void
	 * @author 
	 * @date 2015-11-13下午5:08:57
	 */
	public void setSpecialProperties(AbstractSpecialProperties specialProperties) {
		this.specialProperties = specialProperties;
	}
	
	public boolean[] getNotnull() {
		return notnull;
	}
	/**
	 * @description 设置是否校验可为空数组
	 * @param notnull
	 * @void
	 * @author 
	 * @date 
	 */
	public void setNotnull(boolean[] notnull) {
		this.notnull = notnull;
	}
	private int maxRownum = 0;//导入的最大条数限制
	//保存导入的数据
	private List<T> datas;
	public List<T> getDatas() {
		return datas;
	}
	public void setDatas(List<T> datas) {
		this.datas = datas;
	}
	/**
	 * @description 如果有错误,errors不为空,
	 * <p>key为ij,第几行第几列</p>
	 * <p>value为第i行第j列,+ header[j-1] + '数据错误' </p>
	 */
	private Map<String, String> errors;
	public int getHeaderrowno() {
		return headerrowno;
	}
	public void setHeaderrowno(int headerrowno) {
		this.headerrowno = headerrowno;
	}
	public String[] getProperties() {
		return properties;
	}
	public void setProperties(String[] properties) {
		this.properties = properties;
	}
	public int[] getProLength() {
		return proLength;
	}
	public void setProLength(int[] proLength) {
		this.proLength = proLength;
	}
	public int getSheetno() {
		return sheetno;
	}
	public void setSheetno(int sheetno) {
		this.sheetno = sheetno;
	}
	public int getRowno() {
		return rowno;
	}
	public void setRowno(int rowno) {
		this.rowno = rowno;
	}
	public int getI() {
		return i;
	}
	public void setI(int i) {
		this.i = i;
	}
	public Class<T> getClazz() {
		return clazz;
	}
	public void setClazz(Class<T> clazz) {
		this.clazz = clazz;
	}
	public String[] getRegepx() {
		return regepx;
	}
	public void setRegepx(String[] regepx) {
		this.regepx = regepx;
	}
	public Map<String, String> getErrors() {
		return errors;
	}
	public void setErrors(Map<String, String> errors) {
		this.errors = errors;
	}
	public int getMaxRownum() {
		return maxRownum;
	}
	/**
	 * @description 设置可导入的最大条数
	 * @param maxRownum
	 * @void
	 * @author
	 * @date 
	 */
	public void setMaxRownum(int maxRownum) {
		this.maxRownum = maxRownum;
	}
	/**
	 * @description 有错误返回true,没有错误返回false
	 * @return
	 * @boolean
	 * @author 
	 * @date 
	 */
	public boolean hasErrors(){
		return !errors.isEmpty();
	}
	/**
	 * @description properties,proLength,regepx必须存在,长度必须相等
	 * @param properties 属性数组不可为空
	 * @param proLength 属性长度不可为空
	 * @param sheetno 数据页
	 * @param rowno 数据起始行
	 * @param headerrowno 标题行
	 * @param i 起始列
	 * @param clazz
	 * @param regepx 正则匹配不可为空
	 */
	public ExcelBean(String[] properties, int[] proLength, String[] regexp, int sheetno,
			int rowno, int i, int headerrowno, Class<T> clazz){
		this.properties = properties;
		this.proLength = proLength;
		this.sheetno = sheetno;
		this.rowno = rowno;
		this.i = i;
		this.clazz = clazz;
		this.regepx = regexp;
		this.headerrowno = headerrowno;
		//按行列排序
		this.errors = new TreeMap<String, String>(new Comparator<String>() {
			@Override
			public int compare(String o1, String o2) {
				if(o1 != null && o2 != null){
					if(o1.contains("行") && o1.contains("列") && o2.contains("行") && o2.contains("列")){
						int temp1 = Integer.valueOf(o1.substring(0, o1.indexOf("行")));
						int temp2 = Integer.valueOf(o2.substring(0, o2.indexOf("行")));
						if(temp1 == temp2){
							temp1 = Integer.valueOf(o1.substring(o1.indexOf("行") + 1, o1.indexOf("列")));
							temp2 = Integer.valueOf(o2.substring(o2.indexOf("行") + 1, o2.indexOf("列")));
							return temp1 - temp2;
						}
						return temp1 - temp2;
					}
				}
				return o1.compareTo(o2);
			}
		});
	}
	/**
	 * @description 处理报盘模板Excel中的数据,并作校验
	 * @param source
	 * @return
	 * @List<T>
	 * @author 
	 * @throws IOException 
	 * @date 
	 */
	public List<T> impExcel(InputStream source){
		List<T> objs = new ArrayList<T>();
		boolean iterateFlag = true;
		int currRow = rowno;
		try {
			HSSFWorkbook wb = new HSSFWorkbook(new POIFSFileSystem(
					new BufferedInputStream(source)));
			String[] header = getExcelHeader(wb, sheetno, headerrowno, properties.length, i);
			if(!hasErrors()){
				HSSFSheet sheet = wb.getSheetAt(sheetno);
				if(sheet == null){
					errors.put("00", "导入文件sheet页错误");
					iterateFlag = false;
				}
				while (iterateFlag) {
					if(maxRownum != 0 && currRow >= maxRownum + rowno){
						//超过最大行数限制,多余数据忽略
						break;
					}
					HSSFRow row = sheet.getRow(currRow);
					
					if(row == null){//已到最后一行
						break;
					}
					if(checkLastRow(row, this.properties.length)){//有空行即退出循环。如果是最后一行返回true
						break;
					}else{
						T t = clazz.newInstance();
						HSSFCell cell;
						for (int i = 0; i < header.length; i++) {
							cell = row.getCell(i + this.i);
							
							if(cell == null){
								if(this.notnull != null){
									if(this.notnull[i]){//不可为空
										errors.put((currRow + 1) + "行" + (i + this.i + 1) + "列" , header[i] + "信息不能为空,请按要求填写。");
									}
								}
								continue;
							}
							String value = getStringValueFromCell(cell);
							if(StringUtils.isBlank(value)){//值为空,不作处理。
								continue;
							}
							//特殊处理属性的类存在
							if(this.specialProperties != null){
								//特殊属性不为空并且当前属性属于特殊属性
								if(this.specialProperties.getSpecialPropertiesList() != null && this.specialProperties.getSpecialPropertiesList().contains(this.properties[i])){
									try {
										value = this.specialProperties.dealSpecialMethod(properties[i], value);
										BeanUtils.copyProperty(t, properties[i], value);
									} catch (Exception e) {
										e.printStackTrace();
										errors.put((currRow + 1) + "行" + (i + this.i + 1) + "列", header[i] + "信息错误,请按要求填写。");
									}
									//不做其他校验
									continue;
								}
							}
							if("code".equals(regepx[i])){
								if(value.indexOf(" ") == -1){//代码项不含空格,提示错误
									errors.put((currRow + 1) + "行" + (i + this.i + 1) + "列", header[i] + "信息错误,应为选择项,请按要求选择。");
									continue;
								}else{
									value = value.substring(0, value.indexOf(" "));
								}
								
								if(!Pattern.matches("^[a-zA-Z0-9_\\-]*$", value)){//代码项中只允许有字符和数字、下划线、横线
									errors.put((currRow + 1) + "行" + (i + this.i + 1) + "列" , header[i] + "信息错误,请按要求选择。");
									continue;
								}
							}else if("int".equals(regepx[i])){
								if(!Pattern.matches("^[1-9][0-9]*$", value)){//整数校验
									errors.put((currRow + 1) + "行" + (i + this.i + 1) + "列" , header[i] + "信息错误,请输入整数。");
									continue;
								}
							}else if("number".equals(regepx[i])){//校验数字
								try {
									Double.valueOf(value);
								} catch (Exception e) {
									errors.put((currRow + 1) + "行" + (i + this.i + 1) + "列" , header[i] + "信息应为数字,请按要求填写。");
									continue;
								}
							}else if("cardid".equals(regepx[i])){//校验身份证号
								if(!Pattern.matches("^(([0-9]{17}[Xx]{1})|([1-9]{1}[0-9]{17}))$", value)){
									errors.put((currRow + 1) + "行" + (i + this.i + 1) + "列" , header[i] + "信息为身份证号,现填的内容为" + value +",长度为" + value.length() + "。请按要求填写。");
									continue;
								}
							}else if(regepx[i] != null && regepx[i].startsWith("date,")){//date已英文逗号隔开date,format日期格式化
								try {
									String[] datesReg = regepx[i].split(",");
									SimpleDateFormat format = new SimpleDateFormat(datesReg[1]);
									Date date = format.parse(value.trim());
									if(datesReg.length == 3){//保存成字符串格式
										SimpleDateFormat dateFormat = new SimpleDateFormat(datesReg[2]);
										BeanUtils.copyProperty(t, properties[i], dateFormat.format(date));
									}else{
										BeanUtils.copyProperty(t, properties[i], date);
									}
								} catch (Exception e) {
									errors.put((currRow + 1) + "行" + (i + this.i + 1) + "列" , header[i] + "信息错误,请按要求填写。");
								}
								continue;//时间赋值之后跳到下一个CELL
							}else if(regepx[i] != null){//自定义校验
								if(!Pattern.matches(regepx[i], value)){
									errors.put((currRow + 1) + "行" + (i + this.i + 1) + "列" , header[i] + "信息格式不正确,请按要求填写。");
									continue;
								}
							}else{
								//按普通字符串填写
							}
							//校验长度是否超范围
							if(value.length() > proLength[i]){
								errors.put((currRow + 1) + "行" + (i + this.i + 1) + "列" , header[i] + "信息超过要求长度,请按要求填写。");
								continue;
							}else{
								BeanUtils.copyProperty(t, properties[i], value);
							}
						}
						objs.add(t);
					}
					currRow++;
				}
			}
			//关闭文件流
			source.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
		if(this.hasErrors()){//校验出现错误,返回空。不进行导入。
			return null;
		}
		this.setDatas(objs);//导入的数据存放于datas中,便于保存
		return objs;
	}
	
	private String[] getExcelHeader(HSSFWorkbook workbook, int sheerno, int headerrow, int length, int i){
		String[] header = new String[length];
		try {
			HSSFWorkbook wb = workbook;
			if(sheetno > wb.getNumberOfSheets()){
				return null;
			}
			HSSFSheet sheet = wb.getSheetAt(sheetno);
			if (sheet == null) {
				errors.put("header00", "导入文件sheet页错误!");
				throw new Exception("导入文件sheet页错误!");
			}
			HSSFRow row = sheet.getRow(headerrowno);
			if (row != null) {
				for (int j = 0; j < length; j++) {
					HSSFCell cell = (HSSFCell) row.getCell(j + i);
					if(cell == null ){
						continue;
					}
					String value;
					if(getObjFormCell(cell) instanceof java.lang.String) {
						value = String.valueOf(getObjFormCell(cell));
					}else {
						continue;
					}
					if(value!=null){
						value=value.replaceAll(" ", "");
						value=value.replaceAll("\\n", "");
						value=value.replaceAll("\\*", "");
					}
					if (j == 0 && value != null && "end".equalsIgnoreCase(value)) {
						break;
					}
					if(value != "" || value != null){
						if(header[j]==null){
							header[j] = value;
						}else {
							if(header[j]!=""){
								header[j] += value;
							}else if(i > 0){
								header[j] = header[j-1]+value;
							}
						}
					}
				}
			}
		} catch (Exception ex) {
			errors.put("header01", "获取模板头部信息时错误!");
			throw new RuntimeException(ex);
		}
		return header;
	}
	
	private static Object getObjFormCell(HSSFCell cell) {
		switch (cell.getCellType()) {
			case HSSFCell.CELL_TYPE_NUMERIC :
				if (HSSFDateUtil.isCellDateFormatted(cell)) {
					return cell.getDateCellValue();
				}
				return (Object) new Double(cell.getNumericCellValue());
				
			case HSSFCell.CELL_TYPE_STRING : 
				return cell.getStringCellValue();
				
			default:
				return (Object) cell.getStringCellValue();
		}
	}
	/**
	 * @description 获取excel表格中的字符串数据
	 * @param cell
	 * @return
	 * @String
	 * @author 
	 * @date 
	 */
	private static String getStringValueFromCell(HSSFCell cell){
		switch (cell.getCellType()) {
			case HSSFCell.CELL_TYPE_NUMERIC :
				if (HSSFDateUtil.isCellDateFormatted(cell)) {
					Date date = cell.getDateCellValue();
					return date == null ? null : date.toString();
				}
				cell.setCellType(HSSFCell.CELL_TYPE_STRING);//修改为文本数据
				return cell.getStringCellValue();
			case HSSFCell.CELL_TYPE_STRING : 
				return cell.getStringCellValue();
			default:
				cell.setCellType(HSSFCell.CELL_TYPE_STRING);//修改为文本数据
				return cell.getStringCellValue();
		}
	}
	/**
	 * @description 
	 * @param row
	 * @param cellNum 列数
	 * @return
	 * @boolean
	 * @author 
	 * @date 
	 */
	private boolean checkLastRow(HSSFRow row, int cellNum){
		boolean isLast = true;
		if(row == null){
			return isLast;
		}else{//row不为空
			for (int i = 0; i < cellNum; i++) {
				HSSFCell cell = row.getCell(i);
				if(cell != null){
					//强制cell为String类型,以免取值发生错误
					cell.setCellType(HSSFCell.CELL_TYPE_STRING);
					String value = getStringValueFromCell(cell);
					if(StringUtils.isNotBlank(value)){//有一个不为空既不是最后一行
						isLast = false;
						break;
					}
				}
			}
		}
		return isLast;
	}
}

定义实体和dao、dto :


限制EXCL导入数据条数上限:

@Repository
public class testWebDao{

	public int countNum(String Id){
		Bricks bricks = new Bricks(this);
		bricks.eq("Id", Id);
		return countBricks(bricks).intValue();
	}
	
}

实体dto,testWebDto.java


public class testWebDto {


        private String Id;
	private String name;
	private String class;
	private String age;
	private String sex;
    .............

}




service 类,ImportExcelMngImpl .java ,调用excleBean:


import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.sql.Date;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
public class WgbgfImportExcelMngImpl implements WgbgfImportExcelMng<testWebDto> {
	
	@Autowired
	private testWebDao testWebDao;


	@Override
	public ExcelBean<<span style="font-family: Arial, Helvetica, sans-serif;">test</span>WebDto> tempSaveInJavaBean(InputStream is,<span style="font-family: Arial, Helvetica, sans-serif;">test</span><span style="font-family: Arial, Helvetica, sans-serif;">WebDto t) {</span>
	
		
		int maxNum = 99;
		int currentNum = testWebDao.countNum(t.getId());
		if(currentNum >= maxNum){
			return null;
		}
		
		int[] proLength = new int[]{ 18, 10, 3, 3, 50};
		String[] properties = new String[]{"id", "name", "age", "class", "sex"};
		String[] regexp = new String[]{"cardid", null, "code",  "^[0-9\\-]{0,50}$",
									  "number", "date,yyyyMMdd,yyyy-MM-dd", "date,yyyyMMdd,yyyy-MM-dd", null};
		boolean[] notnull = new boolean[]{true, true, true, false, true};
		ExcelBean<testWebDto> excelBean = new ExcelBean<testWebDto>(properties, proLength, regexp, 1, 3, 0, 1, testWebDto.class);
		excelBean.setNotnull(notnull);
		excelBean.setMaxRownum(maxNum - currentNum);
		excelBean.impExcel(is);
		return excelBean;
	}


}





action 这里用的是SpringMVC注解模式:


import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;

import org.apache.commons.lang.StringUtils;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.multipart.commons.CommonsMultipartFile;




@Controller
@RequestMapping("/t/")

public class WtAct {


	@Autowired
	private ImportExcelMng<testWebDto> importExcelMng;

       @ResponseBody
	@RequestMapping("wt_importdata.html")
	public void importData(MultipartHttpServletRequest request, String Id, ModelMap model, HttpServletResponse response){
		
		
		testWebDto dto = new testWebDto();
		dto.setId(Id);
		Iterator<String> fileIter = request.getFileNames();
		String message="";
		if (!fileIter.hasNext()) {
			message="模板文件错误,请查看!";
			JSONUtil.writejson(response, "{'status' : '2', 'message' : '" + message + "'}");
			return;
		}
		CommonsMultipartFile file = (CommonsMultipartFile) request.getFile("textfield");
		String fileName = file.getOriginalFilename();
		if (!fileName.endsWith(".xls")) {
			message="模板文件错误,请查看!";
			JSONUtil.writejson(response, "{'status' : '2', 'message' : '" + message + "'}");
			return;
		} else if(StringUtils.isBlank(Id)){
			message="请先填写并保存基本补贴信息!";
			JSONUtil.writejson(response, "{'status' : '2', 'message' : '" + message + "'}");
			return;
		} else {
			try {
				ExcelBean<testWebDto> excelBean = this.importExcelMng.tempSaveInJavaBean(file.getInputStream(), dto);
				if(excelBean == null){//花名册已达到最大人员数量限制
					message = "花名册人员数量已达到最大值。";
				}else if(excelBean.hasErrors()){//报盘文件存在错误信息
					excelBean.getErrors().put("hasError", "true");
					JSONUtil.write(response, excelBean.getErrors());
					return;
				}else{//通过校验,数据保存至临时表
					importExcelMng.saveData(excelBean.getDatas(), dto);
					message = importExcelMng.importCheckData(dto);//调用过程校验报盘表数据  /** saveData和importCheckData分别是保存和校验数据方法,此处不详细叙述
				}
			} catch (Exception e) {
				e.printStackTrace();
				message = "获取模板文件信息出错";
			}
		}
		
		JSONUtil.writejson(response, "{'status' : '4', 'message' : '" + message + "'}");
	}
	



}



你可能感兴趣的:(EXCL模板报盘数据导入)