Java 解析Excel文件為JSON


Excel轉Json的需求

反正我對SSM基本不會的情況下來到現在這家公司,都是90后,感覺很好。第二天就給我開發任務,就是把用戶上傳的Excel文件轉成JSON返回給前台用於大屏的數據展示。

解決方案

  • 方案1:百度一下,全是Java使用jxl去做的,我一開始也嘗試這樣做,但是卡死在一個地方,我們公司的SSM框架用戶上傳的File是MultipartFile的,它的流InputStream在構造Workbook時傳遞InputStream並不起作用,本地文件FileInputStream就可以,不知道是不是我無能,反正我沒轍了。這東西感覺本來就是javase的。

  • 方案2:問了個大神,告訴我一個詞叫POI。搗鼓了一天,終於解決了,對,解決方案就是 Apache的 POI(我的選擇方案)

Excel的xls和xlsx的差別

  • xls 是Excel 2007以下版本的后綴名,但是所有excel都能打開,對應POI里HSSFWorkbook。

  • xlsx 是Excel 2007及以上版本的后綴名,對應POI里XSSFWorkbook。

需要的JAR包

如果只需要支持 xls
poi-3.9.jar
如果只需要支持 xlsx
poi-ooxml-3.8.jar
poi-ooxml-schemas-3.10-FINAL.jar
xmlbeans.jar
dom4j-1.6.1-hudson-1.jar

我的工具代碼

import com.alibaba.fastjson.JSON;
import org.apache.poi.hssf.usermodel.*;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFDataFormat;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;

/**
 * Created by huangzheng on 2016/11/29.
 */
public class ExcelUtils {
    /**
     * 解決思路:采用Apache的POI的API來操作Excel,讀取內容后保存到List中,再將List轉Json(推薦Linked,增刪快,與Excel表順序保持一致)
     *
     *          Sheet表1  ————>    List1<Map<列頭,列值>>
     *          Sheet表2  ————>    List2<Map<列頭,列值>>
     *
     * 步驟1:根據Excel版本類型創建對於的Workbook以及CellSytle
     * 步驟2:遍歷每一個表中的每一行的每一列
     * 步驟3:一個sheet表就是一個Json,多表就多Json,對應一個 List
     *       一個sheet表的一行數據就是一個 Map
     *       一行中的一列,就把當前列頭為key,列值為value存到該列的Map中
     *
     *
     * @param file  SSM框架下用戶上傳的Excel文件
     * @return Map  一個線性HashMap,以Excel的sheet表順序,並以sheet表明作為key,sheet表轉換json后的字符串作為value
     * @throws IOException
     */
    public static LinkedHashMap<String,String> excel2json(MultipartFile file) throws IOException {

        System.out.println("excel2json方法執行....");

        // 返回的map
        LinkedHashMap<String,String> excelMap = new LinkedHashMap<>();

        // Excel列的樣式,主要是為了解決Excel數字科學計數的問題
        CellStyle cellStyle;
        // 根據Excel構成的對象
        Workbook wb;
        // 如果是2007及以上版本,則使用想要的Workbook以及CellStyle
        if(file.getOriginalFilename().endsWith("xlsx")){
            System.out.println("是2007及以上版本  xlsx");
            wb = new XSSFWorkbook(file.getInputStream());
            XSSFDataFormat dataFormat = (XSSFDataFormat) wb.createDataFormat();
            cellStyle = wb.createCellStyle();
            // 設置Excel列的樣式為文本
            cellStyle.setDataFormat(dataFormat.getFormat("@"));
        }else{
            System.out.println("是2007以下版本  xls");
            POIFSFileSystem fs = new POIFSFileSystem(file.getInputStream());
            wb = new HSSFWorkbook(fs);
            HSSFDataFormat dataFormat = (HSSFDataFormat) wb.createDataFormat();
            cellStyle = wb.createCellStyle();
            // 設置Excel列的樣式為文本
            cellStyle.setDataFormat(dataFormat.getFormat("@"));
        }

        // sheet表個數
        int sheetsCounts = wb.getNumberOfSheets();
        // 遍歷每一個sheet
        for (int i = 0; i < sheetsCounts; i++) {
            Sheet sheet = wb.getSheetAt(i);
            System.out.println("第" + i + "個sheet:" + sheet.toString());

            // 一個sheet表對於一個List
            List list = new LinkedList();

            // 將第一行的列值作為正個json的key
            String[] cellNames;
            // 取第一行列的值作為key
            Row fisrtRow = sheet.getRow(0);
            // 如果第一行就為空,則是空sheet表,該表跳過
            if(null == fisrtRow){
                continue;
            }
            // 得到第一行有多少列
            int curCellNum = fisrtRow.getLastCellNum();
            System.out.println("第一行的列數:" + curCellNum);
            // 根據第一行的列數來生成列頭數組
            cellNames = new String[curCellNum];
            // 單獨處理第一行,取出第一行的每個列值放在數組中,就得到了整張表的JSON的key
            for (int m = 0; m < curCellNum; m++) {
                Cell cell = fisrtRow.getCell(m);
                // 設置該列的樣式是字符串
                cell.setCellStyle(cellStyle);
                cell.setCellType(Cell.CELL_TYPE_STRING);
                // 取得該列的字符串值
                cellNames[m] = cell.getStringCellValue();
            }
            for (String s : cellNames) {
                System.out.print("得到第" + i +" 張sheet表的列頭: " + s + ",");
            }
            System.out.println();

            // 從第二行起遍歷每一行
            int rowNum = sheet.getLastRowNum();
            System.out.println("總共有 " + rowNum + " 行");
            for (int j = 1; j <= rowNum; j++) {
                // 一行數據對於一個Map
                LinkedHashMap rowMap = new LinkedHashMap();
                // 取得某一行
                Row row = sheet.getRow(j);
                int cellNum = row.getLastCellNum();
                // 遍歷每一列
                for (int k = 0; k < cellNum; k++) {
                    Cell cell = row.getCell(k);

                    cell.setCellStyle(cellStyle);
                    cell.setCellType(Cell.CELL_TYPE_STRING);
                    // 保存該單元格的數據到該行中
        rowMap.put(cellNames[k],cell.getStringCellValue());
                }
                // 保存該行的數據到該表的List中
                list.add(rowMap);
            }
            // 將該sheet表的表名為key,List轉為json后的字符串為Value進行存儲
            excelMap.put(sheet.getSheetName(),JSON.toJSONString(list,false));
        }

        System.out.println("excel2json方法結束....");

        return excelMap;
    }

}

  


免責聲明!

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



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