Java poi 處理 Excel 文件

一谱净、引入依賴

<!-- POI 支持,適用于高版本擅威,即 xlsx 為后綴的 Excel 表格 -->
  <dependency>
        <groupId>org.apache.poi</groupId>
            <artifactId>poi</artifactId>
            <version>4.1.2</version>
        </dependency>
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-ooxml</artifactId>
            <version>4.1.2</version>
        </dependency>

二壕探、編寫工具類

import lombok.extern.slf4j.Slf4j;
import org.apache.poi.hssf.usermodel.HSSFDataFormat;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.io.InputStream;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * add by sn
 */
@Slf4j
public class AnalysisExcelUtil {

    public static Workbook getWorkBook(MultipartFile file){
        // get fileName
        String fileName = file.getOriginalFilename();
        // create workbook
        Workbook workbook = null;
        try {
            InputStream is = file.getInputStream();
            // 根據(jù)文件名后綴不同獲得不同的 workbook 實現(xiàn)類對象
            if (fileName.endsWith("xls")) {
                // 2003
                workbook = new HSSFWorkbook(is);
            } else if (fileName.endsWith("xlsx")) {
                // 2007 or higher
                workbook = new XSSFWorkbook(is);
            }
        } catch (IOException e) {
            log.error(e.getMessage());
        }
        return workbook;
    }

    public static boolean rowIsEmpty(Row row) {
        if (null == row) {
            return true;
        }
        for (int c = row.getFirstCellNum(); c < row.getLastCellNum(); c++) {
            Cell cell = row.getCell(c);
            if (cell != null && cell.getCellType() != CellType.BLANK) {
                return false;
            }
        }
        return true;
    }

    public static String getCellValue(Cell cell) {
        String cellValue = "";
        if (cell == null) {
            return cellValue;
        }
        switch (cell.getCellType()) {
            case NUMERIC:
                // 數(shù)字
                cellValue = stringDateProcess(cell);
                break;
            case STRING:
                // 字符串
                cellValue = String.valueOf(cell.getStringCellValue());
                break;
            case BOOLEAN:
                // boolean
                cellValue = String.valueOf(cell.getBooleanCellValue());
                break;
            case FORMULA:
                // 公式
                cellValue = String.valueOf(cell.getCellFormula());
                break;
            case BLANK:
                // 空值
                cellValue = "";
                break;
            case ERROR:
                // 故障
                cellValue = "非法字符";
                break;
            default:
                cellValue = "未知類型";
                break;
        }
        return cellValue;
    }

    public static String stringDateProcess(Cell cell) {
        String result = new String();
        if (DateUtil.isCellDateFormatted(cell)) {
            // 處理日期格式、時間格式
            SimpleDateFormat sdf = null;
            if (cell.getCellStyle().getDataFormat() == HSSFDataFormat.getBuiltinFormat("h:mm")) {
                sdf = new SimpleDateFormat("HH:mm");
            } else {
                // 日期
                sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            }
            Date date = cell.getDateCellValue();
            result = sdf.format(date);
        } else if (cell.getCellStyle().getDataFormat() == 58) {
            // 處理自定義日期:m月d日(通過判斷單元格的格式id解決郊丛,id的值是58)
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            double value = cell.getNumericCellValue();
            Date date = DateUtil.getJavaDate(value);
            result = sdf.format(date);
        } else {
            double value = cell.getNumericCellValue();
            CellStyle style = cell.getCellStyle();
            DecimalFormat format = new DecimalFormat();
            String temp = style.getDataFormatString();
            // 單元格設(shè)置成常規(guī)
            if (temp.equals("General")) {
                format.applyPattern("#");
            }
            result = format.format(value);
        }

        return result;
    }

    public static boolean checkFile(MultipartFile file) {
        if (null == file) {
            log.error("文件不存在李请!");
            return false;
        }
        // 獲取文件名
        String fileName = file.getOriginalFilename();
        // 判斷文件是否是 excel 文件
        if (!fileName.endsWith("xls") && !fileName.endsWith("xlsx")) {
            log.error(fileName + "不是 excel 文件瞧筛!");
            return false;
        }
        return true;
    }
}

三、使用工具方法處理上傳的 excel 文件

/**
     * 從上傳的 xlsx 中獲取到對應(yīng)列的數(shù)據(jù)
     * 第一列是sessionId导盅,第二列是時間
     * @param startRow 指定開始的行
     * @param file 上傳的文件
     * @return
     */
    public Response<Map<String, String>> getExcelData(MultipartFile file, int startRow) throws IOException {
        Map<String, String> resultMap = new HashMap<>();
        if (!AnalysisExcelUtil.checkFile(file)) {
            log.error("上傳的excel 文件格式有問題");
            return Response.error("上傳的excel 文件格式有問題");
        }
        // 獲取 workbook 工作簿對象
        Workbook workbook = AnalysisExcelUtil.getWorkBook(file);
        if (workbook != null) {
            // get first sheet
            Sheet sheet = workbook.getSheetAt(0);
            if (sheet == null) {
                return Response.error("第一個Sheet為空");
            }

            // 獲取當(dāng)前 sheet 的開始行
            int firstRowNum = sheet.getFirstRowNum();
            // 獲取當(dāng)前 sheet 的結(jié)束行
            int lastRowNum = sheet.getLastRowNum();
            // 循環(huán)除了 startRow 的所有行较幌,如果要循環(huán)除第一行外的就 firstRowNum + 1
            for (int rowNum = firstRowNum + startRow; rowNum <= lastRowNum; rowNum++) {
                // 獲取當(dāng)前行
                Row row = sheet.getRow(rowNum);
                if (AnalysisExcelUtil.rowIsEmpty(row)) {
                    break;
                }
                // 獲取當(dāng)前行的開始列
                int firstCellNum = row.getFirstCellNum();
                // 獲取當(dāng)前行的列數(shù)
                int lastCellNum = row.getLastCellNum();
                Map<String, String> cellMap = new HashMap<>(2);

                Cell cell0 = row.getCell(0);
                Cell cell1 = row.getCell(1);
                resultMap.put(AnalysisExcelUtil.getCellValue(cell0), AnalysisExcelUtil.getCellValue(cell1));
            }
            workbook.close();
        }
        return Response.success(resultMap);
    }
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市白翻,隨后出現(xiàn)的幾起案子乍炉,更是在濱河造成了極大的恐慌,老刑警劉巖滤馍,帶你破解...
    沈念sama閱讀 212,542評論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件岛琼,死亡現(xiàn)場離奇詭異,居然都是意外死亡纪蜒,警方通過查閱死者的電腦和手機衷恭,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,596評論 3 385
  • 文/潘曉璐 我一進(jìn)店門此叠,熙熙樓的掌柜王于貴愁眉苦臉地迎上來纯续,“玉大人,你說我怎么就攤上這事灭袁♀恚” “怎么了?”我有些...
    開封第一講書人閱讀 158,021評論 0 348
  • 文/不壞的土叔 我叫張陵茸歧,是天一觀的道長倦炒。 經(jīng)常有香客問我,道長软瞎,這世上最難降的妖魔是什么逢唤? 我笑而不...
    開封第一講書人閱讀 56,682評論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮涤浇,結(jié)果婚禮上鳖藕,老公的妹妹穿的比我還像新娘。我一直安慰自己只锭,他們只是感情好著恩,可當(dāng)我...
    茶點故事閱讀 65,792評論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著蜻展,像睡著了一般喉誊。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上纵顾,一...
    開封第一講書人閱讀 49,985評論 1 291
  • 那天伍茄,我揣著相機與錄音,去河邊找鬼施逾。 笑死敷矫,一個胖子當(dāng)著我的面吹牛贞盯,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播沪饺,決...
    沈念sama閱讀 39,107評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼躏敢,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了整葡?” 一聲冷哼從身側(cè)響起件余,我...
    開封第一講書人閱讀 37,845評論 0 268
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎遭居,沒想到半個月后啼器,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,299評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,612評論 2 327
  • 正文 我和宋清朗相戀三年姆涩,在試婚紗的時候發(fā)現(xiàn)自己被綠了呈队。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,747評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡损谦,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出岳颇,到底是詐尸還是另有隱情照捡,我是刑警寧澤,帶...
    沈念sama閱讀 34,441評論 4 333
  • 正文 年R本政府宣布话侧,位于F島的核電站栗精,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏瞻鹏。R本人自食惡果不足惜悲立,卻給世界環(huán)境...
    茶點故事閱讀 40,072評論 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望新博。 院中可真熱鬧薪夕,春花似錦、人聲如沸叭披。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,828評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽涩蜘。三九已至嚼贡,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間同诫,已是汗流浹背粤策。 一陣腳步聲響...
    開封第一講書人閱讀 32,069評論 1 267
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留误窖,地道東北人叮盘。 一個月前我還...
    沈念sama閱讀 46,545評論 2 362
  • 正文 我出身青樓秩贰,卻偏偏與公主長得像,于是被迫代替她去往敵國和親柔吼。 傳聞我的和親對象是個殘疾皇子毒费,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,658評論 2 350

推薦閱讀更多精彩內(nèi)容