Java利用Apache POI實(shí)現(xiàn)Excel文件讀寫操作
Apache POI是一個(gè)用于讀寫Microsoft Office文件格式的Java庫,可以用來讀取或?qū)懭隕xcel文件。
使用步驟
1.導(dǎo)入坐標(biāo)
<!--alibaba-fastjson-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>2.0.9.graal</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.commons/commons-compress -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-compress</artifactId>
<version>1.26.1</version>
</dependency>
<!-- Excel處理 -->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>4.1.2</version>
</dependency>2.封裝類
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import org.apache.poi.hssf.usermodel.HSSFDateUtil;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import java.io.*;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
public class ExcelHelper {
//文件后綴
private final static String XLSX = ".xlsx";
private final static String XLS = ".xls";
/**
* json數(shù)據(jù)導(dǎo)出Excel
*
* @param json json數(shù)據(jù)
* @param filepath 文件路徑
* @return true 導(dǎo)出成功
*/
public static boolean jsonToExcel(String json, String filepath) {
try {
JSONArray array = JSONArray.parseArray(json);
Workbook workbook = new XSSFWorkbook();
Sheet sheet = workbook.createSheet("Sheet1");
// 創(chuàng)建表頭
Row header = sheet.createRow(0);
JSONObject title = array.getJSONObject(0);
for (String s : title.keySet()) {
Cell cell = header.createCell(header.getLastCellNum() < 0 ? 0 : header.getLastCellNum());
cell.setCellValue(s);
}
// 填充數(shù)據(jù)
for (int i = 0; i < array.size(); i++) {
JSONObject object = array.getJSONObject(i);
Row row = sheet.createRow(i + 1);
int colNum = 0;
for (String key : object.keySet()) {
Object value = object.get(key);
row.createCell(colNum).setCellValue(String.valueOf(value));
colNum++;
}
}
// 導(dǎo)出到文件
OutputStream outputStream = new FileOutputStream(filepath);
workbook.write(outputStream);
workbook.close();
return true;
} catch (IOException e) {
System.out.println(e.getMessage());
return false;
}
}
/**
* Excel數(shù)據(jù)讀取成json
*
* @param filepath 文件路徑
* @return json數(shù)據(jù)
*/
public static JSONArray excelToJsonArray(String filepath) throws IOException, InvalidFormatException {
File file = new File(filepath);
String flieName = file.getName();
Workbook book = null;
Sheet sheet = null;
if (flieName.endsWith(XLSX)) {
book = new XSSFWorkbook(file);
sheet = book.getSheetAt(0);
}
if (flieName.endsWith(XLS)) {
POIFSFileSystem poifsFileSystem = new POIFSFileSystem(new FileInputStream(file));
book = new HSSFWorkbook(poifsFileSystem);
sheet = book.getSheetAt(0);
}
if (sheet != null) {
return readSheet(sheet, book);
}
return new JSONArray();
}
/**
* 讀取Excel
*
* @param sheet 工作表
* @param book 工作簿
* @return json數(shù)據(jù)
*/
public static JSONArray readSheet(Sheet sheet, Workbook book) throws IOException {
int rowStart = sheet.getFirstRowNum(); // 首行下標(biāo)
int rowEnd = sheet.getLastRowNum(); // 尾行下標(biāo)
// 如果首行與尾行相同,表明只有一行,直接返回空數(shù)組
if (rowStart == rowEnd) {
book.close();
return new JSONArray();
}
// 獲取第一行JSON對(duì)象鍵
Row firstRow = sheet.getRow(rowStart);
int cellStart = firstRow.getFirstCellNum();
int cellEnd = firstRow.getLastCellNum();
Map<Integer, String> keyMap = new HashMap<Integer, String>();
for (int j = cellStart; j < cellEnd; j++) {
keyMap.put(j, getValue(firstRow.getCell(j), rowStart, j, book, true));
}
// 獲取每行JSON對(duì)象的值
JSONArray array = new JSONArray();
for (int i = rowStart + 1; i <= rowEnd; i++) {
Row eachRow = sheet.getRow(i);
JSONObject obj = new JSONObject();
StringBuffer sb = new StringBuffer();
for (int k = cellStart; k < cellEnd; k++) {
if (eachRow != null) {
String val = getValue(eachRow.getCell(k), i, k, book, false);
sb.append(val); // 所有數(shù)據(jù)添加到里面,用于判斷該行是否為空
obj.put(keyMap.get(k), val);
}
}
if (!sb.toString().isEmpty()) {
array.add(obj);
}
}
book.close();
return array;
}
/**
* 獲取每個(gè)單元格的數(shù)據(jù)
*
* @param cell 單元格對(duì)象
* @param rowNum 第幾行
* @param index 該行第幾個(gè)
* @param book 主要用于關(guān)閉流
* @param isKey 是否為鍵:true-是,false-不是。 如果解析Json鍵,值為空時(shí)報(bào)錯(cuò);如果不是Json鍵,值為空不報(bào)錯(cuò)
*/
public static String getValue(Cell cell, int rowNum, int index, Workbook book, boolean isKey) throws IOException {
// 空白或空
if (cell == null || cell.getCellTypeEnum() == CellType.BLANK) {
if (isKey) {
book.close();
throw new NullPointerException(String.format("the key on row %s index %s is null ", ++rowNum, ++index));
} else {
return "";
}
}
// 0. 數(shù)字 類型
if (cell.getCellTypeEnum() == CellType.NUMERIC) {
if (HSSFDateUtil.isCellDateFormatted(cell)) {
Date date = cell.getDateCellValue();
DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
return df.format(date);
}
String val = cell.getNumericCellValue() + "";
val = val.toUpperCase();
if (val.contains("E")) {
val = val.split("E")[0].replace(".", "");
}
return val;
}
// 1. String類型
if (cell.getCellTypeEnum() == CellType.STRING) {
String val = cell.getStringCellValue();
if (val == null || val.trim().isEmpty()) {
if (book != null) {
book.close();
}
return "";
}
return val.trim();
}
// 2. 公式 CELL_TYPE_FORMULA
if (cell.getCellTypeEnum() == CellType.FORMULA) {
return cell.getStringCellValue();
}
// 4. 布爾值 CELL_TYPE_BOOLEAN
if (cell.getCellTypeEnum() == CellType.BOOLEAN) {
return cell.getBooleanCellValue() + "";
}
// 5. 錯(cuò)誤 CELL_TYPE_ERROR
return "";
}
}
3.使用方式
public static void main(String[] args) throws IOException, InvalidFormatException {
//導(dǎo)出Excel
var json = "[{\"name\":\"張三\",\"age\":\"18\"},{\"name\":\"李四\",\"age\":\"19\"}]";
System.out.println(jsonToExcel(json, "D:\\test.xlsx"));
//讀取Excel
System.out.println(excelToJsonArray("D:\\test.xlsx"));
}到此這篇關(guān)于Java利用Apache POI實(shí)現(xiàn)Excel文件讀寫操作的文章就介紹到這了,更多相關(guān)Java讀寫Excel內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
分布式醫(yī)療掛號(hào)系統(tǒng)Nacos微服務(wù)Feign遠(yuǎn)程調(diào)用數(shù)據(jù)字典
這篇文章主要為大家介紹了分布式醫(yī)療掛號(hào)系統(tǒng)Nacos微服務(wù)Feign遠(yuǎn)程調(diào)用數(shù)據(jù)字典,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪<BR>2022-04-04
詳解SpringBoot實(shí)現(xiàn)fastdfs防盜鏈功能的示例代碼
我們可以通過fastdfs實(shí)現(xiàn)一個(gè)分布式文件系統(tǒng),如果fastdfs部署在外網(wǎng),那么任何一個(gè)人知道了上傳接口,就可以實(shí)現(xiàn)文件的上傳和訪問。那么如何阻止他人訪問我們fastdfs服務(wù)器上的文件呢?此處就需要使用fastdfs的防盜鏈功能,本文就來講講如何實(shí)現(xiàn)這一功能2022-10-10
Java中的HashMap實(shí)現(xiàn)原理深入理解
HashMap是一種非常常見和實(shí)用的數(shù)據(jù)結(jié)構(gòu),它被廣泛應(yīng)用于Java編程中,這篇文章主要介紹了Java中HashMap實(shí)現(xiàn)原理的相關(guān)資料,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下2025-12-12
Java中Set與List的關(guān)系與區(qū)別介紹
這篇文章主要介紹了Java中Set與List的關(guān)系與區(qū)別介紹,本文總結(jié)它們兩個(gè)接口都是繼承自Collection、它們之間的存儲(chǔ)方式不一樣,需要的朋友可以參考下2015-03-03
解析Arthas協(xié)助排查線上skywalking不可用問題
這篇文章主要為大家介紹了解析Arthas協(xié)助排查線上skywalking不可用的問題詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-02-02
通過實(shí)例了解Java 8創(chuàng)建Stream流的5種方法
這篇文章主要介紹了通過實(shí)例了解Java 8創(chuàng)建Stream流的5種方法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-12-12

