Java 基於Apache POI實現Excel讀寫操作

来源:https://www.cnblogs.com/shouke/archive/2023/07/31/17592428.html
-Advertisement-
Play Games

## 實踐環境 Win10 Java JDK1.8 ## 代碼實現 pom.xml配置 ```xml 4.0.0 com.shouke example 1.0 1.8 ${java.version} ${java.version} 4.1.2 org.apache.poi poi-ooxml ${p ...


實踐環境

Win10

Java JDK1.8

代碼實現

pom.xml配置

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.shouke</groupId>
    <artifactId>example</artifactId>
    <version>1.0</version>

    <properties>
        <java.version>1.8</java.version>
        <maven.compiler.source>${java.version}</maven.compiler.source>
        <maven.compiler.target>${java.version}</maven.compiler.target>
        <poi.ooxml.version>4.1.2</poi.ooxml.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-ooxml</artifactId>
            <version>${poi.ooxml.version}</version>
        </dependency>
    <dependencies>        
</project>

讀取Excel

代碼實現

exmple.xml

import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

import java.io.FileInputStream;
import java.util.Iterator;

public class JavaStudy {
    public static void readExcel(String filePath) throws Exception {
        //獲取文件流
        FileInputStream inputStream = new FileInputStream(filePath);

        //1.創建工作簿
        Workbook workbook = new XSSFWorkbook(inputStream);

        //2.得到Sheet表
//        Sheet sheet = workbook.getSheet("Sheet1"); // 通過Sheet名稱獲取
        Sheet sheet = workbook.getSheetAt(0); // 通過索引獲取 //獲取第1個Sheet表

        //3.獲取行
        Row row = sheet.getRow(0); // 獲取第1行 // 註意:行索引從0開始
        System.out.println(sheet.getFirstRowNum()); // 獲取首行(內容行)索引  // 輸出:0
        System.out.println(sheet.getLastRowNum()); // 獲取最後行(內容行)索引 // 輸出:5

        //4.獲取單元格
        Cell cell = row.getCell(0); // 獲取行的第0個元

        //5.獲取單元格的值
        System.out.println(getValue(cell)); // 輸出:姓名

        System.out.println(row.getFirstCellNum()); // 獲取當前行第一個內容單元格索引 // 輸出:0
        System.out.println(row.getLastCellNum()); // 獲取當前行最後內容單元格往後下一個單元格的索引 // 輸出:7 // 輸出值為:最後內容單元格索引+1

        // 遍歷當前行內容化單元格
        // 方法1:
        Iterator<Cell> cellIterator = row.cellIterator();
        while (cellIterator.hasNext()) {
            cell = cellIterator.next();
            System.out.println(cell);
        }

        // 方法2:
        row.forEach(currCell -> {
            System.out.print(currCell+", ");
            System.out.println(currCell.getCellType());
        });


        // 遍歷獲取所有內容行單元格的值
        for (int rowIndex=0; rowIndex<=sheet.getLastRowNum(); rowIndex++) {
            row = sheet.getRow(rowIndex);
            for(int colIndex=0; colIndex<row.getLastCellNum(); colIndex++) {
                System.out.println(getValue(row.getCell(colIndex)));
            }
        }


        inputStream.close();
    }

    public static Object getValue(Cell cell) {
        //匹配類型數據
        Object cellValue = null;
        if (cell != null) { // 單元格未經過編輯的情況下,一定為null //cell為null的情況下,對空單元格調用API會導致上述for迴圈提前結束
            CellType cellType = cell.getCellType(); // 獲取單元格數值類型
            switch (cellType) {
                case STRING: //字元串
                    System.out.print("String類型:");
                    cellValue = cell.getStringCellValue();
                    break;
                case BOOLEAN: //布爾類型
                    System.out.print("Boolean類型:");
                    cellValue = cell.getBooleanCellValue();
                    break;
                case BLANK: //空
                    System.out.print("BLANK類型:"); // 填寫值後,請清理掉值,從沒填過值,那麼cell=null,合併的單元格被當做一個單元格
                    break;
                case NUMERIC: //數字(整數、小數、日期)
                    System.out.print("NUMERIC類型:");
                    if (DateUtil.isCellDateFormatted(cell)) { //日期
                        System.out.print("日期:");
                        cellValue = cell.getDateCellValue(); // cell.getDateCellValue() 返回Date類型數據
                    } else {
                        System.out.print("數字:");
                        cellValue = cell.getNumericCellValue();
                        System.out.println(1.0E50 == (Double) cellValue);
                    }
                    break;
                case FORMULA:
                    System.out.print("公式類型:");
                    cellValue = cell.getCellFormula();
                    break;
                case ERROR:
                    System.out.print("數據類型錯誤");
                    break;
            }
        } else {
            System.out.println("cell為空");
        }
        return cellValue;
    }

    // 測試
    public static void  main(String[] args) {
        try{
            JavaStudy.readExcel("D:\\codePojects\\Study\\src\\main\\resource\\example.xlsx");
        } catch (Exception e) {

        }
    }

}

補充說明

創建工作簿

POI創建工作簿的API有3種:

  • HSSFWorkbook: 此API用於操作Excel 2003及之前的版本(文件擴展名.xls),優點是導出速度快,缺點是導出的行數有局限性,最多為65535行,超出65536條後系統就會報錯。對記憶體消耗比較大,容易造成記憶體溢出(OOM)。

  • XSSFWorkbook: 此API用於操作Excel 2007及往後的版本(文件擴展名.xlsx),優點是導出的數據行數突破65535,最大可導出1048576行,缺點導出速度慢,對記憶體消耗比較大,容易造成記憶體溢出(OOM)。

  • SXSSFWorkbook:POI3.8開始,新增此API,是 XSSFWorkbook API的相容流式擴展,主要解決當使用 XSSFWorkbook 方式導出大數據量時,記憶體溢出的問題,支持導出大量的數據。其原理就是使用硬碟空間代替記憶體:僅保存最新的數據行在記憶體里供查看,在此之前的數據行都會被寫入到硬碟里(Windows電腦的話,是寫入到C盤根目錄下的temp文件夾)。被寫入到硬碟里的數據行是不可見的/不可訪問的。只有還保存在記憶體里的才可以被訪問到。

XSSFWorkbook API為例,可以通過多種方式來創建工作簿,常見用法如下:

//獲取文件流
FileInputStream inputStream = new FileInputStream(excelFilePath);
//創建工作簿
Workbook workbook = new XSSFWorkbook(inputStream);

// 或者
//創建文件
File file = new File(excelFilePath);
Workbook workbook = new XSSFWorkbook(file);

// 或者
Workbook workbook = new XSSFWorkbook(excelFilePath);
獲取單元格類型
CellType getCellType();

返回類型為CellType,在org.apache.poi.ss.usermodel.CellType中定義,它是一個枚舉類型,源碼如下:

public enum CellType {
    @Internal(
        since = "POI 3.15 beta 3"
    )
    _NONE(-1),
    NUMERIC(0), // // 數字(整數、小數、日期)
    STRING(1),
    FORMULA(2), // 公式,即單元格內容通過公式計算出來
    BLANK(3), // 為空//什麼時候會存儲空值,取決於所使用的表格軟體
    BOOLEAN(4),
    ERROR(5);

寫入Excel

import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

import java.io.FileOutputStream;
import java.io.IOException;

public class JavaStudy {
    public static void writeExcel(String filePath) throws IOException {
        Workbook workbook = new XSSFWorkbook();
//        Sheet sheet =  workbook.createSheet();
        Sheet sheet = workbook.createSheet("study"); // 創建Sheet時指定Sheet名詞
        Row row = sheet.createRow(0);  // 創建第1行
        Cell firstCell = row.createCell(0); // 創建第1個單元格
        firstCell.setCellValue("hello");  // 設置單元格的值
        Cell secondCell = row.createCell(1); // 創建第2個單元格
        secondCell.setCellValue("shouke");

        row = sheet.createRow(1);   // 創建第2行
        firstCell = row.createCell(0, CellType.STRING);  // 設置單元格的值和類型
        firstCell.setCellValue("你好");
        secondCell = row.createCell(1, CellType.NUMERIC); // 創建第2個單元格
        secondCell.setCellValue(2023);


        FileOutputStream fileOutputStream = new FileOutputStream(filePath); // 如果文件已存在,則覆蓋已有文件
        workbook.write(fileOutputStream);
        fileOutputStream.close();
        workbook.close();
    }

    // 測試
    public static void  main(String[] args) {
        try{
            JavaStudy.writeExcel("D:\\codePojects\\Study\\src\\main\\resource\\result.xlsx");
        } catch (Exception e) {

        }
    }

}

生成Excel文件內容如下:

作者:授客
微信/QQ:1033553122
全國軟體測試QQ交流群:7156436

Git地址:https://gitee.com/ishouke
友情提示:限於時間倉促,文中可能存在錯誤,歡迎指正、評論!
作者五行缺錢,如果覺得文章對您有幫助,請掃描下邊的二維碼打賞作者,金額隨意,您的支持將是我繼續創作的源動力,打賞後如有任何疑問,請聯繫我!!!
           微信打賞                        支付寶打賞                  全國軟體測試交流QQ群  
              


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 一、插入數據優化 1.1 批量插入 如果有多條數據需要同時插入,不要每次插入一條,然後分多次插入,因為每執行一次插入的操作,都要進行資料庫的連接,多個操作就會連接多次,而一次批量操作只需要連接1次 1.2 手動提交事務 因為Mysql預設每執行一次操作,就會提交一次事務,這樣就會涉及到頻繁的事務的開 ...
  • “莆仙小館”——莆田文化展示APP 文化展示程式目的在於應用科學技術助推家鄉優秀傳統文化的展示與交流。通過圖片、視頻、音頻等展示方式向用戶立體地展示一個文化城邦。傳統文化與科學技術的有效融合,順應了社會發展的需要。傳統文化與科學技術的有效融合是發展中國特色社會主義文化的客觀需要,是傳承中國優秀傳統文 ...
  • # 解決方案 使用`ngClass`和`ngStyle`可以進行樣式的綁定。 ## ngStyle的使用 ngStyle 根據組件中的變數, isTextColorRed和fontSize的值來動態設置元素的顏色和字體大小 ```HTML This text has dynamic styles b ...
  • 在本篇文章中,我們詳細介紹了 Flutter 進階的主題,包括導航和路由、狀態管理、非同步處理、HTTP請求和Rest API,以及數據持久化。這些主題在實際應用中都非常重要,幫助你構建更複雜、功能更強大的 Flutter 應用。 ...
  • 在SpringBoot的Controller中,可以使用註解@RequestBody來獲取POST請求中的JSON數據。我們可以將這個註解應用到一個Controller方法的參數上,Spring將會負責讀取請求正文中的數據,將其反序列化為一個Java對象,並將其作為Controller方法的參數傳遞 ...
  • 對於從事後端開發的同學來說,線程安全問題是我們每天都需要考慮的問題。 線程安全問題通俗地講主要是在多線程的環境下,不同線程同時讀和寫公共資源(臨界資源)導致的數據異常問題。 比如:變數a=0,線程1給該變數+1,線程2也給該變數+1。此時,線程3獲取a的值有可能不是2,而是1。線程3這不就獲取了錯誤 ...
  • ### 歡迎訪問我的GitHub > 這裡分類和彙總了欣宸的全部原創(含配套源碼):[https://github.com/zq2599/blog_demos](https://github.com/zq2599/blog_demos) ### 關於bean的作用域(scope) - 官方資料:ht ...
  • ## 開篇-為什麼要使用線程池? ​ Java 中的線程池是運用場景最多的併發框架,幾乎所有需要非同步或併發執行任務的程式都可以使用線程池。在開發過程中,合理地使用線程池能夠帶來 3 個好處。 ​ 第一:降低資源消耗。通過重覆利用已創建的線程降低線程創建和銷毀造成的消耗。 ​ 第二:提高響應速度。當任 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...