springMVC從上傳的Excel文件中讀取數據


示例:導入客戶文件(Excle文件)

一、編輯customer.xlsx

二、在spring的xml文件設置上傳文件大小

<!-- 上傳文件攔截,設置最大上傳文件大小   10M=10*1024*1024(B)=10485760 bytes -->  
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">  
    <property name="maxUploadSize" value="10485760" />  
</bean>

三、編輯jsp(addCustomer3.jsp)

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
 <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>   
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>

<%  
 String importMsg="";  
 if(request.getSession().getAttribute("msg")!=null){  
    importMsg=request.getSession().getAttribute("msg").toString();  
 }  
 request.getSession().setAttribute("msg", "");  
 %> 
<head>
     <title>批量導入客戶</title>
 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
 <body>
      <div><font color="bule">批量導入客戶</font></div>
     <form action="addController/batchimport" method="post" enctype="multipart/form-data" onsubmit="return check();">
         <div style="margin: 30px;"><input id="excel_file" type="file" name="filename" accept="xlsx" size="80"/>
         <input id="excel_button" type="submit" value="導入Excel"/></div>
         <font id="importMsg" color="red"><%=importMsg%></font><input type="hidden"/>
     </form>
 </body>
 <script type="text/javascript"> 
    function check() {  
          var excel_file = $("#excel_file").val();  
          if (excel_file == "" || excel_file.length == 0) {  
              alert("請選擇文件路徑!");  
              return false;  
          } else {  
             return true;  
          }  
     } 
    
    $(document).ready(function () {  
           var msg="";  
           if($("#importMsg").text()!=null){  
               msg=$("#importMsg").text();  
           }  
           if(msg!=""){  
               alert(msg);  
           }  
    });  
 </script>

</html>

四、編輯Java文件

4.1 控制器代碼(AddController.java)

@Controller
@RequestMapping("toPage/addController/")
public class AddController {
    
    private static Log log = LogFactory.getLog(AddController.class);
     @Autowired
     private CustomerService customerService;
     
     @RequestMapping(value = "batchimport", method = RequestMethod.POST)
     public String batchimport(@RequestParam(value="filename") MultipartFile file,
             HttpServletRequest request,HttpServletResponse response) throws IOException{
         log.info("AddController ..batchimport() start");
         //判斷文件是否為空
         if(file==null) return null;
         //獲取文件名
         String name=file.getOriginalFilename();
         //進一步判斷文件是否為空(即判斷其大小是否為0或其名稱是否為null)
         long size=file.getSize();
         if(name==null || ("").equals(name) && size==0) return null;
         
         //批量導入。參數:文件名,文件。
         boolean b = customerService.batchImport(name,file);
         if(b){
              String Msg ="批量導入EXCEL成功!";
              request.getSession().setAttribute("msg",Msg);    
         }else{
              String Msg ="批量導入EXCEL失敗!";
              request.getSession().setAttribute("msg",Msg);
         } 
        return "Customer/addCustomer3";
     }
         
}

4.2 服務層代碼(CustomerService.java),即上述方法中 customerService.batchImport(name,file);語句所調用的方法

  //批量導入客戶
    public boolean batchImport(String name,MultipartFile file){
        boolean b = false;
        //創建處理EXCEL
        ReadExcel readExcel=new ReadExcel();
        //解析excel,獲取客戶信息集合。
        List<Customer> customerList = readExcel.getExcelInfo(name ,file);

        if(customerList != null){
            b = true;
        }
        
        //迭代添加客戶信息(注:實際上這里也可以直接將customerList集合作為參數,在Mybatis的相應映射文件中使用foreach標簽進行批量添加。)
        for(Customer customer:customerList){
            customerDoImpl.addCustomers(customer);
        }
        return b;
    }

4.3 工具類代碼(ReadExcel.java),即上述方法中readExcel.getExcelInfo(name ,file);語句所調用的方法以及其他相關的方法

Apache POI提供API給Java程式對Microsoft Office格式檔案讀和寫的功能。不過這首先得判斷Excel的版本而選擇不同的Workbook的方式(2003版本對應的是HSSFWorkbook,2007版本及以上對應的是XSSFWorkbook)。此外,一般來說先將在客戶端用戶上傳的文件拷貝一份至服務器的本地磁盤中,然后再從這個拷貝文件中進行讀取,這樣就避免了因客戶端的網絡異常或其他狀況而在讀取時造成的數據流失或損壞的情況。

package com.jun.util;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Date;
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;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.commons.CommonsMultipartFile;

import com.jun.service.CustomerService;
import com.jun.vo.Customer;

public class ReadExcel {
    //總行數
    private int totalRows = 0;  
    //總條數
    private int totalCells = 0; 
    //錯誤信息接收器
    private String errorMsg;
    //構造方法
    public ReadExcel(){}
    //獲取總行數
    public int getTotalRows()  { return totalRows;} 
    //獲取總列數
    public int getTotalCells() {  return totalCells;} 
    //獲取錯誤信息
    public String getErrorInfo() { return errorMsg; }  
    
  /**
   * 驗證EXCEL文件
   * @param filePath
   * @return
   */
  public boolean validateExcel(String filePath){
        if (filePath == null || !(WDWUtil.isExcel2003(filePath) || WDWUtil.isExcel2007(filePath))){  
            errorMsg = "文件名不是excel格式";  
            return false;  
        }  
        return true;
  }
    
  /**
   * 讀EXCEL文件,獲取客戶信息集合
   * @param fielName
   * @return
   */
  public List<Customer> getExcelInfo(String fileName,MultipartFile Mfile){
      
      //把spring文件上傳的MultipartFile轉換成CommonsMultipartFile類型
       CommonsMultipartFile cf= (CommonsMultipartFile)Mfile; //獲取本地存儲路徑
       File file = new  File("D:\\fileupload");
       //創建一個目錄 (它的路徑名由當前 File 對象指定,包括任一必須的父路徑。)
       if (!file.exists()) file.mkdirs();
       //新建一個文件
       File file1 = new File("D:\\fileupload" + new Date().getTime() + ".xlsx"); 
       //將上傳的文件寫入新建的文件中
       try {
           cf.getFileItem().write(file1); 
       } catch (Exception e) {
           e.printStackTrace();
       }
       
       //初始化客戶信息的集合    
       List<Customer> customerList=new ArrayList<Customer>();
       //初始化輸入流
       InputStream is = null;  
       try{
          //驗證文件名是否合格
          if(!validateExcel(fileName)){
              return null;
          }
          //根據文件名判斷文件是2003版本還是2007版本
          boolean isExcel2003 = true; 
          if(WDWUtil.isExcel2007(fileName)){
              isExcel2003 = false;  
          }
          //根據新建的文件實例化輸入流
          is = new FileInputStream(file1);
          //根據excel里面的內容讀取客戶信息
          customerList = getExcelInfo(is, isExcel2003); 
          is.close();
      }catch(Exception e){
          e.printStackTrace();
      } finally{
          if(is !=null)
          {
              try{
                  is.close();
              }catch(IOException e){
                  is = null;    
                  e.printStackTrace();  
              }
          }
      }
      return customerList;
  }
  /**
   * 根據excel里面的內容讀取客戶信息
   * @param is 輸入流
   * @param isExcel2003 excel是2003還是2007版本
   * @return
   * @throws IOException
   */
  public  List<Customer> getExcelInfo(InputStream is,boolean isExcel2003){
       List<Customer> customerList=null;
       try{
           /** 根據版本選擇創建Workbook的方式 */
           Workbook wb = null;
           //當excel是2003時
           if(isExcel2003){
               wb = new HSSFWorkbook(is); 
           }
           else{//當excel是2007時
               wb = new XSSFWorkbook(is); 
           }
           //讀取Excel里面客戶的信息
           customerList=readExcelValue(wb);
       }
       catch (IOException e)  {  
           e.printStackTrace();  
       }  
       return customerList;
  }
  /**
   * 讀取Excel里面客戶的信息
   * @param wb
   * @return
   */
  private List<Customer> 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<Customer> customerList=new ArrayList<Customer>();
       Customer customer;            
      //循環Excel行數,從第二行開始。標題不入庫
       for(int r=1;r<totalRows;r++){
           Row row = sheet.getRow(r);
           if (row == null) continue;
           customer = new Customer();
           
           //循環Excel的列
           for(int c = 0; c <this.totalCells; c++){    
               Cell cell = row.getCell(c);
               if (null != cell){
                   if(c==0){//第一列不讀
                   }else if(c==1){
                       customer.setcName(cell.getStringCellValue());//客戶名稱
                   }else if(c==2){
                       customer.setSimpleName(cell.getStringCellValue());//客戶簡稱
                   }else if(c==3){
                       customer.setTrade(cell.getStringCellValue());//行業
                   }else if(c==4){
                       customer.setSource(cell.getStringCellValue());//客戶來源
                   }else if(c==5){
                       customer.setAddress(cell.getStringCellValue());//地址
                   }else if(c==6){
                       customer.setRemark(cell.getStringCellValue());//備注信息
                   }
               }
           }
           //添加客戶
           customerList.add(customer);
       }
       return customerList;
  }

}

4.4 工具類代碼(WDWUtil.java)

public class WDWUtil {

    // @描述:是否是2003的excel,返回true是2003 
    public static boolean isExcel2003(String filePath)  {  
         return filePath.matches("^.+\\.(?i)(xls)$");  
     }  
   
    //@描述:是否是2007的excel,返回true是2007 
    public static boolean isExcel2007(String filePath)  {  
         return filePath.matches("^.+\\.(?i)(xlsx)$");  
     }  
 
}

說明:上面的代碼為了閱讀便利而先貼的是父方法,后貼的是子方法,而在實際的代碼編輯中一般是先編輯子方法,后編輯父方法,如上面應該是先編輯工具類的代碼,再編輯服務層的代碼,最后編輯控制器的代碼。

運行結果:(先點擊“選擇文件”,再點擊“導入Excel”)

數據庫

 

后記:此博客省略了模型層的代碼,此項目采用的是Mybatis。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM