是时候该总结一下了

附件的批量上传


项目是工单管理系统,顾名思义就是管理工单的系统。在该项目的使用中你创建了工单,可以向该工单上传附件,但当时附件的上传仅仅是单一附件上传。因此二次开发要求开发一个附件的批量上传功能(值得说明一下项目使用的是ssh框架)。最初的业务要求是这样的:
将本地所有要上传的附件添加到一个excel的模板中,模板的样式如下所示

工单编号附件路径附件说明
gdbh1c:/xxx/a.docgdbh1的附件说明
gdbh2d:/xxx/b.xlsgdbh2的附件说明
gdbh3e:/xxx/xxx/c.jpggdbh3的附件说明

注意:“附件路径”中的路径全都是上传这本地的路径,为未来的麻烦埋了个伏笔。

当填写好这个模板后,点击“导入”按钮,将模板提交给action,在action中对此模板进行解析。根据本地路径将文件上传到服务器中。这在本地测试每次都是成功的,但提交到测试服务器,出现了无法按照给定路径找到文件,无法上传成功的问题。

原因是:路径问题,在测试环境中是linux环境,按照本地的windows的文件路径自然是找不到文件。而原本项目中的文件上传是靠struts2中的<s:file>实现的文件上传,此标签<s:file> 当点击“浏览”时选定了文件,此时文件便已经上传到了一个临时的文件夹中,即使选择文件后将本地的文件删除,只要点击“导入”,文件依然会上传到服务器中。
因此,不得不把视线的思路改回到正统的批量上传上来。如图所示
这里写图片描述
图一

下面是前台jsp、js代码及action解析的代码
jsp代码:

<s:form enctype="multipart/form-data" method="POST"> 
<input type="hidden" name="executeMsg" id="executeMsg"/> 
<input type="hidden" name="operators" id="operators"/>
<input type="hidden" name="flowcode" id=flowcode value="${flowcode}"/> 
<input type="hidden" name="formModeId" id="formModeId" value="${formModeId}"/>
<input type="hidden" name="nextView" id="nextView" value="${nextView}"/>

<br>                                    
    <table width="600" border="0" cellspacing="0" cellpadding="0" align="center">
        <!-- 以下附件 by zyc -->
        <tr>
            <td width="1%"><img src="/images/middle/box_topl.gif" width="11" height="19" /></td>
            <td align="center" class="hui2">批量上传安全整改流程工单附件</td>
            <td width="60%" background="/images/middle/box_topbg.gif">&nbsp;</td>
            <td width="1%"><img src="/images/middle/box_topr.gif" width="11" height="19" /></td>
        </tr>
        <tr>
            <td background="/images/middle/box_middlel.gif">&nbsp;</td>
            <td colspan="2">
            <table  width="100%" border="0" id="table_together" style="width: 600px; text-align: center">
                <tr>
                    <td align="center" width="135px">工单编号</td>
                    <td align="center" width="205px">附件地址</td>
                    <td align="center" width="135px">附件说明</td>
                    <td align="center" width="105px"><input value="添加" type="button"  style="width: 40px; height: 25px" onclick="insertRows()">
                                       <input value="导入" type="button"  style="width: 40px; height: 25px" onClick="submitFile2()">
                    </td>
                </tr>
                <tr>
                    <td align="center"><input type="text" id="serialno" name="serialno" ></TD>
                    <td align="center"><s:file name="attachment" id="attachment2" ></s:file></TD>
                    <td align="center"><input type="text" id="remark" name="remark" ></TD>
                    <td align="center"><input value="删除" type="button"  style="width: 40px; height: 25px" onClick="delTableRow(this)"></TD>
                </tr>  
            </table>
            <div>
                  1、此批量上传功能,“工单编号”及“附件地址”是必填项,“附件说明”未选填项 。<br>其中“工单编号”为上传的附件对应的工单。“附件地址”填写该附件所在路径,且文件必须填写扩展名。如:C:\xxx\abc.doc <br>
                  2、点击“添加”时,会增加一行以供添加附件。点击“删除”会删除指定的行。<br>
            </div>
            </td>
            <td background="/images/middle/box_middler.gif">&nbsp;</td>
        </tr>

        <!-- 以上附件 by zyc -->
        <tr>
            <td height="10"><img src="/images/middle/box_bottoml.gif" width="11" height="19" /></td>
            <td height="10" colspan="2" background="/images/middle/box_bottombg.gif">&nbsp;</td>
            <td><img src="/images/middle/box_bottomr.gif" width="11" height="19" /></td>
        </tr>
    </table>
</s:form>

js代码:

var tempRow=0; 
var maxRows=0; 
function insertRows(){ 
    var userAgent = navigator.userAgent; //取得浏览器的userAgent字符串  
    var isOpera = userAgent.indexOf("Opera") > -1; //判断是否Opera浏览器  
    var isIE = userAgent.indexOf("compatible") > -1 && userAgent.indexOf("MSIE") > -1 && !isOpera; //判断是否IE浏览器  
    var table_together = document.getElementById("table_together"); 
    if (isIE){ 
        tempRow=table_together.rows.length-1; 
        maxRows=tempRow; 
        tempRow=tempRow+1; 
        var Rows=table_together.rows;//类似数组的Rows 
        var newRow=table_together.insertRow(table_together.rows.length);//插入新的一行 
        var Cells=newRow.cells;//类似数组的Cells 
        for (i=0;i<4;i++){//每行的7列数据 

        var newCell=Rows(newRow.rowIndex).insertCell(Cells.length); 
        newCell.align="center"; 
            switch (i) { 
                case 0: newCell.innerHTML='<td align="center"><input type="text" id="serialno" name="serialno"></TD>'; break; 
                case 1: newCell.innerHTML='<td align="center">'+
                        '<s:file name="attachment" id="attachment2" ></s:file>'+
                        '</TD>'; break; 
                case 2: newCell.innerHTML='<td align="center" ><input type="text" id="remark" name="remark"></TD>'; break; 
                case 3: newCell.innerHTML='<td align="center" ><input value="删除" type="button"  style="width: 40px; height: 25px" onClick="delTableRow(this)"></TD>'; break; 
            } 
        }
        maxRows+=1; 
    }else{
         var rowObj = document.createElement("tr");  
         var cellObj = document.createElement("td");  
         cellObj.innerHTML = '<input type="text" id="serialno" name="serialno">';  
         rowObj.appendChild(cellObj)  
         cellObj = document.createElement("td");  
         cellObj.innerHTML = '<s:file name="attachment" id="attachment2" ></s:file>';  
         rowObj.appendChild(cellObj);  
         cellObj = document.createElement("td");  
         cellObj.innerHTML = '<input type="text" id="remark" name="remark">';  
         rowObj.appendChild(cellObj);
         cellObj = document.createElement("td");  
         cellObj.innerHTML = '<input value="删除" type="button"  style="width: 40px; height: 25px" onClick="delTableRow(this)">';  
         rowObj.appendChild(cellObj);  
         table_together.appendChild(rowObj);  
    }
} 

function delTableRow(r){ 
    var rowNum = r.parentNode.parentNode.rowIndex;
    table_together.deleteRow(rowNum);

} 


function submitFile2(){     //导入
    var table_together = document.getElementById('table_together');
    if(table_together.rows.length==1){
        alert("请选择文件");
        return false;
    }
    var form=document.forms[1];
    var file = document.getElementsByName('attachment');
    var serialno = document.getElementsByName('serialno');
    var remark = document.getElementsByName('remark');
    if(checkData(file,serialno,remark)){
        form.action="${ctx}/maintenance/SafetyLanuchAction!saveSafetyFlowAttachments.do";
        form.submit();
        showProgressBar(this);
    }

}

function checkData(file,serialno,remark){   //进行校验  进行验证
    if(file.length-1!=serialno.length){ //如果工单编号与附件个数不等说明有空白项目  不予上传
        alert("工单编号或文件未填写");
        return false;
    }

    for(var i=1;i<file.length;i++){     //判断是否有空附件
        if(file[i].value==""){
            alert("存在空白的附件,请选择要上传的附件。");
            return false;
        }
    }

    for(var i=0;i<serialno.length;i++){     //判断是否有空工单编号
        if(serialno[i].value==""){
            alert("存在空白工单编号,请填写。");
            return false;
        }
    }

    for(var i=0;i<remark.length;i++){
        if(remark[i].value.length>500){
            alert("附件说明字数不能超过500字");
            return false;
        }
    }
    return true;
}

action代码如下:
此代码中上传成功跳转的页面采用的是已有的异常页面格式,这是欠妥的!!!
如果有使用者借用此action代码,要注意这一点,小心被骂。

public void saveSafetyFlowAttachments() throws ServletException, IOException {
        StringBuffer msg = new StringBuffer();  //重复文件的提示信息 
        StringBuffer msg1 = new StringBuffer(); //文件过大的提示信息
        StringBuffer msg2 = new StringBuffer(); //上传成功的提示信息
        StringBuffer msg3 = new StringBuffer(); //工单不存在的提示信息
        LogonVO logonVO = null;
        int num = 0;                            //用以承接某一工单中存在的重复工单数 
        int numToJudge = 0;                     //计数器  用以确定需要批量上传的工单是否存在工单编号错误的情况
        RecFlow recFlow = null;         //  声明recFlow对象
        //获得传来的.xls文件
        Map<String, String[]> params = request.getParameterMap();
        serialno = params.get("serialno");                                  //工单编号
        remark = params.get("remark");                                      //附件说明
        String flw_ids[] = new String[serialno.length];                     //存储工单流水号的数组
        String fileNames[] = new String[this.model.getAttachmentFileName().length]; //文件名
        File files[] = new File[this.model.getAttachment().length];                 //文件路径
        List<Integer> upload_num = new ArrayList<Integer>();                        //存储上传文件的 下标
        for(int k=0;k<this.model.getAttachment().length;k++){
            fileNames[k]=this.model.getAttachmentFileName()[k];
            files[k]=this.model.getAttachment()[k];
            logger.info("数据导入文件:"+fileNames[k]);

            long fileSize=files[k].length();
            if(fileSize>MAX_SIZE){
                if (!StringUtils.isBlank(msg1.toString())) {
                    msg1.append(",<br>");
                }
                msg1.append(serialno[k].trim()+"工单的"+fileNames[k]);
                continue;
            }

            //根据工单编号查询工单进而获取流水号
            recFlow = recFlowManager.findByserialNO(serialno[k].trim());
            //判断工单是否存在
            if (recFlow==null) {

                msg3.append(serialno[k].trim()+"工单不存在,请检查工单编号是否正确。<br>");
                continue;
            }else{
                flw_ids[k] = recFlow.getFlowlsh();
                upload_num.add(k);
            }
            numToJudge++;                   
            flw_ids[k]=recFlow.getFlowlsh();
            //查询工单重复数量
            num = attachmentService.getNumberOfAttachments(flw_ids[k],fileNames[k]);

            //如果该工单存在同名附件  则向msg注入信息
            if (num>0&&msg.toString().indexOf(fileNames[k].toString())==-1) {
                msg.append(serialno[k]+"工单,已经存在"+num+"个与"+fileNames[k]+"同名的文件。<br>");
            }
        }

        //上传文件
        if(numToJudge>0){           //如果flag为false 说明存在大于2M文件 如果等式不成立 说明某个工单不存在
            for (Integer i : upload_num) {
                AttachmentImpl attachmentImpl = new AttachmentImpl();
                byte[] content = new byte[0];
                if (files[i].exists()) {
                    content = FileCopyUtils.copyToByteArray(files[i]);
                }
                //获取登录人
                HttpSession session = request.getSession(false);
                logonVO = (LogonVO) session.getAttribute("logonVO");

                attachmentImpl.setContent(content);
                attachmentImpl.setMimeType(new MimetypesFileTypeMap().getContentType(files[i]));
                attachmentImpl.setName(fileNames[i]);
                attachmentImpl.setSize(content.length);
                attachmentImpl.setRemark(remark[i]);
                attachmentService.addAttachment(attachmentImpl, flw_ids[i], "",logonVO.getPersonCode());
            }
        }
        if(upload_num.size()>0){
            if(!StringUtils.isBlank(msg1.toString())){
                msg2.append(msg1.toString()+"<br>附件太大了,因此不执行上传操作。<br>文件不能大于"+MAX_SIZE/(1024 * 1024)+"M。<br>");
            }
            if(!StringUtils.isBlank(msg3.toString())){
                msg2.append(msg3.toString());
            }
            if(!StringUtils.isBlank(msg1.toString())||!StringUtils.isBlank(msg3.toString())){
                msg2.append("其余上传成功。<br>");
            }else{
                msg2.append("上传成功。<br>");
            }
            if(!StringUtils.isBlank(msg.toString())){
                msg2.append("其中"+msg.toString());
            }
        }
        if(upload_num.size()==0){
            if(!StringUtils.isBlank(msg1.toString())){
                msg2.append(msg1.toString()+"<br>附件太大了,因此不执行上传操作。<br>文件不能大于"+MAX_SIZE/(1024 * 1024)+"M。<br>");
            }
            if(!StringUtils.isBlank(msg3.toString())){
                msg2.append(msg3.toString());
            }
        }

        String backBtn = "<br><button href='javascript:' onclick='self.location=document.referrer;'>返回</button> ";
        throw new IllegalStateException(GlobalMessage.prefix+msg2.toString()+backBtn);
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值