1. 程式人生 > >詳細webMVC實現提交excel後臺並讀取資料

詳細webMVC實現提交excel後臺並讀取資料

使用MVC上傳EXCEL表格,主要是用到MultipartFile類進行檔案的獲取,然後把檔案讀取成EXCEL物件再進行處理,Java有處理Excel物件的包,需要匯入才能使用,具體的步驟,下面的用的MatchInfo是一個實體類,可以不用管

轉載自 南國櫻花祭的文章 這是我看的文章,基本複製他的程式碼,如果要看配置上傳檔案的大小限制的可以點進去看看

maven專案的要先新增pom依賴,不是maven的也要新增jar包,可以自行上網下載

<!-- 處理excel表格需要的jar包 三個 -->
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-ooxml-schemas</artifactId>
            <version>3.10-FINAL</version>
        </dependency>
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-ooxml</artifactId>
            <version>3.10-FINAL</version>
        </dependency>
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi</artifactId>
            <version>3.10-FINAL</version>
        </dependency>

1.先前端寫form表單

enctype="multipart/form-data" 是提交檔案時必須要加的屬性,不然後臺的Controller是獲取不到這個檔案

accept="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"是規定只能選取excel檔案

<form action="submitExcel" method="post" enctype="multipart/form-data">
                        <table>
                            <tr>
                                <td>根據excel表格錄入 :</td>
                                <td><input type="file" id="file" name="file" accept="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"></td>
                                <td><input type="submit" value="批量錄入"></td>
                            </tr>
                        </table>
                    </form>

2.Controller獲取請求

引數中可以寫很多種寫法我是直接寫MultipartFile file,這樣要求就是你前端頁面的檔案元件 name要是file

也可以@RequestParam(value="file") MultipartFile fileXXXX   要求是紅色的file是前端的name

@RequestMapping(value = "submitExcel",method = RequestMethod.POST)
    public void MatchExcel(HttpServletRequest request, HttpServletResponse response,MultipartFile file) throws IOException {
        //判斷檔案是否為空
        if(file==null) {return;}
        //獲取檔名
        String name=file.getOriginalFilename();
        //進一步判斷檔案是否為空(即判斷其大小是否為0或其名稱是否為null)
        long size=file.getSize();
        if(name==null || ("").equals(name) && size==0) {return;}

        //獲取專案web路徑,主要是臨時寫一個檔案在webapp目錄下
        String pic_path = request.getServletContext().getRealPath("/");
        //批量匯入。引數:檔名,檔案。
        int b = submitService.insertMatchesFromExcel(name,file,pic_path+"static"+"/excel");
        
if(b==0){
            String Msg ="批量匯入EXCEL成功!";request.getSession().setAttribute("msg",Msg);
        }else{
            String Msg ="批量匯入EXCEL失敗!";
            request.getSession().setAttribute("msg",Msg);
        }
        return;

        }

3.service服務層處理資料

建立一個下面的要寫的工具類,然後讀取檔案

public int insertMatchesFromExcel(String fileName, MultipartFile mfile, String systemPage) {        ReadExcel readExcel=new ReadExcel();//初始化一個EXCEL讀取物件
        List<MatchInfo> Mlist=null;
        Mlist=readExcel.getExcelInfo(fileName,mfile,systemPage);//讀取
        for (MatchInfo m:Mlist){
            System.out.println(m.getId());
        }
        return 0;
    }

4.工具類驗證檔案和進行資料的遍歷,解析,讀取等

4.1WDWutil類,函式是使用正則表示式判斷檔案是xls還是xlsx檔案

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)$");
    }
}
4.2READEXCEL工具類,真正處理資訊的類

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
     * @return
     */
    public List<MatchInfo> getExcelInfo(String fileName, MultipartFile Mfile,String systemPage){

        //把spring檔案上傳的MultipartFile轉換成CommonsMultipartFile型別
        CommonsMultipartFile cf= (CommonsMultipartFile)Mfile; //獲取本地儲存路徑
        File file = new  File(systemPage);//此檔案為存放的目錄
        //建立一個目錄 (它的路徑名由當前 File 物件指定,包括任一必須的父路徑。)
        if (!file.exists()) {file.mkdirs();}//存在則不會建立
        //新建一個檔案
        File file1 = new File(systemPage + "/"+new Date().getTime() + ".xlsx");
        //將上傳的檔案寫入新建的檔案中
        try {
            cf.getFileItem().write(file1);
        } catch (Exception e) {
            e.printStackTrace();
        }

        //初始化賽程資訊的集合
        List<MatchInfo> customerList=new ArrayList<MatchInfo>();
        //初始化輸入流
        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<MatchInfo> getExcelInfo(InputStream is,boolean isExcel2003){
        List<MatchInfo> 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<MatchInfo> readExcelValue(Workbook wb){
        //得到第一個shell,只讀取第一個sheet,多個sheet可以迴圈
        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<MatchInfo> customerList=new ArrayList<MatchInfo>();
        MatchInfo matchInfo;
        //迴圈Excel行數,從第二行開始。標題不入庫
        for(int r=1;r<totalRows;r++){
            Row row = sheet.getRow(r);
            if (row == null) {continue;}//為空跳過
            matchInfo = new MatchInfo();

            //迴圈Excel的列
            for(int c = 0; c <this.totalCells; c++){
                Cell cell = row.getCell(c);
                if (null != cell){
                    cell.setCellType(Cell.CELL_TYPE_STRING);//設定從EXCEL獲取的資料型別為String,否則容易讀取的時候要根據內容
                    進行getString型別的資料還是整數型別的判斷,容易報錯,這樣寫就可以後面獲取的資料都獲取成String再轉成其他型別就可以了
                    if(c==0){//第一列資料
                        matchInfo.setId(Long.valueOf(cell.getStringCellValue()));//獲取資料數值並由String轉成Long
                    }else if(c==1){//第二列資料
                        matchInfo.setSeason(cell.getStringCellValue());//獲取資料數值並賦值給MatchInfo的season屬性
                    }
                }
            }
            //新增該物件到物件集合中去
            customerList.add(matchInfo);
        }
        return customerList;
    }
}
        }

對EXCEL的讀取基本就完成了,大概就是上傳的檔案轉成File物件,然後用java已經有的EXCEL物件進行處理資料,除去驗證檔案型別等環節,基本就是file檔案讀取成excel物件,然後獲取行,列,讀值