在springmvc项目中使用poi导入导出excel

首先要导入spring相关包,poi,和fileupload包,我是使用maven构建的。


一.导入excel

(1)使用spring上传文件

a.前台页面提交
<form name="excelImportForm" action="${pageContext.request.contextPath}/brand/importBrandSort" method="post" οnsubmit="return checkImportPath();" enctype="multipart/form-data" id="excelImportForm">  
               <input  type="hidden" name="ids" id="ids">  
               <div class="modal-body">  
                   <div class="row gap">  
                       <label class="col-sm-7 control-label"><input class="btn btn-default" id="excel_file" type="file" name="filename"  accept="xls"/></label>  
                       <div class="col-sm-3">  
                             
                        <input class="btn btn-primary" id="excel_button" type="submit" value="导入Excel"/>  
                       </div>  
                   </div>  
                     
               </div>  
                
               <div class="modal-footer">  
                    <button type="button" class="btn btn-default" data-dismiss="modal" onClick="uncheckBoxes();">取消</button>  
            </div>  

在提交前可进行一些判断,可查看:

b.后台spring的controller进行相关操作,这里主要讲的是使用spring上传文件,和读取文件信息,可以参考这两篇文章:


使用spring上传文件之前,需要配置bean
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"></bean>  

@RequestMapping(value = "/importBrandSort", method = RequestMethod.POST)  
    public ModelAndView importBrandSort(@RequestParam("filename") MultipartFile file,HttpServletRequest request,HttpServletResponse response) throws Exception {  
        /*String temp = request.getSession().getServletContext() 
                .getRealPath(File.separator) 
                + "temp"; // 临时目录 
        File tempFile = new File(temp); 
        if (!tempFile.exists()) { 
            tempFile.mkdirs(); 
        } 
        DiskFileUpload fu = new DiskFileUpload(); 
        fu.setSizeMax(10 * 1024 * 1024); // 设置允许用户上传文件大小,单位:位 
        fu.setSizeThreshold(4096); // 设置最多只允许在内存中存储的数据,单位:位 
        fu.setRepositoryPath(temp); // 设置一旦文件大小超过getSizeThreshold()的值时数据存放在硬盘的目录 
        // 开始读取上传信息 
        // int index = 0; 
        List fileItems = null; 
        try { 
            fileItems = fu.parseRequest(request); 
        } catch (Exception e) { 
            e.printStackTrace(); 
        } 
        Iterator iter = fileItems.iterator(); // 依次处理每个上传的文件 
        FileItem fileItem = null; 
        while (iter.hasNext()) { 
            FileItem item = (FileItem) iter.next();// 忽略其他不是文件域的所有表单信息 
            if (!item.isFormField()) { 
                fileItem = item; 
                // index++; 
            } 
        } 
         
        if (fileItem == null) 
            return null; 
            */  
        if (file == null)  
            return null;  
        logger.info(file.getOriginalFilename());  
  
        String name = file.getOriginalFilename();// 获取上传文件名,包括路径  
        //name = name.substring(name.lastIndexOf("\\") + 1);// 从全路径中提取文件名  
        long size = file.getSize();  
        if ((name == null || name.equals("")) && size == 0)  
            return null;  
        InputStream in = file.getInputStream();  
        int count = brandService.importBrandPeriodSort(in);  
  
        // 改为人工刷新缓存KeyContextManager.clearPeriodCacheData(new  
        // PeriodDimensions());// 清理所有缓存  
        //int count = BrandMobileInfos.size();  
        String strAlertMsg ="";  
          
            strAlertMsg= "成功更新" + count + "条!";  
          
        logger.info(strAlertMsg);  
        //request.setAttribute("brandPeriodSortList", BrandMobileInfos);  
        //request.setAttribute("strAlertMsg", strAlertMsg);  
      
        request.getSession().setAttribute("msg",strAlertMsg);  
        return get(request, response);  
        //return null;  
    } 
代码中的注释部分是如果不使用spring的方式,如何拿到提交过来的文件名(需要是要apache的一些工具包),其实使用spring的也是一样,只是已经做好了封装,方便我们写代码。

代码中的后半部分是读取完上传文文件的信息和对数据库进行更新之后,输出到前台页面的信息。

这里给页面设置session信息,前台检测session提示是否导入成功。具体可参考:
上述代码中:
InputStream in = file.getInputStream();  
        List<BrandMobileInfoEntity> BrandMobileInfos = brandService  
                .importBrandPeriodSort(in);  

读取excel的信息。

(2)使用poi读取excel

a.更新数据库
@Override  
    public List<BrandMobileInfoEntity> importBrandPeriodSort(InputStream in) throws Exception  {  
          
        List<BrandMobileInfoEntity> brandMobileInfos = readBrandPeriodSorXls(in);  
        for (BrandMobileInfoEntity brandMobileInfo : brandMobileInfos) {  
            mapper.updateByConditions(brandMobileInfo);  
        }  
        return brandMobileInfos;  
    }  

这部分是sevice层的代码,用于读取excel信息之后更新数据库数据,我这里是使用mybatis。定义一个类BrandMobileInfoEntity,用与保存excel表每一行的信息,而List< BrandMobileInfoEntity>则保存了全部信息,利用这些信息对数据库进行更新。

b.读取excel信息

private List<BrandMobileInfoEntity> readBrandPeriodSorXls(InputStream is)  
            throws IOException, ParseException {  
        HSSFWorkbook hssfWorkbook = new HSSFWorkbook(is);  
        List<BrandMobileInfoEntity> brandMobileInfos = new ArrayList<BrandMobileInfoEntity>();  
        BrandMobileInfoEntity brandMobileInfo;  
        // 循环工作表Sheet  
        for (int numSheet = 0; numSheet < hssfWorkbook.getNumberOfSheets(); numSheet++) {  
            HSSFSheet hssfSheet = hssfWorkbook.getSheetAt(numSheet);  
            if (hssfSheet == null) {  
                continue;  
            }  
            // 循环行Row  
            for (int rowNum = 1; rowNum <= hssfSheet.getLastRowNum(); rowNum++) {  
                brandMobileInfo = new BrandMobileInfoEntity();  
                HSSFRow hssfRow = hssfSheet.getRow(rowNum);  
                for (int i = 0; i < hssfRow.getLastCellNum(); i++) {  
                    HSSFCell brandIdHSSFCell = hssfRow.getCell(i);  
                    if (i == 0) {  
                        brandMobileInfo.setBrandId(Integer  
                                .parseInt(getCellValue(brandIdHSSFCell)));  
                    } else if (i == 1) {  
                        continue;  
                    } else if (i == 2) {  
                        brandMobileInfo.setMobileShowFrom(Integer.parseInt(getCellValue(brandIdHSSFCell)));  
                    } else if (i == 3) {  
                        brandMobileInfo.setMobileShowTo(Integer.parseInt(getCellValue(brandIdHSSFCell)));  
                    } else if (i == 4) {  
                        brandMobileInfo.setSellMarkValue(getCellValue(brandIdHSSFCell));  
                    } else if (i == 5) {  
                        brandMobileInfo.setWarehouse(getCellValue(brandIdHSSFCell));  
                    } else if (i == 6) {  
                        brandMobileInfo.setSortA1(Integer.parseInt(getCellValue(brandIdHSSFCell)));  
                    } else if (i == 7) {  
                        brandMobileInfo.setSortA2(Integer.parseInt(getCellValue(brandIdHSSFCell)));  
                    } else if (i == 8) {  
                        brandMobileInfo.setSortB(Integer.parseInt(getCellValue(brandIdHSSFCell)));  
                    } else if (i == 9) {  
                        brandMobileInfo.setSortC10(Integer.parseInt(getCellValue(brandIdHSSFCell)));  
                    } else if (i == 10) {  
                        brandMobileInfo.setSortC(Integer.parseInt(getCellValue(brandIdHSSFCell)));  
                    } else if (i == 11) {  
                        brandMobileInfo.setHitA(getCellValue(brandIdHSSFCell));  
                    } else if (i == 12) {  
                        brandMobileInfo.setHitB(getCellValue(brandIdHSSFCell));  
                    } else if (i == 13) {  
                        brandMobileInfo.setHitC(getCellValue(brandIdHSSFCell));  
                    } else if (i == 14) {  
                        brandMobileInfo.setCustomSellType(getCellValue(brandIdHSSFCell));  
                    }else if (i == 15) {  
                      continue;  
                    }else if (i == 16) {  
                        brandMobileInfo.setChannelId(Integer.parseInt(getCellValue(brandIdHSSFCell)));  
                    }  
                }  
                brandMobileInfos.add(brandMobileInfo);  
  
            }  
        }  
        return brandMobileInfos;  
    }  

这种代码有点搓,还没有优化,可以大概看到是怎么读取信息的。

(3)使用mybatis更新数据


二.导出excel

(1)
前台页面使用一个按钮,定义js事件:
$(".exportBrandSort").on('click', function() {  
          
         var url = contextPath+"/brand/exportBrandSort";  
         $('#searchform').attr('action', url);  
         $('#searchform').submit();  
         //还原action值  
         url = contextPath+"/brand/getBrand";  
         $('#searchform').attr('action', url);}  

这里使用查询功能的form的表单,则导出的就是查询之后的信息的excel表格。

(2)后台controller处理
a.后端controller处理并输出到前台
@RequestMapping(value = "/exportBrandSort", method = RequestMethod.GET)  
    public void exportBrandSort(HttpServletRequest request,  
            HttpServletResponse response) throws Exception {  
  
        try {  
            Map<String, Object> params = new HashMap<>();  
            // start time of selling  
            String startTimeStr = RequestUtil.getStringParameter(request,  
                    "startTimeStr", null);  
            if (StringUtils.isNotBlank(startTimeStr)) {  
                params.put("startTimeStr", startTimeStr);  
                params.put("startTime", df.parse(startTimeStr).getTime() / 1000);  
            }  
  
            // end time of selling  
            String endTimeStr = RequestUtil.getStringParameter(request,  
                    "endTimeStr", null);  
            if (StringUtils.isNotBlank(endTimeStr)) {  
                params.put("endTimeStr", endTimeStr);  
                params.put("endTime", df.parse(endTimeStr).getTime() / 1000);  
            }  
  
            // warehouse  
            String warehouse = RequestUtil.getStringParameter(request,  
                    "warehouse");  
            if (StringUtils.isNotBlank(warehouse)) {  
                params.put("warehouse", warehouse);  
            }  
  
            // channel  
            String channel4ui = BrandConstants.CHANNEL_ID_SEARCH_DEFAULT;  
  
            String[] channel = request.getParameterValues("channel");  
            if (channel != null && channel.length > 0) {  
                channel4ui = stringArrayToString(channel);  
            }  
            params.put("channel", channel4ui);  
  
            String orderType = request.getParameter("orderType");  
            if (orderType == null || "".equals(orderType)) {  
                orderType = "C";  
            }  
            params.put("orderType", orderType);  
  
            // brand id  
            if (RequestUtil.getIntParameter(request, "brandId") > 0)  
                params.put("brandId",  
                        (RequestUtil.getIntParameter(request, "brandId")));  
            // brand name  
            if (RequestUtil.getStringParameter(request, "brandName") != null  
                    && !"".equals(RequestUtil.getStringParameter(request,  
                            "brandName").trim()))  
                // params.put("brandName", new  
                // String(RequestUtil.getStringParameter(request,  
                // "brandName").getBytes("ISO-8859-1"),"UTF-8"));  
                params.put("brandName",  
                        RequestUtil.getStringParameter(request, "brandName"));  
  
            int count = brandService.countByConditions(params);  
  
            List<BrandCompleteInfoEntity> list = brandService  
                    .queryBrands(params);  
  
            // --------  
  
            byte[] fileNameByte = ("kxw.xls").getBytes("GBK");  
            String filename = new String(fileNameByte, "ISO8859-1");  
  
            byte[] bytes = brandService.exportBrandPeriodSort(list);  
        //  logger.info("------------------------"+bytes.length);  
            response.setContentType("application/x-msdownload");  
            //response.setContentType("application/x-excel");    
            response.setContentLength(bytes.length);  
            response.setHeader("Content-Disposition", "attachment;filename="  
                    + filename);  
            response.getOutputStream().write(bytes);  
            //response.getOutputStream().flush();  
              
             
        } catch (Exception ex) {  
            logger.debug(ex.getMessage());  
        }  
    }  

代码中前半部分只是根据表单信息去后台那数据并保存在List<BrandCompleteInfoEntity>中,可忽略细节。
关键是把 List<BrandCompleteInfoEntity>拼接成excel并输出到网页中。

这里注意该方法的返回值是void,否则如果是ModelAndView或者String等类型,提交之后会发生跳转,返回null则是跳转到空白页面。

代码中:
byte[] fileNameByte = ("档期列表.xls").getBytes("GBK");  
            String filename = new String(fileNameByte, "ISO8859-1");  
  
            byte[] bytes = brandService.exportBrandPeriodSort(list);  

若乱码:
response.setHeader("Content-Disposition", "attachment;filename="  
                    + java.net.URLEncoder.encode("档期列表.xls", "UTF-8") );  
            response.getOutputStream().write(bytes);  

是拼接excel。

b.拼接excel(service层)
@Override  
    public byte[] exportBrandPeriodSort(List<BrandCompleteInfoEntity>  list) throws Exception {  
          
        ByteArrayOutputStream out = new ByteArrayOutputStream();  
        // 第一步,创建一个webbook,对应一个Excel文件  
        HSSFWorkbook wb = new HSSFWorkbook();  
        // 第二步,在webbook中添加一个sheet,对应Excel文件中的sheet  
        HSSFSheet sheet = wb.createSheet("档期排序表");  
        // 第三步,在sheet中添加表头第0行,注意老版本poi对Excel的行数列数有限制short  
        HSSFRow row = sheet.createRow((int) 0);  
        // 第四步,创建单元格,并设置值表头 设置表头居中  
        HSSFCellStyle style = wb.createCellStyle();  
        style.setAlignment(HSSFCellStyle.ALIGN_CENTER); // 创建一个居中格式  
  
        //设置表头  
        List<String> excelHead = getExcelHead();  
          
        HSSFCell cell = null;  
        // excel头  
        for (int i = 0; i < excelHead.size(); i++) {  
            cell = row.createCell(i);  
            cell.setCellValue(excelHead.get(i));  
            cell.setCellStyle(style);  
        }  
  
        // 第五步,写入实体数据 实际应用中这些数据从数据库得到  
        //List<BrandPeriodSortEntity> list = getBrandPeriodSortDynamicOrder(entity, orderType);  
  
        BrandCompleteInfoEntity brandCompleteInfo = null; // 拼装excel内容  
        for (int i = 0; i < list.size(); i++) {  
            row = sheet.createRow((int) i + 1);  
            brandCompleteInfo = list.get(i);  
            // 创建单元格,并设置值  
          
              
            int j=0;  
            insertCell(row, j++, brandCompleteInfo.getBrandId());  
            insertCell(row, j++, brandCompleteInfo.getBrandName());  
            insertCell(row, j++, brandCompleteInfo.getMobileShowFrom());  
            insertCell(row, j++, brandCompleteInfo.getMobileShowTo());  
            insertCell(row, j++, brandCompleteInfo.getSellMarkValue());  
            insertCell(row, j++, brandCompleteInfo.getWarehouse());  
            insertCell(row, j++, brandCompleteInfo.getSortA1());  
            insertCell(row, j++, brandCompleteInfo.getSortA2());  
            insertCell(row, j++, brandCompleteInfo.getSortB());  
            insertCell(row, j++, brandCompleteInfo.getSortC10());  
            insertCell(row, j++, brandCompleteInfo.getSortC());  
            insertCell(row, j++, brandCompleteInfo.getHitA());  
            insertCell(row, j++, brandCompleteInfo.getHitB());  
            insertCell(row, j++, brandCompleteInfo.getHitC());  
            insertCell(row, j++, brandCompleteInfo.getCustomSellType());  
            insertCell(row, j++, channelInfoMapper.loadChannelNameById(brandCompleteInfo.getChannelId()));  
            insertCell(row, j++, brandCompleteInfo.getChannelId());  
              
        }  
        wb.write(out);  
        return out.toByteArray();  
    }  
      
    /** 
     * 获取excel表头 
     *  
     * @return 
     */  
    private List<String> getExcelHead() {  
        List<String> result = new ArrayList<String>(17);  
        result.add("XXXXX");  
        result.add("XXXXX");  
        result.add("XXXXX");  
        result.add("XXXXX");  
        result.add("XXXXX");  
        result.add("XXXXX");  
        result.add("XXXXX");  
        result.add("XXXXX");  
        result.add("XXXXX");  
        result.add("XXXXX");  
  
        //。。。。  
        return result;  
}  
    private void insertCell(HSSFRow row,int i,Object object){  
          
        if(object==null){  
            row.createCell(i).setCellValue("");  
        }else{  
            row.createCell(i).setCellValue(object.toString());  
        }  
          
    } 
















评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值