struts2中excel表格上传以及解析

6 篇文章 0 订阅
4 篇文章 0 订阅

 

 

之前因为工作需要实现了后端struts2框架,前端jsp实现的excel表格上传以及内容解析,现在整理一下。

前端jsp html部分代码如下:

<s:form action="planAction_uploadAndSaveExcel.action" method="post" enctype="multipart/form-data">
    <s:file name="uploadFile" label="导入汇总表" id="filePath"></s:file>
	<input type="hidden" id="recordname" name="recordName" value="${sessionScope.globle_user.loginname}"/>
	<input type="submit" value="导入">
</s:form>

form表单的action映射到struts后端 planAction类的uploadAndSaveExcel方法

//上传Excel文件并保存数据到数据库
	public String uploadAndSaveExcel() throws Exception{
		String directory = "/upload/role";
		String targetDirectory = ServletActionContext.getServletContext().getRealPath(directory);
		//生成上传的文件对象
		File target = new File(targetDirectory,uploadFileFileName);
		//如果文件已经存在,则删除原有文件
		if(target.exists()){
			target.delete();
		}
		//复制file对象,实现上传
		try {
			FileUtils.copyFile(uploadFile, target);
		} catch (IOException e) {
			e.printStackTrace();
		}

		//解析上传的excel表格
		String importresult = loadPlanInfo(uploadFileFileName,target);
		String result=null;

		if (importresult.equals("import success")){
			result = "saveAndStartProcess";
		}else if(importresult.equals("import error")){
			result =  "concentratedleave";
		}
		return result;
	}
loadPlanInfo方法对excel表格做解析处理,该方法只能对没有合并单元格的excel表格进行解析
/**
	 * 把Excele表读出的数据,组装成一个List,统一导入数据库
	 * @param uploadFileFileName
	 */
public String loadPlanInfo(String uploadFileFileName,File target){

	String randuuid =uuidUtil.get32UUID();

	List<HolidayApply> holidayApplys = new ArrayList<>();
	SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
	SimpleDateFormat sdf_time2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
	Date new_enddate = new Date();

	try{
		InputStream fi = new FileInputStream(target);
		Workbook wb = WorkbookFactory.create(fi);
		Sheet sheet = wb.getSheetAt(1);

		int rowNum = sheet.getLastRowNum();
		for(int i=3;i<rowNum;i++){
			HolidayApply applyInfo = new HolidayApply();
			Row row = sheet.getRow(i);
			int cellNum = row.getLastCellNum();
			for(int j=1;j<cellNum;j++){
				Cell cell = row.getCell(j);
				String cellValue = null;
				switch(cell.getCellType()){ //判断excel单元格内容的格式,并对其进行转换,以便插入数据库
				    case 0 :
						if ("yyyy/mm;@".equals(cell.getCellStyle().getDataFormatString()) || "m/d/yy".equals(cell.getCellStyle().getDataFormatString()) || "yy/m/d".equals(cell.getCellStyle().getDataFormatString()) ||									"mm/dd/yy".equals(cell.getCellStyle().getDataFormatString()) ||									"dd-mmm-yy".equals(cell.getCellStyle().getDataFormatString())||								"yyyy/m/d".equals(cell.getCellStyle().getDataFormatString()) ) {
							new_enddate = cell.getDateCellValue();
						}else {
								cellValue = String.valueOf((int)cell.getNumericCellValue());
						}
						break;
					case 1 : cellValue = cell.getStringCellValue(); break;
					case 2 : new_enddate = cell.getDateCellValue(); break;
					case 3 : cellValue = ""; break;
					case 4 : cellValue = String.valueOf(cell.getBooleanCellValue()); break;
					case 5 : cellValue = String.valueOf(cell.getErrorCellValue()); break;
					}

				switch(j){//通过列数来判断对应插如的字段
					case 1 : applyInfo.setName(cellValue);break;
					case 2 : applyInfo.setServicy(cellValue);break;
					case 3 :
						if (cellValue.equals("休假")){
							cellValue="10";
						}
						applyInfo.setEventclass(Integer.parseInt(cellValue));
						break;
					case 4 : applyInfo.setDestination(cellValue);break;
					case 5 : applyInfo.setEvent(cellValue);break;
					case 6 :
							applyInfo.setStartdate(new_enddate);
							applyInfo.setStrstartdate(sdf.format(new_enddate));
							break;
						//将结束时间设置到当天夜里23点,使得人员在位情况白天处于不在位
					case 7 :
			applyInfo.setEnddate(sdf_time2.parse(sdf.format(new_enddate)+" 23:00:00"));
							applyInfo.setStrenddate(sdf.format(new_enddate));
							break;
				}
			}
		
			try {
				applyInfo.setApplytime(new Date());
				applyInfo.setRecordname(recordName);
				applyInfo.setCountdays((int)countdays);
				applyInfo.setProcuuid(randuuid);
				holidayApplys.add(applyInfo);

			} catch (Exception e) {
				// TODO: handle exception
				e.printStackTrace();
			}
		}

	} catch(IOException e){
		e.printStackTrace();
	} catch (InvalidFormatException e) {
		e.printStackTrace();
	} catch (ParseException e) {
		e.printStackTrace();
	}
	return "import success";
}

而如果需要对存在合并单元格的excel表格,则对应的loadPlanInfo方法为:

/**
     * 把Excele表读出的数据,组装成一个List,统一导入数据库
     * @param uploadFileFileName
     */
    public String loadPlanInfo(String uploadFileFileName,File target){
        String randuuid =uuidUtil.get32UUID();
        List<HolidayPlan> planInfolist = new ArrayList<>();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        SimpleDateFormat sdf_time2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

        try{
            InputStream fi = new FileInputStream(target);
            Workbook wb = WorkbookFactory.create(fi);
            Sheet sheet = wb.getSheetAt(1);
            int rowNum = sheet.getLastRowNum();

            for(int i=3;i<rowNum;i++){
                int isempty = 0;//该标志作为表格中的某行是否为空行
                HolidayPlan planInfo = new HolidayPlan();
                Row row = sheet.getRow(i);
                int cellNum = row.getLastCellNum();
                for(int j=1;j<cellNum;j++){
                    Cell cell = row.getCell(j);
                    String cellValue = null;
                    boolean isMerge = isMergedRegion(sheet, i, cell.getColumnIndex());
                    //判断是否具有合并单元格
                    if(isMerge) {
                        cellValue = getMergedRegionValue(sheet, row.getRowNum(), cell.getColumnIndex());
                    }else {
                        cellValue = getCellValue(cell);
                    }

                    switch (j){
                        case 1 : planInfo.setName(cellValue);break;
                        case 2 : planInfo.setServicy(cellValue);break;
                        case 3 :
                            if(cellValue.equals("休假")){
                                cellValue = "1";
                                planInfo.setEventclass(Integer.parseInt(cellValue));
                            }else if(cellValue.equals("探亲")){
                                cellValue = "5";
                                planInfo.setEventclass(Integer.parseInt(cellValue));
                            }else if(cellValue.equals("")){
                                //当请假类型为空时,说明该行记录为空,不再继续解析后续的列
                                isempty = 1;
                                j = cellNum;
                            }
                            break;
                        case 4 : planInfo.setTotaldays(Integer.parseInt(cellValue)); break;
                        case 5 :
                            Date new_startdate = new Date(cellValue);
                            planInfo.setStartdate(new_startdate);
                            planInfo.setStrstartdate(sdf.format(new_startdate));
                            break;
                        case 6 :
                            Date new_enddate = new Date(cellValue);
                            planInfo.setEnddate(new_enddate);
                            planInfo.setStrenddate(sdf.format(new_enddate)); break;
                        case 7 : planInfo.setActualdays(Integer.parseInt(cellValue)); break;
                        case 8 : planInfo.setDestination(cellValue); break;
                        case 9 :
                            if (cellValue != null && cellValue != ""){
                                planInfo.setDaysonroad(Integer.parseInt(cellValue));
                            } else{
                                planInfo.setDaysonroad(0);
                            }break;
                    }
                }
                //该行记录为空,增加一个空对象(只含name,userid等字段),继续解析下一行
                if (isempty == 1){
                    planInfolist.add(planInfo);
                    continue;
                }

                try {
                    planInfo.setStatus(HolidayPlan.HAS_APPLY);
                    planInfo.setApplytime(new Date());
                    planInfo.setRecordname(recordName);
                    int countdays = computeActualdays(planInfo);
                    planInfo.setCountdays(countdays);
                    planInfo.setProcuuid(randuuid);
                    planInfolist.add(planInfo);
                } catch (Exception e) {
                    // TODO: handle exception
                    e.printStackTrace();
                }
            }

            //为了前端展示方便,添加index
            for (int i= 0 ; i< planInfolist.size();i++){
                planInfolist.get(i).setIndex(i);
            }


        } catch(IOException e){
            e.printStackTrace();
        } catch (InvalidFormatException e) {
            e.printStackTrace();
        }
        return "import success";
    }

对excel的合并单元格做判断的方法如下:

/**
     * 获取合并单元格的值
     * @param sheet
     * @param row
     * @param column
     * @return
     */
    public String getMergedRegionValue(Sheet sheet ,int row , int column){
        int sheetMergeCount = sheet.getNumMergedRegions();

        for(int i = 0 ; i < sheetMergeCount ; i++){
            CellRangeAddress ca = sheet.getMergedRegion(i);
            int firstColumn = ca.getFirstColumn();
            int lastColumn = ca.getLastColumn();
            int firstRow = ca.getFirstRow();
            int lastRow = ca.getLastRow();

            if(row >= firstRow && row <= lastRow){

                if(column >= firstColumn && column <= lastColumn){
                    Row fRow = sheet.getRow(firstRow);
                    Cell fCell = fRow.getCell(firstColumn);
                    return getCellValue(fCell) ;
                }
            }
        }

        return null ;
    }
    /**
     * 判断合并了行
     * @param sheet
     * @param row
     * @param column
     * @return
     */
    private boolean isMergedRow(Sheet sheet,int row ,int column) {
        int sheetMergeCount = sheet.getNumMergedRegions();
        for (int i = 0; i < sheetMergeCount; i++) {
            CellRangeAddress range = sheet.getMergedRegion(i);
            int firstColumn = range.getFirstColumn();
            int lastColumn = range.getLastColumn();
            int firstRow = range.getFirstRow();
            int lastRow = range.getLastRow();
            if(row == firstRow && row == lastRow){
                if(column >= firstColumn && column <= lastColumn){
                    return true;
                }
            }
        }
        return false;
    }
    /**
     * 判断指定的单元格是否是合并单元格
     * @param sheet
     * @param row 行下标
     * @param column 列下标
     * @return
     */
    private boolean isMergedRegion(Sheet sheet,int row ,int column) {
        int sheetMergeCount = sheet.getNumMergedRegions();
        for (int i = 0; i < sheetMergeCount; i++) {
            CellRangeAddress range = sheet.getMergedRegion(i);
            int firstColumn = range.getFirstColumn();
            int lastColumn = range.getLastColumn();
            int firstRow = range.getFirstRow();
            int lastRow = range.getLastRow();
            if(row >= firstRow && row <= lastRow){
                if(column >= firstColumn && column <= lastColumn){
                    return true;
                }
            }
        }
        return false;
    }
    /**
     * 判断sheet页中是否含有合并单元格
     * @param sheet
     * @return
     */
    private boolean hasMerged(Sheet sheet) {
        return sheet.getNumMergedRegions() > 0 ? true : false;
    }

    /**
     * 合并单元格
     * @param sheet
     * @param firstRow 开始行
     * @param lastRow 结束行
     * @param firstCol 开始列
     * @param lastCol 结束列
     */
    private void mergeRegion(Sheet sheet, int firstRow, int lastRow, int firstCol, int lastCol) {
        sheet.addMergedRegion(new CellRangeAddress(firstRow, lastRow, firstCol, lastCol));
    }

    /**
     * 获取单元格的值
     * @param cell
     * @return
     */
    public String getCellValue(Cell cell){

        if(cell == null) return "";

        if(cell.getCellType() == Cell.CELL_TYPE_STRING){

            return cell.getStringCellValue();

        }else if(cell.getCellType() == Cell.CELL_TYPE_BOOLEAN){

            return String.valueOf(cell.getBooleanCellValue());

        }else if(cell.getCellType() == Cell.CELL_TYPE_FORMULA){

            return cell.getCellFormula() ;

        }else if(cell.getCellType() == Cell.CELL_TYPE_NUMERIC){
            if ( "yyyy/mm;@".equals(cell.getCellStyle().getDataFormatString()) ||
                    "m/d/yy".equals(cell.getCellStyle().getDataFormatString()) ||
                    "yy/m/d".equals(cell.getCellStyle().getDataFormatString()) ||
                    "mm/dd/yy".equals(cell.getCellStyle().getDataFormatString()) ||
                    "dd-mmm-yy".equals(cell.getCellStyle().getDataFormatString())||
                    "yyyy/m/d".equals(cell.getCellStyle().getDataFormatString()) ) {
                return cell.getDateCellValue().toString();
            }else {
                return String.valueOf((int)cell.getNumericCellValue());
            }
        }
        return "";
    }

以上就是前端ecxel表格上传以及后端解析的过程

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值