1. 程式人生 > >在SSM下使用POI解析Excel資料並實現批量匯入到資料庫

在SSM下使用POI解析Excel資料並實現批量匯入到資料庫

暑假實習期間,作為一名Java後臺開發的小白實習生,專案組老大分發給我的一項任務就是實現在SSM下實現Excel資料的匯入/匯出,咱總不能手動Ctrl+C/Ctrl+V實現吧hhh,於是經過查閱資料,發現Apache的一個子專案POI可以幫助解析Office文件並實現需求。分享如下:

Apache POI是Apache軟體基金會的開源專案,POI提供API給Java程式對Microsoft Office格式檔案讀和寫的功能。本例中主要使用其中的兩個包:HSSF提供讀寫Microsoft Excel XLS(2003版本)格式檔案的功能。XSSF提供讀寫Microsoft Excel OOXML XLSX(2007版本)格式檔案的功能。

1、下載POI
首先進入POI首頁:http://poi.apache.org/`,之後點選download進入下載頁。
下載poi
下載一個3.16二進位制版,即編譯版,不想自己編譯,畢竟麻煩。圖中兩個下載版本的區別在於壓縮格式不同,請擇一下載。

2、解壓POI並加入專案lib中
若未參考文件,咱不知道需要哪些包匯入,so先一股腦兒匯入專案。全部解壓後如下:
所有的Jar
測試專案架構如下:
專案基本架構

3、設定測試環境
在本例中未編寫上傳Excel表的功能,僅在jsp頁面上點選,後臺處理器讀取特定位置的Excel檔案,然後解析,入庫。

3.1 、在MySql資料庫中建表
people表字段展示

3.2 、建立Excel表


為了測試2003和2007兩個版本,建立不同版本的測試表:

表內容如下:
這裡寫圖片描述

3.3、jsp頁面中設定觸發操作

觸發操作

3.4、生成Mapper檔案
資料庫中的資料表有新添成員people表,so重新配置下mybatis.generator然後重新生成新的mapper和pojo:

生成mapper檔案

在專案中得到對應people表的mapper類和pojo類:
這裡寫圖片描述

3.5、編寫解析入庫處理器
下面開始編寫處理器,這裡簡化處理,直接在handler中完成所有操作。更好地作法是在service層完成解析入庫的工作。

3.5.1、2003版本處理

@Autowired
    PeopleMapper peopleMapper;

    @RequestMapping("readXLS"
) public String readXLS() { InputStream is = null; HSSFWorkbook hssfWorkbook = null; try { // 1 開啟Excel檔案 is = new FileInputStream("d:\\excel\\people.xls"); // 2 通過POI的工作薄類解析xls檔案 hssfWorkbook = new HSSFWorkbook(is); } catch (Exception e) { is = null; e.printStackTrace(); } if (is == null) return "failed"; // 3 建立people物件準備接收資料 People people = new People(); // 4 迴圈工作表Sheet,一個excel中可能有多個sheet for (int numSheet = 0; numSheet < hssfWorkbook.getNumberOfSheets(); numSheet++) { HSSFSheet hssfSheet = hssfWorkbook.getSheetAt(numSheet); if (hssfSheet == null) { continue; } // 迴圈行Row,一個sheet中可以有多行 for (int rowNum = 1; rowNum <= hssfSheet.getLastRowNum(); rowNum++) { // 取得當前行的資料 HSSFRow hssfRow = hssfSheet.getRow(rowNum); if (hssfRow != null) { // 獲取單元格物件 HSSFCell id = hssfRow.getCell(0); HSSFCell name = hssfRow.getCell(1); HSSFCell sex = hssfRow.getCell(2); HSSFCell birthday = hssfRow.getCell(3); HSSFCell workday = hssfRow.getCell(4); // 全部先作為字串資料提取出來 String idstr = getValue(id); String namestr = getValue(name); String sexstr = getValue(sex); String birthdaystr = getValue(birthday); String workdaystr = getValue(workday); try { // 轉換並賦值給people // id是long型別 people.setId(Long.parseLong(idstr)); // name是String型別 people.setName(namestr); // sex是Boolean型別 if (sexstr.equals("男")) { people.setSex(true); } else if (sexstr.equals("女")) { people.setSex(false); } // birthday是日期型 SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd"); people.setBirthday(sdf.parse(birthdaystr)); people.setWorkday(sdf.parse(workdaystr)); // 入庫 peopleMapper.insert(people); } catch (Exception e) { } } // 結束不為空的行的處理 } // 結束迴圈處理row } // 結束迴圈處理sheet // 關閉EXCEL表 try { hssfWorkbook.close(); } catch (Exception e) { } return "success"; } //對應版本讀取資料的函式 private String getValue(HSSFCell hssfCell) { if (hssfCell.getCellTypeEnum() == CellType.BOOLEAN) { // 返回布林型別的值 return String.valueOf(hssfCell.getBooleanCellValue()); } else if (hssfCell.getCellTypeEnum() == CellType.NUMERIC) { // 返回數值型別的值,日期型別的資料在EXCEL表中也是數值型 String cellValue = ""; if (HSSFDateUtil.isCellDateFormatted(hssfCell)) { // 判斷是日期型別 SimpleDateFormat dateformat = new SimpleDateFormat("yyyy/MM/dd"); Date dt = HSSFDateUtil.getJavaDate(hssfCell.getNumericCellValue());// 獲取成DATE型別 cellValue = dateformat.format(dt); } else { DecimalFormat df = new DecimalFormat("0"); cellValue = df.format(hssfCell.getNumericCellValue()); } return cellValue; } else if (hssfCell.getCellTypeEnum() == CellType._NONE) { return ""; } else if (hssfCell.getCellTypeEnum() == CellType.BLANK) { return ""; } else if (hssfCell.getCellTypeEnum() == CellType.STRING) { // 返回字串型別的值 return String.valueOf(hssfCell.getStringCellValue()); } return null; }

3.5.1、2007版本處理

@RequestMapping("readXLSX")
    public String readXLSX() {

        InputStream is = null;
        XSSFWorkbook xssfWorkbook = null;
        try {
            // 1 開啟Excel檔案
            is = new FileInputStream("d:\\excel\\people.xlsx");

            // 2 通過POI的工作薄類解析xls檔案
            xssfWorkbook = new XSSFWorkbook(is);

        } catch (Exception e) {
            is = null;
            e.printStackTrace();
        }

        if (is == null)
            return "failed";

        // 3 建立people物件準備接收資料
        People people = new People();

        // 4 迴圈工作表Sheet,一個excel中可能有多個sheet
        for (int numSheet = 0; numSheet < xssfWorkbook.getNumberOfSheets(); numSheet++) {
            XSSFSheet xssfSheet = xssfWorkbook.getSheetAt(numSheet);
            if (xssfSheet == null) {
                continue;
            }
            // 迴圈行Row,一個sheet中可以有多行
            for (int rowNum = 1; rowNum <= xssfSheet.getLastRowNum(); rowNum++) {

                // 取得當前行的資料
                XSSFRow xssfRow = xssfSheet.getRow(rowNum);
                if (xssfRow != null) {

                    // 獲取單元格物件
                    XSSFCell id = xssfRow.getCell(0);
                    XSSFCell name = xssfRow.getCell(1);
                    XSSFCell sex = xssfRow.getCell(2);
                    XSSFCell birthday = xssfRow.getCell(3);
                    XSSFCell workday = xssfRow.getCell(4);

                    // 全部先作為字串資料提取出來
                    String idstr = getXValue(id);
                    String namestr = getXValue(name);
                    String sexstr = getXValue(sex);
                    String birthdaystr = getXValue(birthday);
                    String workdaystr = getXValue(workday);

                    try {
                        // 轉換並賦值給people
                        // id是long型別
                        people.setId(Long.parseLong(idstr));

                        // name是String型別
                        people.setName(namestr);

                        // sex是Boolean型別
                        if (sexstr.equals("男")) {
                            people.setSex(true);
                        } else if (sexstr.equals("女")) {
                            people.setSex(false);
                        }

                        // birthday是日期型
                        SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd");
                        people.setBirthday(sdf.parse(birthdaystr));
                        people.setWorkday(sdf.parse(workdaystr));

                        // 入庫
                        peopleMapper.insert(people);
                    } catch (Exception e) {

                    }
                } // 結束不為空的行的處理
            } // 結束迴圈處理row
        } // 結束迴圈處理sheet

        // 關閉EXCEL表
        try {
            xssfWorkbook.close();
        } catch (Exception e) {

        }

        return "success";
    }

//對應版本讀取資料的函式
private String getXValue(XSSFCell xssfCell) {

        if (xssfCell.getCellTypeEnum() == CellType.BOOLEAN) {
            // 返回布林型別的值
            return String.valueOf(xssfCell.getBooleanCellValue());
        } else if (xssfCell.getCellTypeEnum() == CellType.NUMERIC) {
            // 返回數值型別的值,日期型別的資料在EXCEL表中也是數值型
            String cellValue = "";
            if (HSSFDateUtil.isCellDateFormatted(xssfCell)) { // 判斷是日期型別
                SimpleDateFormat dateformat = new SimpleDateFormat("yyyy/MM/dd");
                Date dt = HSSFDateUtil.getJavaDate(xssfCell.getNumericCellValue());// 獲取成DATE型別
                cellValue = dateformat.format(dt);
            } else {
                DecimalFormat df = new DecimalFormat("0");
                cellValue = df.format(xssfCell.getNumericCellValue());
            }
            return cellValue;
        } else if (xssfCell.getCellTypeEnum() == CellType._NONE) {
            return "";
        } else if (xssfCell.getCellTypeEnum() == CellType.BLANK) {
            return "";
        } else if (xssfCell.getCellTypeEnum() == CellType.STRING) {
            // 返回字串型別的值
            return String.valueOf(xssfCell.getStringCellValue());
        }
        return null;
    }

3.6、觸發操作
將專案部署到tomcat上啟動index.jsp 並觸發響應的操作,DB中的資料表有以下變化:
former:
這裡寫圖片描述
latter:
這裡寫圖片描述

感謝各位看官閱讀本例,若有疑問,歡迎留言討論,嘻嘻。