欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java操作Excel文件解析與讀寫方法詳解

 更新時間:2022年11月07日 11:59:13   作者:OlaiolaiO  
相信現(xiàn)在很多搞后端的同學大部分做的都是后臺管理系統(tǒng),那么管理系統(tǒng)就肯定免不了Excel的導出導入功能,下面這篇文章主要給大家介紹了關(guān)于Java簡單使用EasyExcel操作讀寫與解析的步驟與要點,需要的朋友可以參考下

一、概述

在應用程序的開發(fā)過程中,經(jīng)常需要使用 Excel 文件來進行數(shù)據(jù)的導入或?qū)С?。所以,在通過Java語言實現(xiàn)此 類需求的時候,往往會面臨著Excel文件的解析(導入)或生成(導出)。

在Java技術(shù)生態(tài)圈中,可以進行Excel文件處理的主流技術(shù)包括: Apache POI 、 JXL 、 Alibaba EasyExcel 等。

二、Apache POI

Apache POI 是用 Java 編寫的免費開源的跨平臺的 Java API , Apache POI 提供 給 Java 程序?qū)?Microsoft Office 格式檔案進行讀寫功能的 API 開源類庫。

它分別提供對不同格式文件的解析:

  • HSSF - 提供讀寫Microsoft Excel格式檔案的功能。
  • XSSF - 提供讀寫Microsoft Excel OOXML格式檔案的功能。
  • HWPF - 提供讀寫Microsoft Word格式檔案的功能。
  • HSLF - 提供讀寫Microsoft PowerPoint格式檔案的功能。
  • HDGF - 提供讀寫Microsoft Visio格式檔案的功能。

三、XSSF解析Excel文件

HSSF 用于解析舊版本(*.xls)Excel文件,由于舊版本的Excel文件只能存在65535行數(shù)據(jù),所以目前已經(jīng)不常用。所以 目前主要采用 XSSF 進行新版本(*.xlsx)Exce文件的解析。

1.Workbook(Excel文件)

Workbook 接口代表一個 Excel 文件,用于創(chuàng)建或加載(解析) Excel 文件。常見實現(xiàn)類是 XSSFWorkbook 。

創(chuàng)建Excel文件

try (Workbook workbook = new XSSFWorkbook();
				FileOutputStream fos = new FileOutputStream("c:\\test\\temp.xlsx")) {
    workbook.write(fos);
} catch (IOException e) {
    e.printStackTrace();
}

解析Excel文件

// 輸入流
FileInputStream fis = new FileInputStream("c:\\test\\1627356554991.xlsx");
// Excel文件對象
Workbook workbook = new XSSFWorkbook(fis);

2.Sheet(工作簿)

通過 Workbook 來進行工作簿 Sheet 對象的獲取或創(chuàng)建

創(chuàng)建工作簿

// 按照默認名稱創(chuàng)建工作簿
Sheet sheet1 = workbook.createSheet();
// 按照自定義名稱創(chuàng)建工作簿
Sheet sheet2 = workbook.createSheet("自定義工作簿2");

獲取工作簿

// 按照工作簿下標獲取Sheet
Sheet sheet01 = workbook.getSheetAt(0);
// 按照工作簿名稱獲取Sheet
Sheet sheet02 = workbook.getSheet("Sheet0");

獲取工作簿的數(shù)量

int n = workbook.getNumberOfSheets();

3.Row(數(shù)據(jù)行)

通過 Sheet 來進行數(shù)據(jù)行 Row 對象的獲取或創(chuàng)建

創(chuàng)建數(shù)據(jù)行

Row row = sheet.createRow(0);

獲取首行下標和尾行下標

int first = sheet.getFirstRowNum();
int last = sheet.getLastRowNum();

根據(jù)下標獲取指定行

Row row = sheet.getRow(0);

遍歷所有行

for(Row row : sheet) {
    System.out.println(row);
}

遍歷指定區(qū)域行

for (int i = 1; i <= sheet.getLastRowNum(); i++) {
    Row row = sheet.getRow(i);
    System.out.println(row);
}

4.Cell(單元格)

通過 Row 來進行單元格 Cell 對象的獲取或創(chuàng)建。

創(chuàng)建單元格

Cell cell0 = row.createCell(0);

設置單元格值

cell0.setCellValue(UUID.randomUUID().toString());

根據(jù)下標獲取單元格

Cell cell = row.getCell(1);

遍歷所有單元格

for(Cell cell : row) {}

獲取單元格的類型

CellType type = cell.getCellType();

設置單元格樣式

// 創(chuàng)建單元格樣式
DataFormat dataFormat = workbook.createDataFormat();
Short formatCode = dataFormat.getFormat("yyyy-MM-dd HH:mm:ss");
CellStyle cellStyle = workbook.createCellStyle();
cellStyle.setDataFormat(formatCode);
// 為當前行創(chuàng)建單元格
Cell cell1 = row.createCell(1);
cell1.setCellStyle(cellStyle); // 設置單元格樣式
cell1.setCellValue(new Date()); // 保存當前日期時間至本單元格

設置單元格對齊

// 創(chuàng)建單元格樣式
CellStyle cellStyle = workbook.createCellStyle();
//設置單元格的水平對齊類型。 此時水平居中
cellStyle.setAlignment(HorizontalAlignment.CENTER);
// 設置單元格的垂直對齊類型。 此時垂直靠底邊
cellStyle.setVerticalAlignment(VerticalAlignment.BOTTOM);

四、超大Excel文件讀寫

1.使用POI寫入

使用 SXSSFWorkbook 進行寫入,通過設置 SXXFWorkbook 的構(gòu)造參數(shù),可以設置每次在內(nèi)存中保持的行 數(shù),當達到這個值的時候,那么會把這些數(shù)據(jù) flush 到磁盤上,這樣就不會出現(xiàn)內(nèi)存不夠的情況。

try (Workbook workbook = new SXSSFWorkbook(100);
				FileOutputStream fos = new FileOutputStream("c:\\test\\temp.xlsx")) {
    Sheet sheet1 = workbook.createSheet();
    for (int i = 0; i <= 1000000; i++) {
        Row row = sheet1.createRow(i);
        Cell cell0 = row.createCell(0);
        cell0.setCellValue(UUID.randomUUID().toString());
        Cell cell1 = row.createCell(1);
        cell1.setCellValue(new Date());
    }
    workbook.write(fos);
} catch (IOException e) {
    e.printStackTrace();
}

但是讀取超大Excel時POI會把文件的所有內(nèi)容都加載到內(nèi)存中,很容易占用大量內(nèi)存;甚至發(fā)生out of memory異常。

2.使用EasyExcel

  • Java領域解析、生成Excel比較有名的框架有Apache poi、jxl等。但他們都存在一個嚴重的問題就是非常的耗內(nèi)存。如果你的系統(tǒng)并發(fā)量不大的話可能還行,但是一旦并發(fā)上來后一定會OOM或者JVM頻繁的full gc。
  • EasyExcel是阿里巴巴開源的一個excel處理框架,以使用簡單、節(jié)省內(nèi)存著稱。EasyExcel能大大減少占用內(nèi)存的主要原因是在解析Excel時沒有將文件數(shù)據(jù)一次性全部加載到內(nèi)存中,而是從磁盤上一行行讀取數(shù)據(jù),逐個解析。
  • EasyExcel采用一行一行的解析模式,并將一行的解析結(jié)果以觀察者的模式通知處理。

例:

//準備實體類
public class Order {
    @ExcelProperty("訂單編號")
	private String orderId; // 訂單編號
    @ExcelProperty("支付金額")
	@NumberFormat("¥#,###")
	private Double payment; // 支付金額
    @ExcelProperty(value = "創(chuàng)建日期",converter = LocalDateTimeConverter.class)
	private LocalDateTime creationTime; // 創(chuàng)建時間
	public Order() {
		this.orderId = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddhhmmss"))
				+ UUID.randomUUID().toString().substring(0, 5);
		this.payment = Math.random() * 10000;
		this.creationTime = LocalDateTime.now();
	}
	public String getOrderId() {
		return orderId;
	}
	public void setOrderId(String orderId) {
		this.orderId = orderId;
	}
	public Double getPayment() {
		return payment;
	}
	public void setPayment(Double payment) {
		this.payment = payment;
	}
	public LocalDateTime getCreationTime() {
		return creationTime;
	}
	public void setCreationTime(LocalDateTime creationTime) {
		this.creationTime = creationTime;
	}
	@Override
	public String toString() {
		return "Order [orderId=" + orderId + ", payment=" + payment + ", creationTime=" + creationTime + "]";
	}
}
//準備Converter轉(zhuǎn)換類
public class LocalDateTimeConverter implements Converter<LocalDateTime> {
	@Override
	public Class<LocalDateTime> supportJavaTypeKey() {
		return LocalDateTime.class;
	}
	@Override
	public CellDataTypeEnum supportExcelTypeKey() {
		return CellDataTypeEnum.STRING;
	}
	@Override
	public LocalDateTime convertToJavaData(CellData cellData, ExcelContentProperty contentProperty,
			GlobalConfiguration globalConfiguration) {
		return LocalDateTime.parse(cellData.getStringValue(), DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
	}
	@Override
	public CellData<String> convertToExcelData(LocalDateTime value, ExcelContentProperty contentProperty,
			GlobalConfiguration globalConfiguration) {
		return new CellData<>(value.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
	}
}

寫入數(shù)據(jù)

import java.util.ArrayList;
import java.util.List;
import com.alibaba.excel.EasyExcel;
public class Demo01 {
	public static void main(String[] args) {
		long begin = System.currentTimeMillis();
		// 寫入100w
        EasyExcel.write("D:\\java.workspace\\1000W.xlsx", Order.class)
                 .sheet("訂單列表")
                 .doWrite(data());
        long end = System.currentTimeMillis();
		System.out.println("共耗時"+(end-begin)+"毫秒");
    }
    // 創(chuàng)建100w條訂單數(shù)據(jù)
    private static List<Order> data() {
        List<Order> list = new ArrayList<Order>();
        for (int i = 0; i < 1000000; i++) {
            list.add(new Order());
        }
        return list;
    }
}

讀取數(shù)據(jù)

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
public class Demo02 {
	public static void main(String[] args) {
		//用于保存讀取到的結(jié)果
		List<Order> orderList = new ArrayList<Order>();
		//讀取
		EasyExcel.read("D:\\java.workspace\\1000W.xlsx", Order.class,new AnalysisEventListener<Order>() {
		    @Override
		    public void invoke(Order order, AnalysisContext arg1) {
		        // 讀取每條數(shù)據(jù)
		        orderList.add(order);
		    }
		    @Override
		    public void invokeHeadMap(Map<Integer, String> headMap, AnalysisContext context) {
		        // 讀取到列頭
		        System.out.println(headMap);
		    }
		    @Override
		    public void doAfterAllAnalysed(AnalysisContext arg0) {
		        // 讀取完畢
		        System.out.println("END");
		    }
		}).sheet().doRead();
		//遍歷
		for(Order order : orderList) {
			System.out.println(order);
		}
	}
}

到此這篇關(guān)于Java操作Excel文件解析與讀寫方法詳解的文章就介紹到這了,更多相關(guān)Java Excel文件解析內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java編程中二維數(shù)組的初始化和基本操作實例

    Java編程中二維數(shù)組的初始化和基本操作實例

    這篇文章主要介紹了Java編程中二維數(shù)組的初始化和基本操作實例,是Java入門學習中的基礎知識,需要的朋友可以參考下
    2015-10-10
  • JVM?運行時數(shù)據(jù)區(qū)與JMM?內(nèi)存模型

    JVM?運行時數(shù)據(jù)區(qū)與JMM?內(nèi)存模型

    這篇文章主要介紹了JVM?運行時數(shù)據(jù)區(qū)與JMM?內(nèi)存模型,文章圍繞主題展開詳細的內(nèi)容介紹,具有一定的參考價值。需要的朋友可以參考一下
    2022-07-07
  • Java HttpURLConnection使用方法詳解

    Java HttpURLConnection使用方法詳解

    這篇文章主要為大家詳細介紹了Java HttpURLConnection使用方法,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-11-11
  • Java如何實現(xiàn)簡單后臺訪問并獲取IP

    Java如何實現(xiàn)簡單后臺訪問并獲取IP

    這篇文章主要介紹了Java如何實現(xiàn)簡單后臺訪問并獲取IP,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-10-10
  • springboot讀取application.yml報錯問題及解決

    springboot讀取application.yml報錯問題及解決

    這篇文章主要介紹了springboot讀取application.yml報錯問題及解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-06-06
  • 詳解Java中NullPointerException異常的原因詳解以及解決方法

    詳解Java中NullPointerException異常的原因詳解以及解決方法

    這篇文章主要介紹了詳解Java中NullPointerException異常的原因詳解以及解決方法。文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-08-08
  • 關(guān)于SpringBoot接收json格式的Demo案例

    關(guān)于SpringBoot接收json格式的Demo案例

    這篇文章主要介紹了關(guān)于SpringBoot接收json格式的Demo案例,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-05-05
  • Spring?Data?Redis切換底層Jedis和Lettuce實現(xiàn)源碼解析

    Spring?Data?Redis切換底層Jedis和Lettuce實現(xiàn)源碼解析

    這篇文章主要為大家介紹了Spring?Data?Redis切換底層Jedis和Lettuce實現(xiàn)方法源碼解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-11-11
  • Java面試題沖刺第二十七天--JVM2

    Java面試題沖刺第二十七天--JVM2

    這篇文章主要為大家分享了最有價值的三道關(guān)于JVM的面試題,涵蓋內(nèi)容全面,包括數(shù)據(jù)結(jié)構(gòu)和算法相關(guān)的題目、經(jīng)典面試編程題等,感興趣的小伙伴們可以參考一下
    2021-08-08
  • Java+Ajax實現(xiàn)的用戶名重復檢驗功能實例詳解

    Java+Ajax實現(xiàn)的用戶名重復檢驗功能實例詳解

    這篇文章主要介紹了Java+Ajax實現(xiàn)的用戶名重復檢驗功能,結(jié)合實例形式詳細分析了java針對用戶名提交的ajax數(shù)據(jù)庫查詢與重復檢查功能相關(guān)實現(xiàn)技巧與操作注意事項,需要的朋友可以參考下
    2018-12-12

最新評論