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; } }
限制EXCL导入数据条数上限:
@Repository public class testWebDao{ public int countNum(String Id){ Bricks bricks = new Bricks(this); bricks.eq("Id", Id); return countBricks(bricks).intValue(); } }
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 + "'}"); } }