SpringMVC导入Excel文件到MySQL

 

转载自 https://blog.csdn.net/wdehxiang/article/details/77619677

使用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;
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33

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;
  }
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值