SpringMVC导入Excel文件到MySQL

来源:互联网 发布:office for mac 威锋 编辑:程序博客网 时间:2024/06/05 22:37

使用SpringMVC导入Excel文件到MySQL时,由于是第一次做,所以走了比较多弯路,希望这篇文章能够给和我一样新学的童鞋,一点启发~做这个的时候,参考了比较多的文章,特别是最后两个文件上传类和解析类的,然后根据自己的项目需要进行修改。现在找不到之前看的帖子了,所以未能贴上参考网址,如果有知道的童鞋也可以告诉我一下哈~
(关于前台上传部分,可以参考这里)

SpringMVC的配置文件,需要增加文件上传配置:

(我就是一开始没配置,一直上传不了,纠结了一个多小时)

<!-- 支持文件上传 -->      <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">           <!-- 默认编码 -->        <property name="defaultEncoding" value="utf-8" />        <!-- 文件大小最大值 -->        <property name="maxUploadSize" value="10485760000" />        <!-- 内存中的最大值 -->        <property name="maxInMemorySize" value="40960" />    </bean>

pom导入相关包:

<!-- 文件上传 -->      <dependency>              <groupId>commons-fileupload</groupId>              <artifactId>commons-fileupload</artifactId>              <version>1.3</version>          </dependency>          <dependency>              <groupId>commons-io</groupId>              <artifactId>commons-io</artifactId>              <version>2.4</version>          </dependency>    </dependencies>

controller层部分代码。

接收前台上传的文件用MultipartFile,返回用map,所以前台用json类型接收

@ResponseBody    @RequestMapping(value="/analyzeXml", method = RequestMethod.POST)      public Map<String,Object> analyzeXml(@RequestParam("excelFile") MultipartFile  excelFile,HttpServletRequest request,HttpServletResponse response) {          //上传xml文件          InputStream inputs;          boolean result=false;//导入标志        Map<String,Object> map=new HashMap<String, Object>();        try {           //上传            inputs = excelFile.getInputStream();              String fileName = excelFile.getOriginalFilename();              String filePath=request.getSession().getServletContext().getRealPath("uploadFile");            String uploadFileName = FileUtil.uploadFile(inputs, fileName, filePath);              System.out.println(filePath+"/"+uploadFileName);            //解析Excel,导入MySQL            result=bbuService.addBbu(filePath+"/"+uploadFileName);        } catch (IOException e) {              e.printStackTrace();          }          if(result){         map.put("message", "成功");        }else{         map.put("message", "失败");        }         return map;    }

service层代码

这里主要是将解析后的信息转化为相关对象

public boolean addBbu(String filePath) {         int result=0;          //解析xml文件        ReadExcel readExcel=new ReadExcel();        List<List<String>> lList =readExcel.getExcelInfo(filePath);        Bbu bbu=null;        List<Bbu> bbuList=new ArrayList<Bbu>();        for(List<String> list : lList){         bbu=new Bbu();         bbu.setBranch(list.get(0));         bbu.setCity(list.get(1));         bbu.setGrid_no(list.get(2));        bbu.setBusiness_department_name(list.get(3));         bbu.setEngineering_station_no(list.get(4));         bbu.setSystem_type(list.get(5));         bbu.setBbu_name(list.get(6));         bbu.setAddress(list.get(7));         bbu.setLongitude(list.get(8));         bbu.setLatitude(list.get(9));         bbu.setBuilding_type(list.get(10));         bbu.setCover_type(list.get(11));         bbu.setIndoor_coverage_area(list.get(12));        bbu.setOutdoor_cover_building_num(list.get(13));         bbuList.add(bbu);        }        result=bbuMapper.addBbu(bbuList);        if(result>0){             return true;         }         return false;    }

Dao层代码

这里记得要加上@Param注解

/**     * 插入数据     * @param bbuList     */    public int addBbu(@Param("list")List<Bbu> bbuList);持久层用的是mybatis,写在mapper文件里的代码。因为要批量上传,所以使用了foreach语句,将list中的每一个对象逐条读取。<insert id="addBbu"  parameterType="java.util.List" >         insert into bbu        (branch,city,grid_no,business_department_name,engineering_station_no,        system_type,bbu_name,address,longitude,latitude,building_type,cover_type,indoor_coverage_area,outdoor_cover_building_num)         values         <foreach collection="list" item="item" index="index" separator=",">               (#{item.branch},#{item.city},#{item.grid_no},#{item.business_department_name},             #{item.engineering_station_no},#{item.system_type},#{item.bbu_name},#{item.address},             #{item.longitude},#{item.latitude},#{item.building_type},#{item.cover_type},             #{item.indoor_coverage_area},#{item.outdoor_cover_building_num})                </foreach>      </insert>

最后是两个关键类

文件上传类:

package com.shenofusc.utils;import java.io.BufferedInputStream;import java.io.BufferedOutputStream;import java.io.File;import java.io.FileNotFoundException;import java.io.FileOutputStream;import java.io.IOException;import java.io.InputStream;import java.util.UUID;public class FileUtil {    /***     * <pre>uploadFile(springMVC文件上传  传inputStream)           * 修改备注:       * @param inputs     * @param fileName     * @param folderPath     * @return</pre>     */    public static String uploadFile(InputStream inputs, String fileName, String folderPath) {        // 上传物理文件到服务器硬盘        BufferedInputStream bis = null;        FileOutputStream fos = null;        BufferedOutputStream bos = null;        String uploadFileName = null;        try {            // 构建输入缓冲区,提高读取文件的速度            bis = new BufferedInputStream(inputs);            // 自动建立文件夹            File folder = new File(folderPath);            if (!folder.exists()) {                folder.mkdirs();            }            // 为了保证上传文件的唯一性,可以通过uuid来解决            // 为了避免中文乱码问题则新生成的文件名由uuid+原来文件名的后缀组成            uploadFileName = UUID.randomUUID().toString()+getSuffix(fileName);            // 构建写文件的流即输出流            fos = new FileOutputStream(new File(folderPath+"/"+uploadFileName));            // 构建输出缓冲区,提高写文件的性能            bos = new BufferedOutputStream(fos);            // 通过输入流读取数据并将数据通过输出流写到硬盘文件夹            byte[] buffer = new byte[4096];// 构建4k的缓冲区            int s = 0;            while ((s=bis.read(buffer)) != -1) {                bos.write(buffer, 0, s);                bos.flush();            }        } catch (FileNotFoundException e) {            // TODO Auto-generated catch block            e.printStackTrace();        } catch (IOException e) {            // TODO Auto-generated catch block            e.printStackTrace();        } finally {            if (bos != null) {                try {                    bos.close();                    bos = null;                } catch (IOException e) {                    // TODO Auto-generated catch block                    e.printStackTrace();                }            }            if (fos != null) {                try {                    fos.close();                    fos = null;                } catch (IOException e) {                    // TODO Auto-generated catch block                    e.printStackTrace();                }            }            if (bis != null) {                try {                    bis.close();                    bis = null;                } catch (IOException e) {                    // TODO Auto-generated catch block                    e.printStackTrace();                }            }            if (inputs != null) {                try {                    inputs.close();                    inputs = null;                } catch (IOException e) {                    // TODO Auto-generated catch block                    e.printStackTrace();                }            }        }        return uploadFileName;    }
/** * 后缀名的获取 * @param fileName * @return */private static String getSuffix(String fileName) {    int index = fileName.lastIndexOf(".");    String suffix = fileName.substring(index);    return suffix;}

}

解析Excel

主要思路是首先判断是2007还是2003的Excel文件,然后将表格进行每一行每个单元格读取,每一行的每一个单元格存入list中,而将这些行再存入list中,最后再service层进行赋值转成bean。这里的缺点是表格文件的列必须是固定好的,不够灵活。但是想用反射来做,通过实体类的setXXX方法,来截取每个方法的XXX字段名,与表格中的标题比较,但无奈表格是中文的。如果再弄个map相对应英文名,太麻烦了,所以就没弄了。

package com.shenofusc.utils;import java.io.FileInputStream;import java.io.IOException;import java.io.InputStream;import java.util.ArrayList;import java.util.List;import org.apache.poi.hssf.usermodel.HSSFWorkbook;import org.apache.poi.ss.usermodel.Cell;import org.apache.poi.ss.usermodel.Row;import org.apache.poi.ss.usermodel.Sheet;import org.apache.poi.ss.usermodel.Workbook;import org.apache.poi.xssf.usermodel.XSSFWorkbook;public class ReadExcel {    private int totalRows = 0;//总行数    private int totalCells = 0;//构造方法    public ReadExcel(){}    public int getTotalRows()  { return totalRows;}    public int getTotalCells() {  return totalCells;}  /**   * 读EXCEL文件,获取集合   * @param fielName   * @return   */  public List<List<String>> getExcelInfo(String filePath){       //初始化集合          List<List<String>> lList=new ArrayList<List<String>>();       //初始化输入流       InputStream is = null;       try{          //根据文件名判断文件是2003版本还是2007版本          boolean isExcel2003 = true;          if(filePath.matches("^.+\\.(?i)(xlsx)$")){              isExcel2003 = false;          }          //根据新建的文件实例化输入流          is = new FileInputStream(filePath);          Workbook wb = null;          //根据excel里面的内容读取客户信息          if(isExcel2003){//当excel是2003时              wb = new HSSFWorkbook(is);          }          else{//当excel是2007时              wb = new XSSFWorkbook(is);          }          //读取Excel里面客户的信息          lList=readExcelValue(wb);          is.close();      }catch(Exception e){          e.printStackTrace();      } finally{          if(is !=null)          {              try{                  is.close();              }catch(IOException e){                  is = null;                     e.printStackTrace();              }          }      }      return lList;  }  /**   * 读取Excel里面客户的信息   * @param wb   * @return   */  private List<List<String>> readExcelValue(Workbook wb){      //得到第一个shell       Sheet sheet=wb.getSheetAt(0);      //得到Excel的行数       this.totalRows=sheet.getPhysicalNumberOfRows();      //得到Excel的列数(前提是有行数)       if(totalRows>=1 && sheet.getRow(0) != null){            this.totalCells=sheet.getRow(0).getPhysicalNumberOfCells();       }       List<List<String>> lList=new ArrayList<List<String>>();      //循环Excel行数,从第二行开始。标题不入库       for(int r=1;r<totalRows;r++){           Row row = sheet.getRow(r);           if (row == null) continue;           List<String> sList=new ArrayList<String>();           //循环Excel的列           for(int c = 0; c <this.totalCells; c++){                  Cell cell = row.getCell(c);               if (null != cell){                cell.setCellType(Cell.CELL_TYPE_STRING);                sList.add(cell.getStringCellValue());               }           }           //添加客户           lList.add(sList);       }       return lList;  }}