需要注意的地方:

    1.js构造表单并提交

    2.js中文传参encodeURI(encodeURI("中文")),action接收并转换value = URLDecoder.decode(value,"utf-8");

    3.excel2003和excel2007以上版本,java代码有所区别

    4.excel边框,样式,字体,颜色等设置;excel单元格的合并

    5.excel文件的下载

1.excel下载

  1.1 js构造excel下载表单,设置查询参数

  1. /* charset:UTF-8 */
  2. $(document).ready(function() {
  3.  
  4. //添加form,用于下载excel文件
  5. $("body").append( '<div class="form_container" style="display:none;">'+
  6. '<form id="download_excel_form" action="" method="post">'+
  7. '<input type="text name="nessesary" value="">'+
  8. '<input type="submit" name="submit" id="form_container_submit">'+
  9. '</form>'+
  10. '</div>'
  11. );
  12.  
  13. });
  14.  
  15. //重写方法:查询页面,根据查询条件,导出个人信息(完整信息)
  16. function doExpExcel(){
  17. //查询条件16个
  18. //name,gender,birth,fhighestDegree全日制,nhighestAcademic非全日制最高学位,whetherPost是否在岗,
  19. //stationId单位,note是否审核,note1是否委派,currentPosition现任职务
  20. //accountingQualification会计专业技术资格,technicalPosition会计专业技术职务,administrativeLevel行政级别
  21. //appointmentTime现任职务时间,unitClassification单位分类,jobPosition现从事会计工作岗位
  22. var action = "/cwgl/cwgl/cwglpersonnel/CwglPersonnel.do?method=exportXlsx";
  23. //获取查询参数
  24. //单位名称
  25. action = getSelectedValue("stationId", action);
  26. //姓名
  27. action += "&name="+$("#name").val();
  28. //性别
  29. action = getSelectedValue("gender", action);
  30. //出生日期
  31. action += "&birth="+$("#birth").val();
  32. action = getSelectedValue("administrativeLevel", action);
  33. action = getSelectedValue("fhighestDegree", action);
  34. action = getSelectedValue("nhighestDegree", action);
  35. action = getSelectedValue("whetherPost", action);
  36. action = getSelectedValue("accountingQualification", action);
  37. action = getSelectedValue("technicalPosition", action);
  38. action += "&appointmentTime="+$("#appointmentTime").val();//现任职务时间
  39. action = getSelectedValue("note1", action);
  40. action = getSelectedValue("note", action);
  41. action = getSelectedValue("unitClassification", action);
  42. action = getSelectedValue("jobPosition", action);
  43. console.log(action);
  44. var form = $("#download_excel_form");
  45. form.attr("action",encodeURI(encodeURI(action)));
  46. // $("#download_excel_form").submit();
  47. $("#form_container_submit").click();
  48. }
  49.  
  50. //下拉列表所选值
  51. function getSelectedValue(id,action){
  52. var _txt = $("#"+id+"_dd_text").val();
  53. $("#"+id+" option").each(function(){
  54. if($(this).text()==_txt){
  55. action += "&"+id+"="+$(this).val();
  56. }
  57. });
  58. return action;
  59. }

1.2 action 获取查询参数,查询数据,poi生成excel,下载excel

  1. //导出数据为Xlsx文件
        public void exportXlsx(ActionMapping mapping, ActionForm form, HttpServletRequest request,
                HttpServletResponse response) throws UnsupportedEncodingException{
            
            ////79个字段
            String[] head = new String[]{
                    "从业资格档案号码","姓名","民族","身份证号","性别","出生日期","政治面貌","全日制最高学历","全日制最高学历毕业学校","全日制最高学历毕业时间",
                    "全日制最高学历所学专业","全日制最高学位","非全日制最高学历","非全日制学历毕业学校","非全日制学历毕业时间","非全日制学历所学专业","非全日制最高学位","非全日制最高学位毕业学校","非全日制最高学位毕业时间","非全日制最高学位所学专业",
                    "单位代码","单位名称","具体下属单位","工作单位经济类型","单位分类","工作单位电话","单位地址","单位邮政编码","会计行政职务","行政级别",
                    "行政级别任职命令号","现任职务","参加工作时间","从事会计工作时间","现从事会计工作岗位","珠算等级","珠算证号","珠算证取得时间","电算级别","电算证号",
                    "电算证取得时间","继续教育成绩","本年学时","继续教育开始时间","首次从业资格证发证机关","会计从业资格证取得方式","资格证最初取得时间","发证单位","从业资格证发证日期","注册时间",
                    "是否在岗","会计专业技术资格","会计专业技术资格取得方式","会计专业技术资格取得时间","会计专业技术资格证号或批文号","会计专业技术职务","会计专业技术职务聘任时间","会计专业技术职务任职命令号","非会计专业技术资格级别","非会计专业技术资格类型",
                    "非会计专业技术资格取得时间","非会计专业技术资格证书号或批文号","非会计专业技术资格取得方式","注册会计师","资产评估师","注册税务师","其他资格","IC卡号","诚信记录档案","有效证件名称",
                    "有效证件号","籍贯","出生地","家庭住址","联系电话","电子邮箱","外语掌握情况","是否审核","是否委派"};
            
            //查询条件16个
            //name,gender,birth,fhighestDegree全日制,nhighestAcademic非全日制最高学位,whetherPost是否在岗,
            //stationId单位,note是否审核,note1是否委派,currentPosition现任职务
            //accountingQualification会计专业技术资格,technicalPosition会计专业技术职务,administrativeLevel行政级别
            //appointmentTime现任职务时间,unitClassification单位分类,jobPosition现从事会计工作岗位
            LinkedList<String> names = new LinkedList<String>();
            LinkedList<String> values = new LinkedList<String>();
            
            @SuppressWarnings("unchecked")
            Enumeration<String> nameEnum = request.getParameterNames();
            while (nameEnum.hasMoreElements()) {
                String name = (String) nameEnum.nextElement();
                String value = request.getParameter(name);
                if (value!=null&&!"".equals(value.trim())&&!"exportXlsx".equals(value)&&!"提交查询".equals(value)) {
                    Pattern pattern = Pattern.compile("([A-Z])");
                    Matcher matcher = pattern.matcher(name);
                    while(matcher.find()){
                        if(matcher.groupCount()>0){
                            name = matcher.replaceAll("_"+matcher.group(1).toLowerCase());
                        }
                    }
                    names.add(name);
                    value = URLDecoder.decode(value,"utf-8");
                    values.add(value);
                }
            }
            CwglPersonnelManager manager = ((CwglPersonnelManager) getEntityManager());
            List<Object[]> datas = manager.getAllData(names,values);
        //1.将数据转换为excel
            short validColNum = 79;
            
            XSSFWorkbook workbook = new XSSFWorkbook();
            XSSFSheet sheet = workbook.createSheet();
            
            //row:表名
            XSSFRow titlerow = sheet.createRow(0);
            XSSFCell titlecell = titlerow.createCell(0,XSSFCell.CELL_TYPE_STRING);
            titlecell.setCellValue("人员信息");//表名,表标题
                //标题样式
            XSSFCellStyle style = getNewCenterStyle(workbook,Color.gray,"title");
            CellRangeAddress region = new CellRangeAddress(0,(short)0,0,validColNum-1);//设置合并的行列
            
            sheet.addMergedRegion(region);//将单元格合并
            setRegionStyle(sheet,region,style);//设置合并单元格的风格(加边框)setRegionStyle是一个我写的方法
    //        setRegionBorder(XSSFCellStyle.BORDER_DASHED, region, sheet, workbook);
                //表头样式
            setAllRangeStyle(sheet,style);
            style = getNewCenterStyle(workbook, Color.LIGHT_GRAY, "header");
            //row:表头,
            XSSFRow headrow = sheet.createRow(1);
            for (int i = 0; i < head.length; i++) {
                XSSFCell headcell = headrow.createCell(i,XSSFCell.CELL_TYPE_STRING);
                headcell.setCellValue(head[i]);
                headcell.setCellStyle(style);
            }
                //内容数据样式
            style = getNewCenterStyle(workbook, new Color(192, 192, 192),"body");;
            //row:内容
            for (int i = 0; i < datas.size(); i++) {
                XSSFRow row = sheet.createRow(i+2);
                Object[] rowdata =  datas.get(i);//.values().toArray();
                for (int j = 0; j < validColNum; j++) {
                    XSSFCell cell = row.createCell(j,XSSFCell.CELL_TYPE_STRING);
                    cell.setCellValue(rowdata[j]==null?"":String.valueOf(rowdata[j]));
                    cell.setCellStyle(style);
                }
            }
            
            try  
            {   
                //保存excel到磁盘
                @SuppressWarnings("deprecation")
                String directory = request.getRealPath("/");
                File file = new File(directory+"\\cwgl\\module\\cwglpersonnel\\人员信息.xlsx");
                System.out.println(file.getAbsolutePath());
                FileOutputStream fout = new FileOutputStream(file);
                workbook.write(fout);  
                fout.close();  
                
                //下载excel
                downLoadFile(request,response, file.getAbsolutePath(), "xlsx");
            }catch (Exception e)  {  
                e.printStackTrace();  
            }  
        }
        
        
        /**
         * 获取excel边框,样式
         * @param workBook    
         * @param bgColor    背景色
         * @param type    类型:title标题,Header表头,body内容
         * @return
         */
        
        private static XSSFCellStyle getNewCenterStyle(XSSFWorkbook workBook,Color bgColor,String type){
              XSSFCellStyle style = workBook.createCellStyle();;
              style.setAlignment(XSSFCellStyle.ALIGN_CENTER);
              style.setWrapText(true);
              style.setVerticalAlignment(XSSFCellStyle.VERTICAL_CENTER);
              style.setBorderLeft(XSSFCellStyle.BORDER_THIN);
              style.setBorderRight(XSSFCellStyle.BORDER_THIN);
              style.setBorderTop(XSSFCellStyle.BORDER_THIN);
              style.setBorderBottom(XSSFCellStyle.BORDER_THIN);  
              //字体
              XSSFFont font = workBook.createFont();   
              if ("title".equals(type)) {
                  font.setFontName("黑体");
                  font.setColor(new XSSFColor(Color.green));//字体颜色
                  font.setFontHeight(60);
                  font.setBoldweight(XSSFFont.BOLDWEIGHT_BOLD);//粗体显示    
                  font.setFontHeightInPoints((short) 22);
              }else if ("header".equals(type)) {
                  font.setFontName("宋体");
                  font.setColor(new XSSFColor(Color.red));
                  font.setFontHeightInPoints((short) 12);
                  //设置单元格边框颜色
                  XSSFColor borderColor = new XSSFColor(Color.red);
                  style.setTopBorderColor(borderColor);
                  style.setBottomBorderColor(borderColor);
                  style.setLeftBorderColor(borderColor);
                  style.setRightBorderColor(borderColor);
                  //设置单元格背景色
                  style.setFillPattern(XSSFCellStyle.SOLID_FOREGROUND);
                  style.setFillBackgroundColor(new XSSFColor(bgColor));// 设置背景色,好像不起作用
                  style.setFillForegroundColor(new XSSFColor(bgColor));// 设置前景色
              }else if ("body".equals(type)) {
                  font.setFontName("仿宋_GB2312");    
                  font.setFontHeightInPoints((short) 9);   //字体大小
              }
              style.setFont(font);
          return style;
         }
        
        /**
         * 设置合并区域样式
         * 设置excel边框,样式
         * @param sheet    sheet
         * @param range    合并区域
         * @param cs    样式
         */
        private void setRegionStyle(XSSFSheet sheet, CellRangeAddress range , XSSFCellStyle cs) {
            for (int i = range.getFirstRow(); i <= range.getLastRow(); i ++) {
                XSSFRow row = sheet.getRow(i);
                if(range.getFirstColumn()!=range.getLastColumn()){
                    for (int j = range.getFirstColumn(); j <= range.getLastColumn(); j++) {
                        XSSFCell cell = row.getCell((short)j);
                        if( cell==null){  
                            cell=row.createCell(j);  
                            cell.setCellValue("");  
                        }
                        cell.setCellStyle(cs);
                    }
                }
            }
        }
        
        /**
         * 一次性设置所有合并区域
         * @param sheet        工作薄
         * @param style        样式
         */
        private void setAllRangeStyle(XSSFSheet sheet , XSSFCellStyle style){
            int num = sheet.getNumMergedRegions();
            for (int i = 0; i < num; i++) {
                CellRangeAddress range = sheet.getMergedRegion(i);
                setRegionStyle(sheet, range, style);
            }
        }
        
        /**
         * excel 下载
         * @param response            response
         * @param fileFullName        文件名包括路径
         * @param fileType            文件类型:pdf,xls或xlsx,doc或docx
         * @return
         * @throws Exception
         */
        public static boolean downLoadFile(HttpServletRequest request,HttpServletResponse response, String fileFullName, String fileType)
                throws Exception {
                File file = new File(fileFullName);  //根据文件路径获得File文件
                //设置文件类型(这样设置就不止是下Excel文件了,一举多得)
                if("pdf".equals(fileType)){
                   response.setContentType("application/pdf;charset=GBK");
                }else if("xls".equals(fileType)||"xlsx".equals(fileType)){
                   response.setContentType("application/msexcel;charset=GBK");
                }else if("doc".equals(fileType)||"docx".equals(fileType)){
                   response.setContentType("application/msword;charset=GBK");
                }
  2.  
  3.             //文件名
                String fileName = fileFullName.substring(fileFullName.lastIndexOf("\\"));
                String userAgent = request.getHeader("User-Agent");
                //针对IE或者以IE为内核的浏览器:
                if (userAgent.contains("MSIE")||userAgent.contains("Trident")) {
                  fileName = java.net.URLEncoder.encode(fileName, "UTF-8");
                } else {
                  //非IE浏览器的处理:
                  fileName = new String(fileName.getBytes("UTF-8"),"ISO-8859-1");
                }
                response.setHeader("Content-Disposition", "attachment;filename=\""+ fileName + "\"");
                response.setContentLength((int) file.length());
                BufferedOutputStream output = null;
                BufferedInputStream input = null;
                try {
                  output = new BufferedOutputStream(response.getOutputStream());
                  InputStream fis = new BufferedInputStream(new FileInputStream(file));  
                  byte[] buffer = new byte[fis.available()];  
                  fis.read(buffer);  
                  fis.close();
                  output.write(buffer);
                  output.flush();   //不可少
                  output.close();
                  response.flushBuffer();//不可少
                } catch (Exception e) {
                    e.printStackTrace();
                } finally {
                   //关闭流,不可少
                   if (input != null)
                        input.close();
                   if (output != null)
                        output.close();
                }
  4.  
  5.            return false;
            }
        /**
         * 利用poi自带工具RegionUtil来设置边框
         * @param border
         * @param region
         * @param sheet
         * @param wb
         */
        private static void setRegionBorder(int border, CellRangeAddress region, Sheet sheet,Workbook wb){  
            RegionUtil.setBorderBottom(border,region, sheet, wb);  
            RegionUtil.setBorderLeft(border,region, sheet, wb);  
            RegionUtil.setBorderRight(border,region, sheet, wb);  
            RegionUtil.setBorderTop(border,region, sheet, wb);  
          
        }
    }

    1.3 manager 数据接口

  1. /**
  2. * 查询所有字段,根据参数
  3. * @param names names条件字段
  4. * @param values values条件值
  5. * @return
  6. */
  7. public List<Object[]> getAllData(LinkedList<String> names,LinkedList<String> values){
  8. StringBuffer sb = new StringBuffer();
  9. //79个字段
  10. sb.append(" select "+
  11. "t.file_num,t.name,t.nation,t.id_num,t.gender,t.birth,t.political_outlook,t.fhighest_degree,t.fgraduation_school,t.fgraduation_time,"+
  12. "t.fschool_major,t.fhighest_academic,t.nhighest_degree,t.ngraduation_school,t.ngraduation_time,t.nschool_major,t.nhighest_academic,t.nzgraduation_school,t.nzgraduation_time,t.nzschool_major,"+
  13. "t.station_id,t.station_name,t.subordinate_unit,t.economic_type,t.unit_classification,t.telephone,t.address,t.post,t.administrative,t.administrative_level,"+
  14. "t.command_number,t.current_position,t.work_time,t.accounting_time,t.job_position,t.abacus_level,t.abacus_no,t.abacus_time,t.power_level,t.power_num,"+
  15. "t.power_time,t.continuing_education,t.hours_year,t.continuing_time,t.issuing_authority,t.get_way,t.get_time,t.issuing_unit,t.issuing_time,t.registration_time,"+
  16. "t.whether_post,t.accounting_qualification,t.qualification_way,t.qualification_time,t.qualification_num,t.technical_position,t.appointment_time,t.post_number,t.nqualification_level,t.nqualification_type,"+
  17. "t.nqualification_gettime,t.npermit_no,t.nqualification_way,t.registered,t.assessment_division,t.tax_division,t.other_qualifications,t.ic,t.integrity_record,t.certificate_name,"+
  18. "t.certificate_num,t.place_origin,t.place_birth,t.home_address,t.personal_phone,t.electronic_mail,t.foreign_language,t.note,t.note1 "+
  19. "from CWGL_PERSONNEL t "+
  20. "where 1=1 "
  21. );
  22. for (int i = 0; i < names.size(); i++) {
  23. String name = names.get(i);
  24. if ("birth".equals(name)||"appointmentTime".equals(name)) {
  25. sb.append(" and to_char(to_date("+name+",'yyyy-MM-dd'),'yyyy-MM') = ").append("'"+ values.get(i) +"'");
  26. }else{
  27. sb.append(" and "+name+" = '").append(values.get(i)).append("'");
  28. }
  29. }
  30. String wheresql = sb.toString();
  31. Session session = getExtDao().openSession();
  32. Query query = session.createSQLQuery(wheresql);
  33. @SuppressWarnings("unchecked")
  34. List<Object[]> list = query.list();
  35. return list;
  36. }

2.excel上传和下载完整代码  

  先上图:看着效果挺不错^_^

  aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAABPwAAADqCAYAAAA2/VtjAAAgAElEQVR4nO3dW4wlx3nY8TqzQ655jUjZutAyzFgkF5FEELbhQJ4NEAeWBCwFCIIvRJA80C9aAjECEgb4YICGYYmAHvRCInAArvwiBAkC2Q+yAXEfaAjOw460fhCgyyhecuHIZqSIunGoG7nc3Tk5dc72THVN1VdVfa3q/v8Wgz2XPt3V3+lzuvs7X1UvlisK2fja1/63uuuufzF2M0Z15cqV9f8nT54ctR2vvvqaevDBfzVqGwAAAAAAAFJtj90AwDZ2og8AAAAAAKBkW2M3AAAAAAAAAEB3Fl/96jfo0puZuXfpzYXu0gsAAAAAAFCaxcsvf4uEHwAAAAAAADARdOkFAAAAAAAAJmT7jjtuC0507do1tb3N9T18Dg4O1NYWuVMf4iMjPjLiIyM+MuIjIz4y4iMjPjLiIyM+Mh2fV974p7Gbka3lwVLdc/uvjN2MbPH5khEfGfGRlRSfqFbqFYLf9evXx25C1oiPjPjIiI+M+MiIj4z4yIiPjPjIiI+M+MiIj0wn/ODH9iMjPjLiIyspPiT8OlDSGz4G4iMjPjLiIyM+MuIjIz4y4iMjPjLiIyM+MuIj4/RUxvYjIz4y4iMrKT5RCb+SVmgMxEdGfGTER0Z8ZMRHRnxkxEdGfGTER0Z8ZMRHRnxkVPjJ2H5kxEdGfGQlxYcKvw6U9IaPgfjIiI+M+MiIj4z4yIiPjPjIiI+M+MiIj4z4yJbXSfhJ2H5kxEdGfGQlxcd5JY4vfelL6v3vf//h/dwSfh/72MfUpz/96bGbcSiHN1zHxCWHOOUQn4orTmPHKIf45BiXSq7x0XKIEfGR5RCfih0n4rNhxkXHxL4/phzio+X6HZ1LfLQcY5RDfPh8yXKKh20dn5Gvmfgf/vuvHd7+H//xy8fuj2mZwekpn684OcWlkkN8OH6Ow/bjFnvcs9jf36/9PKKTfZqZ8Hv11VfVXXfd1XUbG8st4ff9739f/fzP//zYzXDGJYdYER9ZrvHJITZarvHxPTY04iPLNT45xEYjPrJc4lPJJS6V3OKj5RSjXOLD50uWSzxsOj5Xb/3x2M04TPKZCb+xk33a669dVb/yzgfGbsbhSXe1DeWyPeX6+SI+dRw/y9h+ZDHxqXXprZJ9thwymJVqJXwZ8THkFJ8c5RCfXL4cXHKIj0sun7Mc42Mf3I2J+MhyiA/fP+UiPjLiI8sxPjl9H+UYn5wQHxldemU5bD+u7xvOL8qQQ3zYfrpxmPDzJfu03Lr05ibXNzyXg7pc46MRn/wRHxnxkeUanxy+e7Rc45ML4iMjPrLc4pPLcWElt/jkhvjIcujSW8klCWFi+5ERHxnxkZUUn/XIEFKyTyPhJ8vpDaePe3mIjyyn+OR2MKcRH1lO8clRTvFh+ykP8ZHlFB8+X+XR8Rl5CL+scZVeGZ8vWU7xYYzn8uQUn1D+ZzuU7NNyWqEc5RSfHPu45xSfHBEfWU7xMcdnyQXxkeUUnxzlFB97/5WDnOKTI+Ijyyk+VCCVJ6eEXzV+n33hjjEd0KVXxOdLllN8cjhft+UUnxzlFJ9q/+7bjracj1pyqfCrDlTs/8eW0xtuyuXgLtf45IL4yIiPjPjIcoyP/l6u/saWY3xyQnxkxEeWW3xyOS6s5Baf3BAfWW4Vfny+ykJ8ZMRHllt8pO+fohJ+ml6Z6i8Xub3huck5PjnsmHOOTw5yjA/fPzLiI6vik0OccoxPToiPjPjIiI+M+MiIjyynMfxyxPYjIz6ynOKTy4/kppziE1Jcwi9HJb3hY8ghPq6sN12eZcQnLIedT87xyUEO8cntV39TDvHJGfGRER9ZjvHJ6fsox/hUcohRzvHJQW4VfrnJYfvh/KtcOcTH7Kpa3Wb78fPt37ff//73B1+cwwqZ3XjNlcnhTc8hIerr5jx2bLQc4qPZH4IcYqPlEB/X9kN8jvD5kuX0fWzLIT4a3z9+7N/DzG2nuj12bLRc4pOrHOLD50uW2zBBphzi4xuvrxrPb0w5VPjZn6ecEuo5bD8axz9+OX0f23KIj8b24+fbfuz7i/39/eDPIy+++KJ64IEHemjmNOzt7an3vve9YzcjW8RHRnxkxEdGfGTER0Z8ZMRHlkN8Qge6Y8ohPjkjPjIdn7v/5a1jNyNbP/w/P2P7EfD5khEfWa7xyeVHz1zj4xJ18accMpgAAACALcdf/4G2/us3/7NS3xy7FXn78/d+YewmABgQ+/h0i6985StLndBbLpeHf+b96jYAAAAAoH/rhB9E/+ne/zJ2EwAga1FdenXJ4s7OzhDtAQAAAAAAALKzWCyKKYqLukovAAAAAAAAgDJEjeEHAAAMX/uaOjh3Ti339tTyjTc2jy0WSlW/9t10k1InT672sttqcdddaqEH9r3tNqW+/W21XE23eOc7lbr99s20P/mJ+/GK73npdanPpSzDfkyLvX/nnWr5j/+4uX/tmlqs4rNc/anVbXVwoBZ6OJETJ9RiFbt1JK9cWT9eWT+vb1TTXL+u1E9/uom7ns/WVn0aPf8b81jccst63ur11zfz1dPeccf6fVm+9ppa6CFM9Pull/dzP7d+/5avvqoWq+nUvfdu5qXbsPo7/H81nV4ntXq9Xs5i9bfU83/LW9TibW87etye9kYsvM938ZjdxldeWa+nWsVh/fiPfrQJ6uq5Kt7r9uvH9fvho+OsX1PNQ5q2L123IXZ+evt497vV1u//vlIPPthumQAAAD2jSy8AAAkOPvlJdfC5z23u6CSf/tOqZF913+R7TnpN09elPpeyDPuxlPv6tnk/pg1dtiWmfdJtm/2cvl2tl/2a0Dy7fsx+rmqbvc6mmK4p9jzG0HUbYudnxmt1e+sjH1Fbf/zH3bQBAAAUo6QuvVT4AQAQ6ytfUQd/8zfr6rBjfMkq6TnpNU1fl/pcyjLsx1Lu20m+mDZ02ZaY9oVuS/MLvSbl+S4eM5+LWZ/Qe9B02r503QZzfkZV6SEzabp6Xif9t06dUup3fqfbdgAAAHSEMfwAAIh0/TOfGbsJAPqiE312sq9KmNpVmqu/a5/61LriFwg5rxbGv2fV5bEbBACYBRJ+AIAZe6x2Ghb6d+n/fmHsBgPoi67cNf/s7uCOqsKDv/7rdeUvfJ5Vp9ffnuc9j2/+PdbR0uqJNXuZsaq2nV7d6sMD6r5e5gsAQB0JPwCYvcurk5qUtJf0b9qVCwtd4FONiWaP3SGN5eF7LjT+R5PXpT6XsozQOkv3fXGT2tBlW2LaJ922/7cfk14TmmfXj7nibt52TR/zlzJtX39dt8H1/rm4uvHfcPAXf1G7f7mWyur2nz8xdj7x54vUf82SX+fVE2p3fevhdeuPUnCPq6eM6c51tO+4X6WOOe6KW9Xm3dWtae/TAADTRsIPAGbvPvVAZ/MquXJhRz2jluK/B97179wJg0psss3sOkjST25Dl22JaZ90m6Rf2rQlJf1s5uPShVFWDv7+79XBn/zJ4f371Pu80w4j/F0W9++Z5PRZ3bPq6VqrnlRnjPtnavN/Qn2q1bJi2em9h9U5cfon1KOk/AAAhSLhBwDFelaoI2lelbCjXko6JXy+0/WI7YLVz7qHnPiDP9jc0AkAs8tfKFlVjQGmk3x6WvP1UgLKd6ELc7mu5I3r+Wq55pVbzemlJIhrWrN9oftmm+yY+dbfbrf0mIsrdq4LWJjtsm+bMTMfd62TuT34pnHNx/eYuWzpMdcy7OnttlX3zT+7O6vrL2Xavv66boMZR9fnIpDsqxz87d/Wkn5HnhG+Uc2E19nVd2n4+/a5YEvycVTdp51VTx37Ociu8nuscSfc5sJxvyD+jBVXV/lw7TUPR9dzDh8PAMCUkPADgAKdr3U7cnlC3d/b+ENd0t2ppPVwvWLEdX/oIbX1oQ/5nzeTeiY7Eee7aqqZyLJf61pWzNVt7eSQ73H7MVdCrVo/VyJNul9xJViq6e3EZah9dgxi4hHDFe+qPVUbq/c4VG0mtSciidQLc7m+hPFcueLhumKv57UHL7yQOJ7fN4zvsXPqcwmvbKPe5Tj2B5L3JVaCy9V9lTPqeXX28N459fCgKS6djH3O2S4AAKaAhB8AFOcxq1rArCA5azyuxx8atkJgR92fMPX59ZrI3als46/71ic+obY++EE5EafZSRS7WsycXkoqhBKArqo6zewyLHVdjOWr0PO1K9RVMlRt1wc72eW67XvOfMy+oIMrWWoncrXYRGE1T/P1oQSiaz1c25puu13x6XtvQ8nA0DYlPR8zP1dy0rwtxU+673q8UsWoIozd53LwV38VPe1l9fXD2zvr1NMY+hiGQY8La/4o84z6jHcpZ9STtY7DD6vTRXWhfa5BJXxMLeemnpNkJACgDRJ+AFAUfSJlpsh0wutx41TqOSvxdU49neXJk+6Sm5rs62Pd39NojCqd9Nv+9KfV1kfuVi/863118cGfqH+49/XNk2byxJc4ciVmYqv7fEkfO8lUJSrMpI6r+jCGvcwqmWjPz5dY9CUdXa+1u1f65hWzTJdQ0s+VQPUlI11dPn3z1LftCkdfpaId11AizhU337RmctmXBNNcSWgzYRlKvpnT2q+TprGToq72SsttmvSTxCSgb7yHy5df9kxwvOvn/UZKbHd1T+7eWU7nzsvqUfWEcf9s7Xv6uPvUhVpCbHddox2z3zp+wY37a7Xf9a6zZSUSAQBoj4QfABTl8+qzxj33idST6hnj3q56qfdWpXks0CXXJ7N1f/BBtfXH71IPP/sP6t98ek89+D+/qv7wi19UJ55+Wqm773a/JibhZSY8Yrv3+tiJI7MyzX6uupCI2QZzuXYixpyfnRyrbruqp8zHzSSVOa/qOV+VW2g6+7bZDru9UrIs1N26Dal7t2t8SFdFpO+21MXaVZ1oT+Oazn7M193avG8nne02mtVz1X3fulhx+NYDD6itX/1VtXXffWrr3ns3f/fcoxa/8AtqccstSt16q1q8/e1q8c53qsXq8/jm3dfUP91zVX3rbVfVj26/WS3183feon584/FrJ4T3N+Fzt/ilX4qedpqeVY/Wvt2fj6pcrHftrRKgqUnOZ2rf/3ovcfbYNM1+5JGFr3SfPoZfOQleAEC+SPgBQFG+URsE/aPOaeyr7r6YVNcQrjSRTmRSbK4kGX/Rj/7XvQuL3/5ttf3JTx5PPEljzelkWpXsMKvArl+vJ998iS2TqzLM9Xy1HPNCImbCyWa2T0rM1ILh6eLqSg7Fzst3304imokisw2+yrhQosnHThiGbvvmYd92vedm+2JvxyQGff/HzsfVNikx6Hpeuq9V292N5PMv/vM/q+Xrr68TdwdXr6qD1f2D73xHLX/wA7V84w2l9HPf+55a6sdefVXd/OpN6pe/c1L94vdPqjt/dk0tVtMsf/S6uuOH2+qX/9/Navu6J/GZmGTf+r3fi5hKupBHVxdE8l/YSKqCq1fEfSNxmfaYrPqCGLGdUs+o56yk36Zt0tAMZ6wOtar2o5Ba7SXM5+WLbwAAMD0k/ACgIOaYT9JUL7ZYRv9X6X3u8PTr8YRXDbHunXnoIaVuv/3ovp1wMpM5VbLP7m6pnThRr3zzJf9MrkSX5hsn0HXFVnt+scmvobjaEWq7/ZiZ8LTnacfarHw0KyFTu4Z2yZUk9N2WnrenkV4Ts0zfvHy3zcek+9X/1Xt35YpavviiWn71q0p9+9vKy5UUrt5LXxLYtS4Rtj7wgc1nvwdp46OOQVe5mcM06B90Useg0wm8l6wqvXPrtF9Md9zL6rOJleNPJPy8JV3c5L7VvqzrMfwYvQ8A0B4JPwAoyH3qfca9r3uSWy/V6jJ21IcnUdfQ/7rrC32k1Dbqf8IohHfeWb8vJROkSryKmaRyzcv1GlOVVJSWZScdXcmyHJJ+UrVcLLPCz5dAdMXZTBLZ3VDt5Kr9/vreMztJ23X34SlyVar6+BLlVfK2g1jrC/nosT3jxCWamldPa4+rC85EUj2hdlZIOV1Q74lclk723V8bt+/o+zS1a+omeWb/kLSpPJeSbpfV5xsMFAEAwJSR8AOAopjjD+2qzzpOfy6rp2tVFo9MIt2nTWTdXVVnrmop1zSucevsx83lpDATWL62VfONrYLyVb7FVIf55hWaLpZd1ej6q7qRui624er2bHY/dVVW2tVmTaV0I5aer9pkT5s6H3u97HmZy3Et04yP674rCWpX5lXvh5lsNRN69vthvr8tLd7xDrX18Y+3ns8wzB9FdqJTen6uZN+O8V0dM16dK9n5/Kql5mh7unuwdPGPT1ltqC/7Medr7K7VZ4Xn7GUfvwhLfPI2LSZcbAQA0BQJPwAoyofVI8Y9XfVQP5F5zBqf6ZHVK6ai73XfjCmY9u/4kPBevi69lZiuuvY8zORfandEO+lmJxBdY7eZ0+eW9EuteIzhinOoe3P1eJVoqhJKdjdVO5nli3kOFZW5kSogzQSeOe5f9Wcnb7W2FX4nTya+YIgx/Hw+Z/wooqvwpKq5GC9ZI/3p7qqPeKaNp7sw37euUXxmnfY7K3YPtq/gfty5w7EAv0EdIABgNkj4AUBRdHen+sDm54Qupu4r2ZaqwHW3EzdmdZEv8WfzVf+5uttqUpdc1zLNMQTt6sFYrmpDXwLOtz5Sws6V4KnaaY+n55tHDLv9UpIvNkb2e2bPy9Xt15UY9FXCuSrxpKo4+7ZrnUJdkM12+rp9m/Py3bbbZM7DVe1nL1/q/mw+Zl5wxr4C9ay4EmOb7sXuCrgY9oUzdFrO7k78jFWrF+5qfGQzL/lKv67qPs2sNDynnu60Uu4551rU16h+PeCzh7FI+3GJi40AAJoi4QcAxdmcYIWrP55RT0bNr36hi+Gu0ttE1+veo+3to9tSYs9OwlTdEE0p1XC+aj9znq6ER6hyzWRfpbd6vb0uvupAV3ulLp++hKDZbruSzl4nO4b2n9n109f2lCTfLbco9ba3KfX2m9UP77yqXr3jqvrZSaONrmVJyStXV1xzea5p7Ta5Ym8n1+z4hSpOU6pK7fn7XmuvT8zFakKq19vjYPaQAAxfYCh9DL9d9VIH7XrUSIzt1NJR5wbrOurrRlyvFHxfdJJLqu57avXvyK761Gpa8715oLdU2uVVNM2Kc30xrI+u31V9FWPfkBSn6cILAOgUCT8AKNQZsZpAVxBkUOHWkxLWffGud924YSVGfLer+1pViWRWr9m3fc9pvoSK2Z6K2QXSV80mJWl883cljlKrB83usXZyToqBK0bmY1WbTGbCsAm7su7KFaW++93V31V1949uUnf9aFvd+sZ197Lt+YQSba5l+hKFKZWboelcz9tJ1VDCMVTl53veXBd99WrX8lO4kp296C+plKY+5MFZdWFdOfdSbWTU0IUxmqlfPfd9q4i4vGik4uLHFrSTmGetqrozterCr9da0teVj13JPl2lZ7ZFJx/rlzM5en8270PqxU4AADiOhB8ATML51emDOTLRU+rx6NfWKyukqzYON85Uijbr3p8Tjz56lGTSXFVxrm6adpIj9c+ct7n8VKFqPTsZZ5OqEu152lVc1e1qGt9FM9rEyJVotW/HcCWyfBf0CM07NSHa5TxD0439vBnja9eOV+dJiT9f5WT1Otdns4WXnKPE+bqAxl411z+CXcimcsy8nNFLh11k9Th59R9MnliPjtpluqkej4+2WBObPW7rU47KbrN78WdqowvGVxHG0tWGC6tNJnMc2nPq4cMoP3ZsSAqlnl7NCwCAdkj4AcAE2FenfSbplMqsrDi7Oh0rS7t179FDDyn11rce70KomZVFZnLITky4un7G/NnJMFe1XtOujHb1lZksMefna4N9376SqrkOoSrBpgk/+8/V5TfE9Rq7ojD0Z1YqVq91VSWa981l25WMZjtcVZCueUjr1PQ53317u4tpg53Qq8acNK+eHJv4S9E4AVgfIqGvKrI459epJFe1mel40k8no053lHA6rz5n3PPH4xsRVYD1+T5WS5Lpq/iGvvu7vkKxaRNp91iCFT0OrVlx+PDqVXay7/nDkfty+OEKAFA2En4AULx6hduO+kzSiUK9u9V7Rj09Tddu3fu2uPfe+MSKq8LJTEY1+fMlAc3l2QmiVivsSJL4klSuZJ45vS8mUvKr6V8sXwKyYic57fUw19G3nq5twPzfTApXt6uksZ3ElZKt9vtht0PaPkPP+e77EsDmPEPzclVPmkl1X/sqUtLSTjI3Io9Fd/7GKG2hZFo1nlvzi2k8u5rDw1ZKzH8BiHrST/9w0k3Cyf5B5pGoqrqY/ZAez/XoIk7yVXwr5hWKY5KKMTZJ1XrSbsfqWGx6vDau4Lljyb5MfrACAEwCCT8AKFz9hOrs6mQipZvSZfX5WsLsw5mMNxWn3bpnwk4iab5x5lL4koXVc2YiyayWshNydrVYKDnoqyazkzzmlVOraey22/HpgyvxZCeIzKSYr1rN9ZxvHq4qTJvvMVeyzHzOnLe9LFeisfrflSx2xSrmOdcyXMu02x+KQejz4Eqa2hWQvnm0+azVfK6W4KpXkT1240Icu+oJMZl31FX1XOOk36Yr62bIhbPrVJJ8pdtN0q/b6rJn1aORwy2EL3TicnSF4NC6aedrybW2P25Vib6Hrc64z6/j95TnVTomTzsSgrrykmQfAKBrJPwAoGj1E6q4KgfT59VnD2/HVl/kou26a2Y3ss1JeNo/39Uhb3jzTf9zZkVRdb/SRbdEXwLFlUizKwLtC3m4qgM1V2Kwet5V0eVKMLmm9yX5fEnBNlwVhNW6mUm7ajozNq5xBF3P+R7zVcH5HnO13ZU0syvjXOsaqka0Y+Kbp+s5e/t1bWv2bXN6e/72bdf2Yc+3+t9OZoeWYZJi71FPKj2iPnx4W1fc1au5fEkqO/nV5gq6Z26kw4ZPJemE2BO1b2ipy219nL8+LnSiE21H2v+49aL1LumqSHmsxfOHV+nVW8ZRdaK2ux45EQCAbpHwA4CCna+dUD3jGLA85fXmyWn+2q77EJb7++GJfGP8tV64I4kRO1+7Wksa78+VtHFVB0pdQqV5Ve3uo8rPVc1XJfTMRJGdGEtJwnU9fZP5xTzfdJ6h5bmSgfb76euK65tf9b+U9KuWZW6LdkLZVynpq4QMsserq5JKOtlX/756SUgMVZV25gWRdEKoadJveOfXtYz17sRS0rHvcQ/1xTTqycf21eBHFZSb6jypKvLRG7WAld31WH/PWUm/c4c/JHV/pWQAwDxtj90AAEBTjxknELq64PHEUxjz9foUKPX1Wv0Et4lNBUqqtuvu0mTcKtfVFQ3Xr8fPyh6bLCXp5+qW6pvOrvKz/zeflyrcYqoQ7eSOr4rRTrpVVYVSd942CUDztWZXXbs9fXYlNrli4WqH9FxXy+9DSiLP1VU8lCD2bWN23Kqkn/mc/XpXLOw2uZKWyjdenf0doZN95vdVfcw/05n1NXxPH3bv3ST9jl9047hNtbJ8AYlUX18n5cKVgse/E88GutxeVo/W2tr11XPt+e+oJzureDwT0RF317pqrxkP3SX5o7VkoPaEdfkPxvYDADRDhR8AFKsavajJmEvx3cvqdKWE2aW1XsXR9YmaX5t1H4mZSJCSE+ZtXzdI1//2dOZyzYSaPZ6Z3a3WTLjZV0OVKsN8f75pYqv5uqh2tOcT0+ZqOleVX9d/drtct+1u1vZzXS1/iPXtI35S230xdI11GJq2mv5YEtI1Xp39PXuU7Dvv+Q612VfQ3V3dC6u6l7b994xw8QnbszcuMxKT7KvvR+6vxa3dleJfspJrl42EaTX//sd6rXcfrmwqAY/H48yNaD/veE3c1YcBAHAj4QcAs5M2tlLdfavTVd9JYJ7dakdXJQh8V0INJQBjk352F0VzufbzZvLCTuiZSZBY5vxdf65pqsfMBJ9d7ddHUmio13XRTt/t0HNjxCmHv1DbpRimxNv+u+kma4gBnXDT36m622fVbVNXaR1V9p2pdeY8et17HI8eXUxDHiNuPHaXZU26UIjejzzviIBOiHY73uB9NzreVsuSqvuaXTjE5cPqkdr9szcu5SEnGs8cvsdmbD6a5TsOACjDYn9/P9jPYm9vT+3sxP/GBwAogU78Pb06wSykQq4XZvezJl16ZdceWZ32vfzy0QOuscH0343HFzffrNSttx5Ne3Cglm+8sekavDhQ11engovlQi0XW+rEwnF1W8M6RXHTTZu/K1fU8tq1+IbbibeY6SXVOtrzN8d3c83D93hTTefXdTtSlue7HXquq+WXJtR2KYb2/dC0N2x98INq6xOfWN/eVJQ9FZGYq49zF+r2GmbOr/vvsjBdtbfpiNp+Xaagej/ojgsAU7NYHQ8sCzlOIuEHAEBPrv/RH6nlF7/on8B14YA+xmdLSd6ZbXPNK2Y6+zWuacz1JOHnXx4JvzQjJPy2n3tOqYceatlwAABQgpISfnTpBQCgJycefTScfPB1qTWfa/MnJel83W7t5+zp2rATnCT7/Msj2ZdmpOo+kn0AACBHXKUXAIC+PPTQOiFw8MILm/tNKu3assfJMx83/7cfNxNyNyxuu00t7rln001YdzV2dRNePbb8wQ82XZFd6ztGDIAebH3oQ2rr4x8fuxkAAABOi4sXLy4P9BhBqwN8qSzx9OnTAzarLDpqnL74ER8Z8ZERHxnxKcN/e/e71b9/61uPJ7uGSn7ZyT2zm+/qsW+9+aba18m71WM/vJHEu31rS/1kdXzwxurv5dXzn/ne99Tuj38cvcidO+5Qf/j2t6v33nqruslYz6ur+f1Qj0m4cvf29uFzvsebajq/rtuRsrwq5vZt3Q79Prmma9vGoddXcmL1d+uJE+rO1frp7jJXbqzjLav7J288dmz8Ry2mItJmvFYv559X2/h3rl5dP2TH295O915/Xf35K68kfR4AAMB0XLhwYewmRIkew+/qjYMgHPdvf+u31P/6u78buxnZIj4y4hlBfYsAAB47SURBVCMjPjLiU447vvlNdf9f/qW65XvfO3rQTK702UVTJ06sJJ/22v33q3/6wAfUj++9t5tlAT1625e/rN71hS8c/wxV3c2lcTCt7f/abbep/dX2/+3f/E22fwAAEE2ff5Uy/AldegEAGIBOKnz5ySfXib97dnfVra+8ok7u76sTr79en9C+mm0XHJWFr/zGb6jLv/u73cwfGMB3f+3X1n/6M/TOL31J3fzaa2q5va0ObrpJXb31VnVydf+mn/5UXddXu1458eabh7e3b3zOfvaOd5DkAwAAs0DCDwCAAelEwyUj2WAmALVrt9yy/t9OVixudC9sYnnixHq+OjFy5S1vUa/8+q+T8ECx9LbL9jsPsVXsMdNREQ8AmBsSfgAAjMhOAALAkNZdkxJVibM2r/W1pY+kXNVOkn4AgDkh4QcAAADMmCsJFpscS0mgpSYI9bybJOns5ZDkAwDMEQk/AAAAAIfaVsI1TdJ1mZgjyQcAmDsSfgAAAABqlXFDVslJyT5flZ/dvuo+iT4AADZI+AEAAABY83Xv7UtMZZ8r6WfeZmw+AACOI+EHAAAAoDFXQjCmQjAlURdb6Rd63NcWAACmhoQfAAAAgLUurrwbk8gzpwkts5pOuogHFYAAANSR8AMAAACw1rZLb5VcCyXZXMm5mAo+VyIvdpkAAMzJ1tgNAAAAADAtVQJu6GUCAIANKvwAAAAArLVJ0rm61fZVdUc1HwAAMhJ+AAAAAFqNe+ebPjbpl7o8kn0AAMjo0gsAAACg0RVvq+dJwAEAkBcSfgAAAMAM2VfK9SXtQuPxhZJ9XVf3DTUvAABKRpdeAAAAYMZiEn++rrltL8zhmydX3QUAoB0SfgAAAMDMmMm02AttxD4mLdPXBnueTZJ9JAgBADiyuHjx4vLg4EAtl8v1n8/Vq1cHbFZZOLiQER8Z8ZERH1nbygoAAAAAQLzdCxfGbkKU7VOnTgUn2tvbG6ApAIAmSIgCAErDD3oAgBLp/dfOzs7YzYjCRTsAAAAAAACACSHhBwAAitLFRQIAABiCtM9psz9iXwYghIt2AACAorS9emfq65ucVJlXPG36WgDAfLn2H00uZJOK/RcwHST8AABAtppWRnR90uGaX2zSsM1VTAEA5aq+06v/U39wMqdz7R/Mx3zzZP8FzBcJPwAAkLUuKhpiH0up+muTVOSCBQAwD31819v7kJRkG/svYD5I+AEAgCy5TmhCJxnSNDGvjWmTb3pOgAAAFWl/5NuXxOxHqvna/8e8znU7drkAykPCDwAAZMnXDUmafoiTltR2AQDmxUzGmar9hzlOnrTfkirRm4xny/4LmBcSfgAAIHuhSoncqxNiuhTnvg4AgDi+pFyT8ft8r0mt8GuK/RdQLhJ+AAAga3alRGo33z7ak8puYwlJSgBAt7r63jf3IU279cZi/wWUi4QfAADImqsLlP1cjK66LbXtEjVUVQYAYBz2PsG+Sq80bZOxan0/itnYfwHzQsIPKMRYO9ZQN4K28wGAGL4kX0ryr4uLdnSJkyYAmCapEj22St3uCly91pU0tOfbN/ZfQBlI+AGFaFOu76qKcc3ffD07cABji0nmNU3+heYV265UrhM/vnMBYH5SquVcz/v2f6FlNsX+CygPCT8gQ9LOODZp16brm2sHzoC9AIaWejIz9BV6u6p05qQJANA39l/A/JDwAzKVuuP0JeSa7oBdY4PEztt3Yh6brAQAF+l7YqjuuE2HOeCECADmzXe13qGSZuy/gPkh4QdkxlVZF/pFrq8dcdMTaK7mBSAnbb6DfCdottAJW9vxBQEA5Wp7LBxzQQ5pmey/gHki4QdkxnfVrSZX3GrTHc4cV6SN2IMNAAgZ+qIa9rJD32W+7+sx2w0AGF/ox3t7/1HtN5r0qHFNx/4LmCcSfsBE2Tvu2Ko76RdEe6cfGh+QBB+ALjXp0ttVdV/sQOWxj0nLBABMR+zYeea+JWa/If2wz/4LgLa4ePHi8uDgQC2Xy/Wfz9WrVwdsVllIasiIjyz0y12T7rExv+SlXPG3ydgiXXU9ZvuRcXAFAAAAAMPZvXBh7CZE2T516lRwor29vQGaAsDW9SC+TZJwbQYUjrmyr7kMNEP80BQJdRnxkREfGfGRER8Z8ZERHxnxkREfGfGR6fjs7OyM3YwodOkFZs43ZohP7JV26eILAAAAAMA4skv4kRCo6+Iy6TFXec1VKPnUxbhMfb6miZiqOF9cUq/uG5qH/doct522XZabTt/V67tqP44QOwAAAABzl13CLzWpkHrl0dJI8Wh6Uptr4sYlZWy7JtPkKCbBG7NuKe9zaDuTpku9GnBsheDQhvxckOTrT8xV7QAAAABg6kZN+Ekn/jEVTNJjMcsoRUySZU66SGKVyL7aVmzSz35tyvLMZZnzlBKPbStSY9sVesz1eEy35SESknymu+V7nwEAAABgrkav8OPEzC/UjdNOwvjm0fYS6zkZqjIqNoFk6jOmvsRam266vmnMRJ+vHXYScEixFx2JvRhJLHN9u9g+YhKlJLLihCpMuVAMAAAAgLkZPeFnyrWr35hikhsxiZfSuj7HJDpiurc2XafUK9n2RUq+VY93PVZdbPLYVS03ZIzM5GPM4/bzvvuux33rHpqHb/nSY1T/9SOl2zkAAAAAlC6rhF/Tyi1O3tzGSsR0wT4591VXDZEIkRI/fS5T66PrctOuzl0nVduKHXewmtZ1O5QsDiUP7Xk06Wad8wVRShCTQAUAAACAuckq4VdJvTDBlKWMV9ZmGbnH0ZVQaZLsSTVWbNom47r+3HQ5dl2fUipgu7jwSdPto20XbRzJpRoXAAAAAHKSZcIv5iS7zbxL0rRLr5k0lV6bu9gKLPtx8/V9LBvjsS9eYj8eW3GXUhEZakeK2G2a7S8d1d4AAAAAsJFFwi9lAHxpzC5sTDEeri69TdcxJaHCBQDy40vqmUnA2G2k7diWTbaPUJdivt/aI2YAAAAA5i6LhF/s2H1SJdtUNenSm1IRl3P8XJVcrosn9LUOTceULE3Tq9zmyE70xVz0xH59m8q/JklkxpvrBmMijqvriwe1mQ/vPWxsE/PW9v3Pffspff1yPA7tctljxxflYttBF7JI+MVo08W31A9Kbjs/TEeOB1cpXBe+MB93Ted6fgy+5LVr7MlS3g+g7fbq24+z/c9TSvf8mG2E79N5m/r7P+T6hY5dXEI/ypTw/tC7B7Fii5bYfjCUYhJ+TcfhYkynMtldNu3nKlVXztCBgqvqx/e60DYjPV/Kl3dp1Z4mV0Wcb1uxp+t6+anPx4wtiHQxXaPRvzYx76pKjwrP6YjZJjjGg03aJqZw/Db2+rm+X6VjSV+iI/a4PSepiU7Mk2/7Tt1+qmn4QRRtjZbwy/GLPBdDJZxyfQ9SDiTMabqqWivtAKSpmASJq+psbKnJva4PyrraPlzjELqen9I214fY+HBw3p0msexj38RnA5ImY6xiGlLfU3O78H2/5ZQsnNL6SW3LqXcGMCRp2+fYB6mKqfCbkz4TTiV8QTRtY6gK1Pdry9y+OEMnQSVX/5Uix67GpYqNHb/Md0caXqPttty2W3CoghvzQi+QeYk9dpF+cOuq2rgPuaxf6AfimGMbu4dGm/Z0pYuEY2pCNZdtC91qcxxjvp7zMXRhlISftLF2ecLAh2Ijpfw/13g1fS9julDObVuxYzK1z0tKmXzKc13HxtypSzv0Kb03Y6G7bz6kk8LUCln7Pj/oTEtshR5QiT0xNr8bYn9kz+G7JOf1yylOTXWRWEmpyOL7bB6k4xPzvvl/aDogxSgJv9AvPl3sdEre4XRtCnFo857GvG5u28yUT45dvxaHphmS6xfjUOJ1Ku8NIP1qbf7ve51LzIlvaB7IT0zlDyfMcOniuC/nfe5Y69c28VBSkQGQyrV9h45PYubl66GS6+cH+dm+dOmSOjg4UMvlcv2Xgy424Kl+CLoouy9V03WJfV3MdFOIZ+yvwjkf7GqutsU+1pc225Dv172YeXNwWkc8+pfSbSn2c+GrNvFV88V2fcn5ewxA99oe95V4/JMyXRe9Zuz5Sfdd7ZF+5Mnlh9rctwPkxbV92xV6Ma+xH28zPfq1u7s7dhOibJ86dSo40d7e3gBNATCEUJeFmKoK5IX3x4/tV9YmOTpGBRbvJ1KQ/J+vmPc+9Ye0XBJRWk7r1+YHydyOOac63A3G49uOpIrXtp9vDGNnZ2fsJkThoh3AzEi/xLLzAJAzvqPmo4sx/ELbCwnB6WqTSEoZh20sua1fF8nQKSbZprQu6E5st3zf9Oy7kGJr7AYAGJbZxa267esKy4HKdEzh4KCPdYjtihT7+qbz6VNObfEp9bum7fYDP3P/5NpnMfxLd98/bLfoQlefzVA3yL7E9HqZEr4/hjPWNp0ztr/hUOEHzFCpJ9dorkkCt2mXgiY73zltj23iM6VuHr6Laczh+0kao9AndXrXa+02NHkdpocf+DZCn4nYsbhy1fX6dXmibW9/Y2yTTZflayefqePmtv/ydeWNaRs/KMZh/xVGwg+YKd8A+fbzfImWRzooiBlMO+bxJvOqXtNke+pjewzNy5WQCnUz7GK8I+n5UpJj0glQRfr+KUGT7adib8sp72uXn682Y29hHLEngb7vpSb7B3seU9XHvisnXa6fuU82H2tiCrEtQcowCdL4cm3Maf/VNok9xS697L/GQcIPmCG7UmTuX4RTM7X3006MdHFyEHPQ4EvU+Npmv76vA2Zp2THPDcH3PtmPuw5i2ySEh9J0+4md99Q+wym6+nxPNYYxn5fUHw5CSj25RH/adH21f8Br8uPGkJp8n7Sp7OpLbHvGbudUUEhxHPuvcZDwA2bKPCmVTrrnvnMqXU4HdF0dNLfdJu3KhFBirsmyfEnAmHbF6CpR1lSbSkb7F++KKxGY43dPm+0nVNXnuu2aVmrXHMxpXbvU1XdwzrqscM9RDuvX5vvIdXzZ1TKHJLXdt+7mPi2Hz1XTKvKUx5se05TOVZXm2u5TYj33xNUc9l99IeEHzIxrJxM6CMnl4ATpSn3vQgdDsQdMrvlKlQmxiTnXfV+su47/FD+jbbq+DLnebbef0Hr5TpDnIjY2UhxL/hw0kbJ9NPluKi2WpbU3VU7rF/q8hr4vXfdz0+T7OlSdNOZ3VNP9ie+Hqmqec993ucT0FknpUeKad+nYfw2DhB8wM6EDlya/+KEsqZVkXS0zZvn2wY+0/JgDJt9rpOdjkjYxz4W6K5lS45NaWTCENstNPdg1nx/yO6uL7UfS9LWx209Xy+tLynvGvmqjzxPtuSVPJVOPQ5P1m/LJdmj/Enpd22n6lJo46Xs/MZX9l63NtjDlz5aJ/dcwSPgBwASFugK4dqh9/fJud4GUfuFu0oam7Wx6oNV1t6k28XF17cUw2h6ox1S/VNNJUrYfaVkcHKPSpHoaQN5y7BLJ/gtdY/91HAk/AJioHHZ2MWPZjCUmOdak8iy1DV3GJ4f3fC6abj9t52lPn+vnC8Poowqb7QaYHqnnhO9H4CGSfa7lsv+aB/ZfwyDhBwCoCVX/xVQHVtO1Gcumj4RKyutjD4qbtif3sX5CuhyvsKvXDR2vpt2gQhWc5vNNu2/HfL5y3ba00PaV2vUr53Vto22XKKoh0EbKd8yUP4clidlvx36H9LXPn+L+S3q8i3mXiP3XMEj4AQCOSUnw+RJjsd1xUwfFlpbbRpfdSMxuKm0O+lzzkLpnl3rQk3tyM0ZM+2PGpIx5vKvPV0z7Sn5PEDa197fJfqHpSWeOsWuz/n2vcwnf83PffobA/svPtw5TPO7rwpzXPQUJPwBAp3I/oG+rbWVb2/jkXjFhH5iGksPSa33zSW1PLjFKrdrrsooypX3IU0rVsfQ5TF1mSdtF6EeilHUZ8genrrRZ/yG/a3I1t+2nzXuc25iAU9lWXcdMvh9/S1pn9l/jIeEHAOjMXMedMw/Guu6G0iQ+Y8Q0pltQTLVabIxiK+py3r5CXVTt7amr7SdmW81JqJ2xXaB9SoiBVko7Ub62+7HQsAWYn7nuvyqp7bWnjz3OzFVp7Z0SEn4AMDFjHgiUtEP3JZmkMUGa/MJvvqaP+HT1S2iTZZkHn65p21RLtN2O+/4cNNl+fELd2qvnu16f3E4cfN2WfNtYNY19UiQ9PyV9jhM1NXOPSZsq9LZVYCElvC9T3H66ru5LrSBtq5T9lxb6QSqlGrS6X3q3XvZfwyHhBwA4pk3XyyHb0dX8XQmD0HOhaqw+pIxR00dbXCeBrgq0LpJ50nxits8hDhhTtx/7tXYieIiqGF/VQPWczxDxlJIMrqRfauXflE4iYpPEEimRinnqYt9WeiJiDqSEXdP99xAVaKXuv1ITpH3/UDw29l/DIuEHABPS1UGWfaCS+nxXUn71jBV7MpKa3Is5CG4rZV59H3Sby0lZZkqbmqzDkEnXNtuP7zV9tn9q3ez6rBDNWduEuT3d1Jmf2aaJq5LFrn8ocdL1Z6qUz+jUtp82xyoxVXxDJfvMZeasSRLU9WOqNG1J2H8Nj4QfAExI18m+Jvdj59t2+qbr2lU7UuIQm6Br05620zbhS3qGfr1tc99cRsz8u9b1dtx2+pTXlXhwLL3fc+0S1Nd37hTZ20/TE8lSt6mU9Q+tc0wCy/V5LTV22hS3nzbHKn3tZ6a6/9K6ardvX1ca9l/DI+EHAACi2Uk9V5LPPkFyzSNGyklTiQe+kLm2MZN08u1LENo4qZiuIaquc9b1+oemn1pM5779IJ2d6Nba/IgXW+UHSEj4AQCAxnwnP/ZBqvm81N1VelxK9klVfyhLSjWNa5o5Vv2hrm3Xw9K3lzG6XkpV3bFDYORi7tsPmvNVxfp+IG0yX9f8AR8SfgCARlIHIZ6j0k5yQqT3vEkX2y5OBEuPKY7Yib7qdgjvP0x9jXNaSoVom/W31zF2zNIpmfv2gzyR3ENTJPwAABhI6V2BQlV3rmRgzDy7/tXbVnLM56TtexTa3qY08Dnc+vysl7CNtF3/Kf1A1cTctx/0K+Y4xzdMiv08EIuEHwCgU65xtgBJ6YlQ9C+m+1zMSRSmq8tuciV+J/X1g0kXrzHlGte5bz/oX+yFzUJj93GcjRQk/AAAnfB195yr1HHo5qppN04AMHX9vVFa0qaPdnaVWCghhnPfftAN33Gv68JmUtLPddueDxCDhB8AIJprfB/f+G0clGzEdmudgpQEb+hiHvZzMbhwR/kYGxRjcl0ApvpOmXqX8JQx5mI+k1K8plqhNOftBxuuMTF9FzZj34YhkPADAERzjSNidz3gIGaeA51roQrP2Li4urLExnFO8Z4i33eKbzqgK3Ovyk7Zd8dMO5e4Vea+/eD4e53afRfoAwk/AEAyXyKGg5c0JcfKdWDbZJqUZbSZF8ohdWfyTZcyT8xPbBJrqvr4wWRO389z337QXGi7iN3fpUwDmLbGbgAAoFwpXXzngrEMAQAAAIyNhB8AIIlr4GHf43NLdJVcsQcAAABgOkj4AQBa8XXj1ffnlvgLjdNiIjkIAAAAoC+M4QcAiCZdQdOX1COpBQAAAADDIuEHAIgWujADY9cBAAAAwPjo0gsAwMDozgsAAACgTyT8AAAYAAk+AAAAAEOhSy8AoDN04a2T4mE/R0IQAAAAQFdI+AEAOsMYfnUk8QAAAACMYXHx4sXlwcGBWi6X6z+f06dPD9issuioLcZuRMaIj4z4yIiPjPjIiI+M+MiIj4z4yIiPjPjIiI+M+MiIj4z4yIiPTMdn98KFsZsRZbG/v+/P8t2wt7enTr9QT/gt/zT4stlYLBZisnTuiI9s8WfHv075fB0hPjI+XzK2HxnxkfH5khEfGZ8vGfGR8fmSER8Z8ZERHxnxkZUUn0YX7WBnDPSHz5eM+KANth8Z8QH6w+dLRnwAAOhWcsKPnTHQHz5fMuKDNth+ZMQH6A+fLxnxAQCge0kJP3bGQH/4fMmID9pg+5ERH6A/fL5kxAcAgH5EX6WXnTHQHz5fMuKDNth+ZMQnX3qMmJBSxpCZKz5fMuIDAEB/oi/asbOzM0R7ouQ2SGJu7ckN8ZHlFB/z5DKnNuXSlkpObcqpLTnKJT6uxE0u7cqhHZUqTrm0aez4hJafe/vmbsz4SPvzXPb1OW0/ucTElFN8ckR8ZMRHRnxkxEdWUnyiK/xyEfNrN4B09hdXSV9kQAn4PMnM7xy+f4DmpP05+/rjiAkAYKoaXaV3TOyAgX7w2YrDjw5A9+wTbL6PAAAAgHaKq/ADgLFUSQmSfmgixy5jucmtS28O+L4BAABAEyT8ANRwwg30gy5jMrr0uoXG8ANs9g9TdvUsPz7UERMAwFSR8ANQwwm3G/FAG2w7YcQI6AZj+KUhJgCAqSpuDD8AGIs+CaiqAKisQQq2FwAAAABDIuEHYI2EhEz/2l/9VfcBAAAAAMhRcV16zeoaTriB7jCGTRy+g9AEny8Z8fHjxxikYgy/NMQEADBVxSX82AkD/eHzFUaM0BTbjoz4uHHRDjQhbTd81o4jJgCAKaJLLwAAQIZCSQiSFAAAAPAh4QcAAAAAAABMyPalS5fUwcFBbTB6F7qNyIiPjPjIiI+M+MiIj4z4yIiPjPjIiI+M+MiIj4z4yIiPjPjIiI+M+Mh2d3fHbkKUxf7+frA/yN7enjr9wunaY8s/pRtJZfFnxz8MxOcI8ZERHxnxkREfGfGRcfEZGfGRER8Z8ZERHxnxkREfGfGRER8Z8ZGVFJ9GXXo5WZIRHxnxkREfGfGRER8Z8QEAAAAwB8kJP06WZMRHRnxkxEdGfGTER0Z8AAAAAMxFUsKPkyUZ8ZERHxnxkREfGfGRER8AAAAAcxKd8ONkSUZ8ZMRHRnxkxEdGfGTEBwAAAMDcRF+0Y2dnZ4j2RMltkMSc2mNeTSenNuXUlkpObcqlLZWc2pRLW1xXqsqlXTm0o1LFKZc25RIftp8yER8Z8ZERHxnxkREfGfGRER8Z8ZERH1lJ8dkeuwGpuDy0n73hlbQhDoH4oC22F5n5meLzdZz9/QMAAAAAfWl0ld4xcQKJpth24pCIQBN2go/PWx0/NgAAAAAYUnEJP/hxAom2SETIdHyqP7gRHwAAAAAYX3FdehGHxI1fbmOMoRxUacno0gsAAAAAeaDCb4I40Zbp2Og/qpDq2G5kxCaMGIXxOQMAAAAwBBJ+E8PJJNowu2OSEK0jHgAAAACAUpDwmxDXVWhxhHjIqsrHahsicQwAAAAAQJmKG8PPrD4iIXEcSS0/uxsv248bnzE3th8Z8QEAAACAfBSX8OMk0o/YhBGjMGLkR2xkxCeMGAEAAAAYAl16AQAAAAAAgAkh4QcAAAAAAABMyPalS5fUwcFBbbB+F8aGkxEfGfGRER8Z8ZERHxnxkREfGfGRER8Z8ZERHxnxkREfGfGRER8Z8ZHt7u6O3YQoi/39/eCAQnt7e2pnZ2eI9hSJixvIiI+M+MiIj4z4yIiPjPjIiI+M+MiIj4z4yIiPjPjIiI+M+MiIj6yk+NClFwAAAAAAAJgQEn4AAAAAAADAhJDwAwAAAAAAACaEhB8AAAAAAAAwIST8AAAAAAAAgAkh4QcAAAAAAABMCAk/AAAAAAAAYEJI+AEAAAAAAAATQsIPAAAAAAAAmBASfgAAAAAAAMCEkPADAAAAAAAAJoSEHwAAAAAAADAhJPwAAAAAAACACSHhBwAAAAAAAEwICT8AAAAAAABgQkj4AQAAAAAAABOyfenSJXVwcKCWy+X6z2exWAzYrPIQHxnxkREfGfGRER8Z8ZERHxnxkREfGfGRER8Z8ZERHxnxkREfGfGR7e7ujt2EKNunTp0KTrS3tycmA+dOv9k7OztjNyNbxEdGfGTER0Z8ZMRHRnxkxEdGfGTER0Z8ZMRHRnxkxEdGfGTER1ZSfOjSCwAAAAAAAEwICT8AAAAAAABgQkj4AQAAAAAAABNCwg8AAAAAAACYEBJ+AAAAAAAAwISQ8AMAAAAAAAAmhIQfAAAAAAAAMCEk/AAAAAAAAIAJIeEHAAAAAAAATAgJPwAAAAAAAGBCSPgBAAAAAAAAE0LCDwAAAAAAAJgQEn4AAAAAAADAhJDwAwAAAAAAACaEhB8AAAAAAAAwIST8AAAAAAAAgAlZXLx4cXlwcKCWy+X6DwAAAAAAAEC5Fvv7+8Es397entrZ2RmiPUXa3d0lPgLiIyM+MuIjIz4y4iMjPjLiIyM+MuIjIz4y4iMjPjLiIyM+MuIjKyk+dOkFAAAAAAAAJoSEHwAAAAAAADAhJPwAAAAAAACACSHhBwAAAAAAAEwICT8AAAAAAABgQkj4AQAAAAAAABPy/wGAA2jHaWRVIwAAAABJRU5ErkJggg==" alt="" />

  1. import java.awt.Color;
  2. import java.io.BufferedInputStream;
  3. import java.io.BufferedOutputStream;
  4. import java.io.File;
  5. import java.io.FileInputStream;
  6. import java.io.FileOutputStream;
  7. import java.io.IOException;
  8. import java.io.InputStream;
  9. import java.io.PrintWriter;
  10. import java.text.DecimalFormat;
  11. import java.util.ArrayList;
  12. import java.util.Calendar;
  13. import java.util.HashMap;
  14. import java.util.Iterator;
  15. import java.util.List;
  16. import java.util.Map;
  17. import java.util.UUID;
  18.  
  19. import javax.servlet.http.HttpServletResponse;
  20.  
  21. import org.apache.catalina.tribes.util.Arrays;
  22. import org.apache.poi.hssf.usermodel.HSSFCell;
  23. import org.apache.poi.hssf.usermodel.HSSFRow;
  24. import org.apache.poi.hssf.usermodel.HSSFSheet;
  25. import org.apache.poi.hssf.usermodel.HSSFWorkbook;
  26. import org.apache.poi.poifs.filesystem.POIFSFileSystem;
  27. import org.apache.poi.ss.util.CellRangeAddress;
  28. import org.apache.poi.xssf.usermodel.XSSFCell;
  29. import org.apache.poi.xssf.usermodel.XSSFCellStyle;
  30. import org.apache.poi.xssf.usermodel.XSSFColor;
  31. import org.apache.poi.xssf.usermodel.XSSFFont;
  32. import org.apache.poi.xssf.usermodel.XSSFRow;
  33. import org.apache.poi.xssf.usermodel.XSSFSheet;
  34. import org.apache.poi.xssf.usermodel.XSSFWorkbook;
  35. import org.springframework.web.multipart.MultipartFile;
  36. import org.springframework.web.multipart.MultipartHttpServletRequest;
  37. import org.springframework.web.multipart.commons.CommonsMultipartResolver;
  38.  
  39. import cn.com.jtv.kaanalysis.module.dzdynamicexcel.entity.DzDynamicExcel;
  40. import cn.com.jtv.kaanalysis.module.dzdynamicexcel.manager.DzDynamicExcelManager;
  41. import cn.com.jtv.kaanalysis.module.dzdynamicexcelsampleinfo.entity.DzDynamicExcelSampleinfo;
  42. import cn.com.jtv.kaanalysis.module.dzdynamicexcelsampleinfo.manager.DzDynamicExcelSampleinfoManager;
  43. import cn.com.jtv.kaanalysis.module.dzdynamicrule.entity.DzDynamicRule;
  44. import cn.com.jtv.kaanalysis.module.dzdynamicrule.manager.DzDynamicRuleManager;
  45. import cn.com.jtv.mf.core.utils.UtilDate;
  46. import cn.com.jtv.mf.core.utils.json.UtilJson;
  47. import cn.com.jtv.mf.core.web.LoginUserHolder;
  48. import cn.com.jtv.mf.core.web.mvc.BaseEntityJsonAction;
  49. /**
  50. * 动态表格简单信息管理控制器.
  51. * <p>
  52. *
  53. * @version 2016-08-25
  54. * @author wanghj
  55. */
  56. public class DzDynamicExcelSampleinfoAction extends
  57. BaseEntityJsonAction<DzDynamicExcelSampleinfo> {
  58.  
  59. //DzDynamicExcel
  60. private DzDynamicExcelManager dEntityManager;
  61.  
  62. public DzDynamicExcelManager getdEntityManager() {
  63. return dEntityManager;
  64. }
  65. public void setdEntityManager(DzDynamicExcelManager dEntityManager) {
  66. this.dEntityManager = dEntityManager;
  67. }
  68.  
  69. //DzDynamicRule
  70. private DzDynamicRuleManager rEntityManager;
  71.  
  72. public DzDynamicRuleManager getrEntityManager() {
  73. return rEntityManager;
  74. }
  75. public void setrEntityManager(DzDynamicRuleManager rEntityManager) {
  76. this.rEntityManager = rEntityManager;
  77. }
  78.  
  79. //表头规则排序字段
  80. Integer sortNum = 1;
  81.  
  82. /**
  83. * 导入Excel 2003.
  84. */
  85. public String importXls() throws Exception {
  86. request.setCharacterEncoding("UTF-8");
  87. Map<String, Map<String, String>> maps = new HashMap<String, Map<String,String>>();
  88. // 获得excel文件
  89. // 解析器解析request的上下文
  90. CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver(
  91. request.getSession().getServletContext());
  92. // 先判断request中是否包涵multipart类型的数据,
  93. if (multipartResolver.isMultipart(request)) {
  94. // 再将request中的数据转化成multipart类型的数据
  95. MultipartHttpServletRequest multiRequest = (MultipartHttpServletRequest) request;
  96. Iterator<String> iter = multiRequest.getFileNames();
  97. while (iter.hasNext()) {
  98. MultipartFile file = multiRequest.getFile(iter.next());
  99. if (file != null) {
  100. maps = parseAndSaveExcel2003(file);
  101. request.setAttribute("fileName",file.getOriginalFilename());
  102. request.setAttribute("maps",maps);
  103. }
  104. }
  105. }
  106. return "success";
  107. }
  108.  
  109. //转换excel并保存其中数据到数据库
  110. public Map<String, Map<String, String>> parseAndSaveExcel2003(MultipartFile file) {
  111.  
  112. Map<String, Map<String, String>> maps = new HashMap<String, Map<String,String>>();
  113. DzDynamicExcelSampleinfo sampleInfo = null;
  114. try {
  115. POIFSFileSystem pois = new POIFSFileSystem(file.getInputStream());
  116. // 新建WorkBook
  117. HSSFWorkbook wb = new HSSFWorkbook(pois);
  118. // 获取Sheet(工作薄)总个数
  119. int sheetNumber = wb.getNumberOfSheets();
  120.  
  121. for (int i = 0; i < sheetNumber; i++) {
  122.  
  123. // 获取Sheet(工作薄)
  124. HSSFSheet sheet = wb.getSheetAt(i);
  125. // 开始行数
  126. int firstRow = sheet.getFirstRowNum();
  127. // 结束行数
  128. int lastRow = sheet.getLastRowNum();
  129. // 判断该Sheet(工作薄)是否为空
  130. boolean isEmpty = false;
  131. if (firstRow == lastRow) {
  132. isEmpty = true;
  133. }
  134.  
  135. if (!isEmpty) {// 工作薄不为空,获取其中数据,并保存到数据库
  136. Map<String, String> map = new HashMap<String, String>();
  137. int totalRownum = lastRow; //总行数
  138. int importRownum = 0; //成功导入行数
  139. // int failedRownum = 0; //失败行数
  140. ArrayList<Integer> errorList = new ArrayList<Integer>();
  141. // 获得表头固定数据
  142. String dwmcid = LoginUserHolder.getLoginStationId();//登录这所在单位id,
  143. //创建时间,一张表中,表头所包含的每一行的创建时间是相同的
  144. String create_time = UtilDate.dateToString(Calendar.getInstance().getTime(),"yyy-MM-dd HH:mm:ss");
  145. String table_id = UUID.randomUUID().toString();
  146. String create_person = LoginUserHolder.getLoginUserId();//创建人id
  147. String table_name = ""; //每张表的第一行内容为表名
  148. String isheader = "1";
  149. String logic_del = "0";
  150. String id = ""; //UUID,每条数据的id,主键
  151.  
  152. //获取数据
  153. List<DzDynamicExcel> list = new ArrayList<DzDynamicExcel>();
  154. DzDynamicExcel entity = null;
  155. boolean willExist = false;//如果解析到某一行是0,1,2,3...则说明表头到此为止.不用再解析了
  156. Integer seriesNumber = 0; //需要,用于排序
  157. List<String[]> tempExcels = new ArrayList<String[]>();
  158. List<String[]> rulesData = new ArrayList<String[]>();
  159.  
  160. for (int j = firstRow; j <= lastRow; j++) {
  161.  
  162. // 获取一行
  163. HSSFRow row = sheet.getRow(j);
  164. // 开始列数
  165. int firstCell = row.getFirstCellNum();
  166. // 结束列数
  167. int lastCell = row.getLastCellNum();
  168. // 判断该行是否为空
  169. String[] value = new String[lastCell];
  170. if (firstCell != lastCell) {
  171. for (int k = firstCell; k < lastCell; k++) {
  172. // 获取一个单元格
  173. HSSFCell cell = row.getCell(k);
  174. value[k] = strFromCell(cell);
  175. }
  176. //是否是表头终止行
  177. String checkStr = value[0]+value[1];
  178. if("01".equals(checkStr)||"null1".equals(checkStr)) {
  179. willExist= true;
  180. }else{
  181. tempExcels.add(value);
  182. id = UUID.randomUUID().toString();
  183. if(j==firstRow){//第一行是标题
  184. table_name = strFromArr(value);
  185. //删除数据库中相同的表
  186. List<DzDynamicExcelSampleinfo> sampleinfos = ((DzDynamicExcelSampleinfoManager)getEntityManager()).deleteByTableName(table_name);
  187. getEntityManager().delete(sampleinfos);
  188. int count = ((DzDynamicExcelSampleinfoManager)getEntityManager()).getCountByTableName(table_name);
  189. if(0!=count){
  190. break;//删除失败
  191. }
  192. }else{
  193. rulesData.add(value);//表头规则数据
  194. entity = new DzDynamicExcel(dwmcid, create_time, table_id, table_name, isheader, logic_del,id,value,String.valueOf(seriesNumber++));
  195. if(entity!=null){//导入成功
  196. list.add(entity);
  197. importRownum++;
  198. }/*else {//导入失败
  199. errorList.add(j+1);
  200. failedRownum++;
  201. }*/
  202. }
  203. }
  204.  
  205. }
  206. if(willExist) break;
  207. }
  208.  
  209. //先保存DzDynamicExcelSampleinfo,后保存DzDynamicExcel(因为数据库中有级联)
  210. //一个工作薄一条记录一张表,保存多个工作薄
  211. sampleInfo = new DzDynamicExcelSampleinfo( table_id,
  212. dwmcid,
  213. table_id,
  214. table_name,
  215. create_time,
  216. create_person,
  217. String.valueOf(tempExcels.size()==0?0:getValicColumnSum(tempExcels)), //有效列数
  218. importRownum+""); //有效行数
  219. ((DzDynamicExcelSampleinfoManager)getEntityManager()).save(sampleInfo);
  220.  
  221. //保存DzDynamicExcel
  222. getdEntityManager().save(list);
  223. //添加表头合并规则
  224. int index = rulesData.size()-1;//2:例如0,1两行数据,
  225. if (index>=0) {
  226. List<DzDynamicRule> rules = new ArrayList<DzDynamicRule>();
  227. //表头规则倒序解析,并从倒数第二行开始(如果存在的话),并且每一个解析成功的对象都有一个排序字段(按照解析的次序)
  228. for (int l =index-1 ; l >=0 ; l--) {
  229. String[] row = (String[]) rulesData.get(l);
  230. String[] last_row = null;//上一行数据
  231.  
  232. last_row = (String[]) rulesData.get(l+1);
  233.  
  234. List<DzDynamicRule> subRules = getMergeRuleToEntities(create_time, table_id,row,last_row);
  235. if(subRules!=null){
  236. rules.addAll(subRules);
  237. }
  238. }
  239. if(rules!=null){
  240. System.out.println(UtilJson.toJson(rules));
  241. ((DzDynamicRuleManager)getrEntityManager()).save(rules);
  242. }
  243. int successRownum = importRownum==0?0:(importRownum+2);
  244. map.put("totalRownum", (totalRownum+1)+"");
  245. map.put("importRownum", successRownum+"");
  246. map.put("failedRownum", (totalRownum+1-successRownum)+"");
  247. map.put("errorList", Arrays.toString(errorList.toArray()));
  248.  
  249. maps.put("sheet"+i, map);
  250. }else{
  251. System.out.println("导入失败");;
  252. }
  253.  
  254. }//--if
  255.  
  256. }
  257.  
  258. } catch (IOException e) {
  259. e.printStackTrace();
  260. }
  261. return maps;
  262. }
  263.  
  264. //将cell中不同类型的值全部转换为String类型
  265. private String strFromCell(HSSFCell cell) {
  266. String str = "";
  267. if (cell != null) {
  268. // 获取单元格,值的类型
  269. int cellType = cell.getCellType();
  270.  
  271. if (cellType == 0) {
  272. Object cellNumber = cell
  273. .getNumericCellValue();
  274. str = new DecimalFormat("#.##")
  275. .format(cellNumber);
  276. } else if (cellType == 1) {
  277. str = cell.getStringCellValue() + "";
  278. // }else if(cellType == 2){
  279. } else if (cellType == 4) {
  280. str = (cell.getBooleanCellValue()) + "";
  281. } else {
  282. str = "";
  283. }
  284. }
  285. return str;
  286. }
  287. //将cell中不同类型的值全部转换为String类型
  288. private String strFromXssfCell(XSSFCell cell) {
  289. String str = "";
  290. if (cell != null) {
  291. // 获取单元格,值的类型
  292. int cellType = cell.getCellType();
  293.  
  294. if (cellType == 0) {
  295. Object cellNumber = cell
  296. .getNumericCellValue();
  297. str = new DecimalFormat("#.##")
  298. .format(cellNumber);
  299. } else if (cellType == 1) {
  300. str = cell.getStringCellValue() + "";
  301. // }else if(cellType == 2){
  302. } else if (cellType == 4) {
  303. str = (cell.getBooleanCellValue()) + "";
  304. } else {
  305. str = "";
  306. }
  307. }
  308. return str;
  309. }
  310.  
  311. /**
  312. * 导入Excel 2007及以上版本.
  313. */
  314. public String importXlsx() throws Exception {
  315. Map<String, Map<String, String>> maps = new HashMap<String, Map<String,String>>();
  316. // 获得前台上传的文件
  317. Map<String, List<MultipartFile>> files = getUploadFiles();
  318. MultipartFile file = files.get("fileselect").get(0);
  319. // 格式校验
  320. String name = file.getOriginalFilename();
  321. if (!name.endsWith(".xlsx")) {
  322. throw new RuntimeException("目前仅支持 xlsx 格式的文件");
  323. }
  324. // 导入数据
  325. InputStream is = file.getInputStream();
  326. XSSFWorkbook workbook = new XSSFWorkbook(is);
  327. try {
  328. maps = parseAndSaveExcel2007(workbook);
  329. request.setAttribute("fileName",file.getOriginalFilename());
  330. request.setAttribute("maps",maps);
  331. } finally {
  332. try {
  333. workbook.close();
  334. } catch (Exception ex) {
  335. }
  336. }
  337. return "success";
  338. }
  339.  
  340. private Map<String, Map<String, String>> parseAndSaveExcel2007(XSSFWorkbook workbook) {
  341.  
  342. Map<String, Map<String, String>> maps = new HashMap<String, Map<String,String>>();
  343. DzDynamicExcelSampleinfo sampleInfo = null;
  344.  
  345. int sheetNum = workbook.getNumberOfSheets();
  346.  
  347. //遍历sheet
  348. for (int x = 0; x < sheetNum; x++) {
  349.  
  350. XSSFSheet sheet = workbook.getSheetAt(x);
  351. int firstRow = sheet.getFirstRowNum();
  352. int lastRow = sheet.getLastRowNum();
  353. if(firstRow != lastRow) {
  354.  
  355. Map<String, String> map = new HashMap<String, String>();
  356. int totalRownum = lastRow; //总行数
  357. int importRownum = 0; //成功导入行数
  358. // int failedRownum = 0; //失败行数
  359. ArrayList<Integer> errorList = new ArrayList<Integer>();
  360. // 获得表头固定数据
  361. String dwmcid = LoginUserHolder.getLoginStationId();//登录这所在单位id,
  362. //创建时间,一张表中,表头所包含的每一行的创建时间是相同的
  363. String create_time = UtilDate.dateToString(Calendar.getInstance().getTime(),"yyy-MM-dd HH:mm:ss");
  364. String table_id = UUID.randomUUID().toString();
  365. String create_person = LoginUserHolder.getLoginUserId();//创建人id
  366. String table_name = ""; //每张表的第一行内容为表名
  367. String isheader = "1";
  368. String logic_del = "0";
  369. String id = ""; //UUID,每条数据的id,主键
  370.  
  371. //获取数据
  372. List<DzDynamicExcel> list = new ArrayList<DzDynamicExcel>();
  373. DzDynamicExcel entity = null;
  374. boolean willExist = false;//如果解析到某一行是0,1,2,3...则说明表头到此为止.不用再解析了
  375. Integer seriesNumber = 0; //需要,用于排序
  376. List<String[]> tempExcels = new ArrayList<String[]>();
  377. List<String[]> rulesData = new ArrayList<String[]>();
  378. // 遍历行
  379. for (int i = 0; i < lastRow; i++) {
  380. XSSFRow row = sheet.getRow(i);
  381. int firstCellNum = row.getFirstCellNum();
  382. int lastCellNum = row.getLastCellNum();
  383. if (firstCellNum == lastCellNum) break;
  384.  
  385. String[] value = new String[lastCellNum];
  386. for (int j = firstCellNum; j <lastCellNum; j++) {//遍历列
  387. XSSFCell cell = row.getCell(j);
  388. value[j] = strFromXssfCell(cell);
  389. }
  390. //是否是表头终止行
  391. String checkStr = value[0]+value[1];
  392. if("01".equals(checkStr)||"null1".equals(checkStr)) {
  393. willExist= true;
  394. }else{
  395. tempExcels.add(value);
  396. id = UUID.randomUUID().toString();
  397. if(i==firstRow){//第一行是标题
  398. table_name = strFromArr(value);
  399. //删除数据库中相同的表
  400. List<DzDynamicExcelSampleinfo> sampleinfos = ((DzDynamicExcelSampleinfoManager)getEntityManager()).deleteByTableName(table_name);
  401. getEntityManager().delete(sampleinfos);
  402. int count = ((DzDynamicExcelSampleinfoManager)getEntityManager()).getCountByTableName(table_name);
  403. if(0!=count){
  404. break;//删除失败
  405. }
  406. }else{
  407. rulesData.add(value);//表头规则数据
  408. entity = new DzDynamicExcel(dwmcid, create_time, table_id, table_name, isheader, logic_del,id,value,String.valueOf(seriesNumber++));
  409. if(entity!=null){//导入成功
  410. list.add(entity);
  411. importRownum++;
  412. }/*else {//导入失败
  413. errorList.add(j+1);
  414. failedRownum++;
  415. }*/
  416. }
  417. }
  418. if(willExist) break;
  419. }//遍历行结束
  420.  
  421. //先保存DzDynamicExcelSampleinfo,后保存DzDynamicExcel(因为数据库中有级联)
  422. //一个工作薄一条记录一张表,保存多个工作薄
  423. sampleInfo = new DzDynamicExcelSampleinfo( table_id,
  424. dwmcid,
  425. table_id,
  426. table_name,
  427. create_time,
  428. create_person,
  429. String.valueOf(tempExcels.size()==0?0:getValicColumnSum(tempExcels)), //有效列数
  430. importRownum+""); //有效行数
  431. ((DzDynamicExcelSampleinfoManager)getEntityManager()).save(sampleInfo);
  432.  
  433. //保存DzDynamicExcel
  434. getdEntityManager().save(list);
  435. //添加表头合并规则
  436. int index = rulesData.size()-1;//2:0,1例如两行数据,
  437. if (index>=0) {
  438. List<DzDynamicRule> rules = new ArrayList<DzDynamicRule>();
  439. //表头规则倒序解析,并从倒数第二行开始(如果存在的话),并且每一个解析成功的对象都有一个排序字段(按照解析的次序)
  440. for (int l =index-1 ; l >=0 ; l--) {
  441. String[] row = (String[]) rulesData.get(l);
  442. String[] last_row = null;//上一行数据
  443.  
  444. last_row = (String[]) rulesData.get(l+1);
  445.  
  446. List<DzDynamicRule> subRules = getMergeRuleToEntities(create_time, table_id,row,last_row);
  447. if(subRules!=null){
  448. rules.addAll(subRules);
  449. }
  450. }
  451. if(rules!=null){
  452. System.out.println(UtilJson.toJson(rules));
  453. ((DzDynamicRuleManager)getrEntityManager()).save(rules);
  454. }
  455. int successRownum = importRownum==0?0:(importRownum+2);
  456. map.put("totalRownum", (totalRownum+1)+"");
  457. map.put("importRownum", successRownum+"");
  458. map.put("failedRownum", (totalRownum+1-successRownum)+"");
  459. map.put("errorList", Arrays.toString(errorList.toArray()));
  460.  
  461. maps.put("sheet"+x, map);
  462. }else{
  463. System.out.println("导入失败");;
  464. }
  465. }//--if(firstRow != lastRow) {
  466.  
  467. }//--for sheet end
  468.  
  469. return maps;
  470. }
  471.  
  472. // 将数组转换为字符串
  473. public static String strFromArr(String[] arr) {
  474. String strs = "";
  475. for (String str : arr) {
  476. strs += (str == null ? "" : str);
  477. }
  478. return strs;
  479. }
  480.  
  481. /**
  482. * 处理多余的列,多余的null列不需要
  483. * @param data 待处理的List
  484. * @return 处理过的List
  485. */
  486. public Integer getValicColumnSum(List<String[]> data){
  487. int len = data.size();
  488. int maxIndex = 0;
  489. if(data!=null){
  490. for (int j = 0; j < len; j++) {//遍历每行数据
  491. Object[] obj = data.get(j);
  492. int maxLen = obj.length<100?obj.length:100;
  493. for (int i = 0; i < maxLen; i++) { //这一行从后面第一个不为null的值的位置,
  494. int currIndex = obj.length-i-1;
  495. if(obj[currIndex]!=null&&!"".equals(obj[currIndex])){
  496. if(maxIndex<currIndex){
  497. maxIndex = currIndex;
  498. }
  499. int rowCol = data.get(j).length-1;
  500. if(maxIndex<rowCol){
  501. maxIndex= rowCol;
  502. }
  503. break;
  504. }
  505. }
  506. }
  507.  
  508. }
  509. return maxIndex+1;
  510. }
  511.  
  512. /**
  513. * 异步检查xlsx文件中的表是否已经存在
  514. * @throws Exception
  515. */
  516. public void xlsxExist() throws Exception{
  517. // 获得前台上传的文件
  518. Map<String, List<MultipartFile>> files = getUploadFiles();
  519. MultipartFile file = files.get("fileselect").get(0);
  520.  
  521. // 导入数据
  522. InputStream is = file.getInputStream();
  523. XSSFWorkbook workbook = new XSSFWorkbook(is);
  524. Map<String, String> map = new HashMap<String, String>();
  525. try {
  526. map = checkXlsx(workbook);
  527. String json = UtilJson.toJson(map);
  528. PrintWriter out = response.getWriter();
  529. out.print(json);
  530. out.flush();
  531. out.close();
  532. } catch (IOException e) {
  533. e.printStackTrace();
  534. }finally {
  535. try {
  536. workbook.close();
  537. } catch (Exception ex) {
  538. }
  539. }
  540. }
  541.  
  542. private Map<String, String> checkXlsx(XSSFWorkbook workbook) {
  543. Map<String, String> map = new HashMap<String,String>();
  544. int sheetNum = workbook.getNumberOfSheets();
  545. //遍历sheet
  546. for (int x = 0; x < sheetNum; x++) {
  547.  
  548. XSSFSheet sheet = workbook.getSheetAt(x);
  549. int firstRow = sheet.getFirstRowNum();
  550. int lastRow = sheet.getLastRowNum();
  551. if(firstRow == lastRow) break;
  552.  
  553. XSSFRow row = sheet.getRow(0);
  554.  
  555. int firstCellNum = row.getFirstCellNum();
  556. int lastCellNum = row.getLastCellNum();
  557. if (firstCellNum == lastCellNum) break;
  558. String[] value = new String[lastCellNum];
  559. if (firstCellNum != lastCellNum) {
  560. for (int k = firstCellNum; k < lastCellNum; k++) {
  561. // 获取一个单元格
  562. XSSFCell cell = row.getCell(k);
  563. String str = "";
  564. if (cell != null) {
  565. // 获取单元格,值的类型
  566. int cellType = cell.getCellType();
  567.  
  568. if (cellType == 0) {
  569. Object cellNumber = cell
  570. .getNumericCellValue();
  571. str = new DecimalFormat("#.##")
  572. .format(cellNumber);
  573. } else if (cellType == 1) {
  574. str = cell.getStringCellValue() + "";
  575. // }else if(cellType == 2){
  576. } else if (cellType == 4) {
  577. str = (cell.getBooleanCellValue()) + "";
  578. } else {
  579. str = "";
  580. }
  581. }
  582. value[k] = str;
  583. }
  584.  
  585. }
  586. String tableName = strFromArr(value);
  587. Integer num = ((DzDynamicExcelSampleinfoManager)getEntityManager()).getCountByTableName(tableName);
  588. map.put(tableName,String.valueOf(num));
  589. }
  590. return map;
  591. }
  592.  
  593. /**
  594. * 异步检查Xls文件中的表是否已经给存在
  595. * 传给前台的是json格式的map字符串,{表名:已经存在次数}
  596. */
  597. public void xlsExist() {
  598.  
  599. try {
  600. request.setCharacterEncoding("UTF-8");
  601. response.setCharacterEncoding("utf-8");
  602. Map<String, String> maps = new HashMap<String, String>();
  603. // 获得excel文件
  604. // 解析器解析request的上下文
  605. CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver(
  606. request.getSession().getServletContext());
  607. // 先判断request中是否包涵multipart类型的数据,
  608. if (multipartResolver.isMultipart(request)) {
  609. // 再将request中的数据转化成multipart类型的数据
  610. MultipartHttpServletRequest multiRequest = (MultipartHttpServletRequest) request;
  611. Iterator<String> iter = multiRequest.getFileNames();
  612. while (iter.hasNext()) {
  613. MultipartFile file = multiRequest.getFile(iter.next());
  614. if (file != null) {
  615. maps = checkXls(file);
  616. }
  617. }
  618. }
  619. String json = UtilJson.toJson(maps);
  620. PrintWriter out = response.getWriter();
  621. out.print(json);
  622. out.flush();
  623. out.close();
  624. } catch (IOException e) {
  625. e.printStackTrace();
  626. }
  627. }
  628.  
  629. private Map<String,String> checkXls(MultipartFile file) {
  630. Map<String, String> map = new HashMap<String,String>();
  631. try {
  632. POIFSFileSystem pois = new POIFSFileSystem(file.getInputStream());
  633. // 新建WorkBook
  634. HSSFWorkbook wb = new HSSFWorkbook(pois);
  635. // 获取Sheet(工作薄)总个数
  636. // int sheetNumber = wb.getNumberOfSheets();
  637.  
  638. // 获取Sheet(工作薄)
  639. HSSFSheet sheet = wb.getSheetAt(0);
  640. // 开始行数
  641. int firstRow = sheet.getFirstRowNum();
  642. // 结束行数
  643. int lastRow = sheet.getLastRowNum();
  644. // 判断该Sheet(工作薄)是否为空
  645. boolean isEmpty = false;
  646. if (firstRow == lastRow) {
  647. isEmpty = true;
  648. }
  649.  
  650. if (!isEmpty) {// 工作薄不为空,获取其中数据,并保存到数据库
  651.  
  652. // 获取一行
  653. HSSFRow row = sheet.getRow(firstRow);
  654. // 开始列数
  655. int firstCell = row.getFirstCellNum();
  656. // 结束列数
  657. int lastCell = row.getLastCellNum();
  658. // 判断该行是否为空
  659. String[] value = new String[lastCell];
  660. if (firstCell != lastCell) {
  661. for (int k = firstCell; k < lastCell; k++) {
  662. // 获取一个单元格
  663. HSSFCell cell = row.getCell(k);
  664. value[k] = strFromCell(cell);
  665. }
  666.  
  667. }
  668. String tableName = strFromArr(value);
  669. Integer num = ((DzDynamicExcelSampleinfoManager)getEntityManager()).getCountByTableName(tableName);
  670. map.put(tableName,String.valueOf(num));
  671. }
  672.  
  673. } catch (IOException e) {
  674. e.printStackTrace();
  675. }
  676. return map;
  677. }
  678.  
  679. //根据表头的一行数据,得到合并规则
  680. public List<DzDynamicRule> getMergeRuleToEntities(String createTime, String tableId,String[] row,String[] last_row){
  681. List<DzDynamicRule> rules = new ArrayList<DzDynamicRule>();
  682. for (int i = 0; i < row.length; i++) {
  683. String groupName = row[i];
  684. if(!"".equals(groupName)){//空白单元格不处理
  685. int field_count = 1;
  686. for (int j = i+1; j < row.length; j++) {//判断当前单元格,后面的空白单元格数
  687. if("".equals(row[j])){
  688. field_count++;
  689. }else{
  690. break;
  691. }
  692. }
  693. //完成一个单元格的判定了,并且这个单元格,是需要合并的
  694. if(field_count>1){
  695. String[] group = new String[]{groupName,"col_"+(i+1),field_count+""};
  696. DzDynamicRule rule = new DzDynamicRule(createTime, UUID.randomUUID().toString(), tableId, sortNum++, group);
  697. rules.add(rule);
  698. i = i+field_count-1;
  699. }else if(field_count==1&&last_row.length!=0&&i<last_row.length){//如果是一个单元格,需要判断上一行同列单元格是否为空?
  700. if (!"".equals(last_row[i])) {//上行同列单元格为空,记录规则
  701. String[] group = new String[]{groupName,"col_"+(i+1),"1"};
  702. DzDynamicRule rule = new DzDynamicRule(createTime, UUID.randomUUID().toString(), tableId, sortNum++, group);
  703. rules.add(rule);
  704. i = i+field_count-1;
  705. }
  706. }
  707. field_count = 1;
  708. }
  709. }
  710. return rules;
  711. }
  712.  
  713. //导出数据为Xlsx文件
  714. public void exportXlsx(){
  715.  
  716. //1.将数据转换为excel
  717. String tableId = request.getParameter("tableId");
  718. System.out.println(tableId);
  719. //获取表头,获取表头规则,获取数据
  720. //表信息
  721. List<Object[]> list = ((DzDynamicExcelSampleinfoManager) getEntityManager()).getSampleInfo(tableId);
  722. Object[] sampleInfo = list.get(0);//表名,有效列数,有效行数
  723. //获取表头,数据
  724. List<Object[]> datas = ((DzDynamicExcelManager)getdEntityManager()).getData(tableId);
  725. //获取表头规则
  726. List<Object[]> rules = ((DzDynamicRuleManager)getrEntityManager()).getRules(tableId);
  727.  
  728. XSSFWorkbook workbook = new XSSFWorkbook();
  729. XSSFSheet sheet = workbook.createSheet();
  730.  
  731. //row:表名
  732. XSSFRow titlerow = sheet.createRow(0);
  733. XSSFCell titlecell = titlerow.createCell(0,XSSFCell.CELL_TYPE_STRING);
  734. titlecell.setCellValue(String.valueOf(sampleInfo[0]));//表名,表标题
  735. //边框,样式
  736. XSSFCellStyle style = getNewCenterStyle(workbook,Color.white,"title");
  737. CellRangeAddress region = new CellRangeAddress(0,(short)0,0,Short.valueOf(sampleInfo[1]+"")-1);//设置合并的行列
  738. setRegionStyle(sheet,region,style); //设置合并单元格的风格(加边框)setRegionStyle是一个我写的方法
  739. sheet.addMergedRegion(region); //将单元格合并
  740.  
  741. //有效列数
  742. int validColumn = Integer.valueOf(sampleInfo[1]+"");
  743. int validRow = Integer.valueOf(sampleInfo[2]+"");
  744. //row:表头,内容
  745. for (int i = 0; i < datas.size(); i++) {
  746. XSSFRow row = sheet.createRow(i+1);
  747. Object[] rowdata = datas.get(i);
  748. //表头
  749. if (i+1<=validRow) {
  750. style = getNewCenterStyle(workbook,Color.lightGray,"header");
  751. for (int j = 0; j < validColumn; j++) {
  752. XSSFCell cell = row.createCell(j,XSSFCell.CELL_TYPE_STRING);
  753. if(j>rowdata.length-1){
  754. cell.setCellValue("");
  755. continue;
  756. }
  757. cell.setCellValue(rowdata[j]==null?"":String.valueOf(rowdata[j]));
  758. cell.setCellStyle(style);
  759. }
  760. //内容
  761. }else{
  762. style = getNewCenterStyle(workbook,new Color(214, 214, 214),"body");
  763. for (int j = 0; j < validColumn; j++) {
  764. XSSFCell cell = row.createCell(j,XSSFCell.CELL_TYPE_STRING);
  765. if(j>rowdata.length-1){
  766. cell.setCellValue("");
  767. continue;
  768. }
  769. cell.setCellValue(rowdata[j]==null?"":String.valueOf(rowdata[j]));
  770. cell.setCellStyle(style);
  771. }
  772. }
  773.  
  774. }
  775. //合并表头
  776. sheet = mergeAllRange(sheet, validRow, validColumn);
  777. //设置表头样式
  778. style = getNewCenterStyle(workbook,Color.lightGray,"header");
  779. setAllRangeStyle(sheet, style);
  780. try
  781. {
  782. //保存excel到磁盘
  783. @SuppressWarnings("deprecation")
  784. String directory = request.getRealPath("/");
  785. File file = new File(directory+"\\kaanalysis\\module\\dzdynamicexcelsampleinfo\\dzdynamic_export_excels\\"+sampleInfo[0]+".xlsx");
  786. System.out.println(file.getAbsolutePath());
  787. FileOutputStream fout = new FileOutputStream(file);
  788. workbook.write(fout);
  789. fout.close();
  790.  
  791. //下载excel
  792. downLoadFile(response, file.getAbsolutePath(), "xlsx");
  793. }catch (Exception e) {
  794. e.printStackTrace();
  795. }
  796. }
  797.  
  798. /**
  799. * 合并表头,并添加表头样式
  800. * @param sheet
  801. * @param validrow
  802. * @param validcol
  803. * @return
  804. */
  805. private static XSSFSheet mergeAllRange(XSSFSheet sheet,int validrow,int validcol){
  806. XSSFCellStyle style = getNewCenterStyle(sheet.getWorkbook(),Color.lightGray,"header");
  807. int countrow = 1;
  808. int countcol = 1;
  809. for (int row = 1; row <validrow; row++) {//eg:3,则1,2行需要合并,3行为最后一行表头,不需要合并
  810. XSSFRow rowdata = sheet.getRow(row);
  811. if (rowdata==null) {
  812. continue;
  813. }
  814. for (int col = 0; col < validcol; col++) {
  815. //当前单元格非空,
  816. if (rowdata.getCell(col)!=null&&!"".equals(rowdata.getCell(col).getStringCellValue())) {
  817. //计算空白列
  818. for (int i = col+1; i < validcol; i++) {
  819. if (rowdata.getCell(i)!=null&&!"".equals(rowdata.getCell(i).getStringCellValue())) {
  820. break;
  821. }
  822. countcol++;
  823. }
  824. //计算空白行
  825. for (int i = row+1; i <= validrow; i++) {
  826. if(sheet.getRow(i).getCell(col)!=null&&!"".equals(sheet.getRow(i).getCell(col).getStringCellValue())){
  827. break;
  828. }
  829.  
  830. countrow++;
  831. }
  832. }
  833. if (countcol!=1||countrow!=1) {
  834. CellRangeAddress range = new CellRangeAddress(row,(short)(row+countrow-1),col,(short)(col+countcol-1));//设置合并的行列
  835. setRegionStyle(sheet,range,style);//设置合并单元格的风格(加边框)setRegionStyle是一个我写的方法
  836. sheet.addMergedRegion(range);//将单元格合并
  837. //重新计数
  838. countcol = 1;
  839. countrow = 1;
  840. }
  841. }
  842. }
  843. return sheet;
  844. }
  845.  
  846. /**
  847. * 获取excel边框,样式
  848. * @param workBook
  849. * @param bgColor 背景色
  850. * @param type 类型:title标题,Header表头,body内容
  851. * @return
  852. */
  853.  
  854. private static XSSFCellStyle getNewCenterStyle(XSSFWorkbook workBook,Color bgColor,String type){
  855. XSSFCellStyle style = workBook.createCellStyle();;
  856. style.setAlignment(XSSFCellStyle.ALIGN_CENTER);
  857. style.setWrapText(true);
  858. style.setVerticalAlignment(XSSFCellStyle.VERTICAL_CENTER);
  859. style.setBorderLeft(XSSFCellStyle.BORDER_THIN);
  860. style.setBorderRight(XSSFCellStyle.BORDER_THIN);
  861. style.setBorderTop(XSSFCellStyle.BORDER_THIN);
  862. style.setBorderBottom(XSSFCellStyle.BORDER_THIN);
  863. //字体
  864. XSSFFont font = workBook.createFont();
  865. if ("title".equals(type)) {
  866. font.setFontName("黑体");
  867. font.setColor(new XSSFColor(Color.green));//字体颜色
  868. font.setFontHeight(60);
  869. font.setBoldweight(XSSFFont.BOLDWEIGHT_BOLD);//粗体显示
  870. font.setFontHeightInPoints((short) 22);
  871. }else if ("header".equals(type)) {
  872. font.setFontName("宋体");
  873. font.setColor(new XSSFColor(Color.red));
  874. font.setFontHeightInPoints((short) 12);
  875. //设置单元格边框颜色
  876. XSSFColor borderColor = new XSSFColor(Color.red);
  877. style.setTopBorderColor(borderColor);
  878. style.setBottomBorderColor(borderColor);
  879. style.setLeftBorderColor(borderColor);
  880. style.setRightBorderColor(borderColor);
  881. //设置单元格背景色
  882. style.setFillPattern(XSSFCellStyle.SOLID_FOREGROUND);
  883. style.setFillBackgroundColor(new XSSFColor(bgColor));// 设置背景色,好像不起作用
  884. style.setFillForegroundColor(new XSSFColor(bgColor));// 设置前景色
  885. }else if ("body".equals(type)) {
  886. font.setFontName("仿宋_GB2312");
  887. font.setFontHeightInPoints((short) 10); //字体大小
  888. }
  889. style.setFont(font);
  890. return style;
  891. }
  892.  
  893. /**
  894. * 设置合并区域样式
  895. * 设置excel边框,样式
  896. * @param sheet sheet
  897. * @param range 合并区域
  898. * @param cs 样式
  899. */
  900. private static void setRegionStyle(XSSFSheet sheet, CellRangeAddress range , XSSFCellStyle cs) {
  901. for (int i = range.getFirstRow(); i <= range.getLastRow(); i ++) {
  902. XSSFRow row = sheet.getRow(i);
  903. if(range.getFirstColumn()!=range.getLastColumn()){
  904. for (int j = range.getFirstColumn(); j <= range.getLastColumn(); j++) {
  905. XSSFCell cell = row.getCell((short)j);
  906. if( cell==null){
  907. cell=row.createCell(j);
  908. cell.setCellValue("");
  909. }
  910. cell.setCellStyle(cs);
  911. }
  912. }
  913. }
  914. }
  915.  
  916. /**
  917. * 一次性设置所有合并区域,但不包括表题,其实只是表头
  918. * @param sheet 工作薄
  919. * @param style 样式
  920. */
  921. private void setAllRangeStyle(XSSFSheet sheet , XSSFCellStyle style){
  922. int num = sheet.getNumMergedRegions();
  923. for (int i = 1; i < num; i++) {
  924. CellRangeAddress range = sheet.getMergedRegion(i);
  925. setRegionStyle(sheet, range, style);
  926. }
  927. }
  928.  
  929. //excel 下载
  930. public static boolean downLoadFile(HttpServletResponse response, String fileFullName, String fileType)
  931. throws Exception {
  932. File file = new File(fileFullName); //根据文件路径获得File文件
  933. //设置文件类型(这样设置就不止是下Excel文件了,一举多得)
  934. if("pdf".equals(fileType)){
  935. response.setContentType("application/pdf;charset=GBK");
  936. }else if("xls".equals(fileType)||"xlsx".equals(fileType)){
  937. response.setContentType("application/msexcel;charset=GBK");
  938. }else if("doc".equals(fileType)){
  939. response.setContentType("application/msword;charset=GBK");
  940. }
  941.  
  942. //文件名
  943. response.setHeader("Content-Disposition", "attachment;filename=\""
  944. + new String(fileFullName.substring(fileFullName.lastIndexOf("\\")).getBytes(), "ISO8859-1") + "\"");
  945. response.setContentLength((int) file.length());
  946. BufferedOutputStream output = null;
  947. BufferedInputStream input = null;
  948. try {
  949. output = new BufferedOutputStream(response.getOutputStream());
  950. InputStream fis = new BufferedInputStream(new FileInputStream(file));
  951. byte[] buffer = new byte[fis.available()];
  952. fis.read(buffer);
  953. fis.close();
  954. output.write(buffer);
  955. output.flush(); //不可少
  956. output.close();
  957. response.flushBuffer();//不可少
  958. } catch (Exception e) {
  959. e.printStackTrace();
  960. } finally {
  961. //关闭流,不可少
  962. if (input != null)
  963. input.close();
  964. if (output != null)
  965. output.close();
  966. }
  967.  
  968. return false;
  969. }
  970.  
  971. }

excel上传和下载的更多相关文章

  1. excel上传与下载

    后台:        @RequestMapping(value = "/uploadFile.do", method = RequestMethod.POST)  public ...

  2. java对excel表格的上传和下载处理

    Excel表格文件的上传和下载,java中涉及到文件肯定会有io流的知识. 而excel文件就要涉及到poi技术,而excel的版本包括:2003-2007和2010两个版本, 即excel的后缀名为 ...

  3. vue实现Excel文件的上传与下载

    一.前言项目中使用到比较多的关于Excel的前端上传与下载,整理出来,以便后续使用或分析他人. 1.前端vue:模板下载与导入Excel 导入Excel封装了子组件,点击导入按钮可调用子组件,打开文件 ...

  4. 2019.06.05 ABAP EXCEL 操作类代码 OLE方式(模板下载,excel上传,内表下载)

    一般使用标准的excel导入方法9999行,修改了标准的excel导入FM 整合出类:excel的 模板下载,excel上传,ALV内表下载功能. 在项目一开始可以SE24创建一个类来供整体开发使用, ...

  5. 微信小程序云开发-云存储-上传、下载、打开文件文件(word/excel/ppt/pdf)一步到位

    一.wxml文件 <!-- 上传.下载.打开文件一步执行 --> <view class="handle"> <button bindtap=&quo ...

  6. Struts2 之 实现文件上传和下载

    Struts2  之 实现文件上传和下载 必须要引入的jar commons-fileupload-1.3.1.jar commons-io-2.2.jar 01.文件上传需要分别在struts.xm ...

  7. PHPexcel:多sheet上传和下载

    excel表格上传和下载,断断续续写了很久,赶紧记下来万一以后忘记就亏大了= = 数据库有三张表:

  8. EXCEL上传POI

    Java SpringMVC POI上传excel并读取文件内容 2017年11月27日 15:26:56 强人锁男. 阅读数:15329   用的SSM框架,所需要的jar包如图所示:,链接地址:j ...

  9. 七牛云存储 qiniu 域名 回收 文件上传 备份 下载 MD

    Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱 MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina ...

随机推荐

  1. [ActionScript 3.0] AS3.0 动态加载显示内容

    可以将下列任何外部显示资源加载到 ActionScript 3.0 应用程序中: 在 ActionScript 3.0 中创作的 SWF 文件 — 此文件可以是 Sprite.MovieClip 或扩 ...

  2. flask-sqlalchemy分表解决方案

    转自:http://ju.outofmemory.cn/entry/61448 关键词: flask-sqlalchemy, sqlalchemy, 分表,分库 大型系统.海量数据肯定涉及到分库分表这 ...

  3. Android--输入自动提示AutoCompleteTextView

    布局文件: <TextView android:id="@+id/title" android:layout_width="wrap_content" a ...

  4. 【转】 ip段/数字,如192.168.0.1/24是什么意思?

    http://blog.csdn.net/aerchi/article/details/39396423 ip段/数字,如192.168.0.1/24是什么意思? ip段/数字,如192.168.0. ...

  5. 02-自定义CALayer

    *:first-child { margin-top: 0 !important; } body > *:last-child { margin-bottom: 0 !important; } ...

  6. Ubuntu 12.04 gedit编辑器 中文乱码

    百度一下查看了很多关于这个问题的解决方法,无非是用通过配置编辑器修改键值来解决.但是由于我的ubuntu是12.04版本的,搜索到的很多方法都不能用,网上一般的解决办法如下: 打开“注册表”(从字面理 ...

  7. JS入门-慕课网

    javascript是一种弱类型的数据交互语言, ch 1 数据类型 js中有六种数据类型:nunmber.string.boolean.null.undenfined.object原始类型:numb ...

  8. [AFUI]App Framework Quickstart

    ---------------------------------------------------------------------------------------------------- ...

  9. memcached学习(3)memcached的删除机制和发展方向

    memcached是缓存,所以数据不会永久保存在服务器上,这是向系统中引入memcached的前提. 本次介绍memcached的数据删除机制,以及memcached的最新发展方向--二进制协议(Bi ...

  10. xml中俩种解析方式

    两种解析方式 1.from xml.etree import ElementTree as ET 利用ElementTree模块下的xml方法可以把一个字符串类型的东西转换成Element类,从而利用 ...