Java實(shí)現(xiàn)集合和Excel文件相互轉(zhuǎn)換
一、集合轉(zhuǎn)化為Excel文件
效果如下,是將集合轉(zhuǎn)化為Excel文件,Excel包含合并單元格。

實(shí)體類(lèi):
@Data
public class ClassGrade {
/** 年級(jí) */
private String grade;
/** 班主任 */
private String leader;
/** 學(xué)生列表 */
private List<Student> students;
@Data
public static class Student {
/** 姓名 */
private String name;
/** 年齡 */
private Integer age;
/** 性別 */
private String sex;
/** 成績(jī) */
private Integer gradeResult;
}
}
需求就是將ClassGrade的集合轉(zhuǎn)化為Excel表格對(duì)外輸出。沒(méi)有針對(duì)當(dāng)前類(lèi)去逐個(gè)取值處理,用到了反射來(lái)處理,達(dá)到了簡(jiǎn)化代碼通用的目的。這個(gè)只針對(duì)有一個(gè)合并單元格的情形,如果是合并單元格中包含合并單元格的話(huà),還需要加代碼去處理。
實(shí)現(xiàn)代碼如下:
1.初始化表頭類(lèi),參數(shù)為表頭集合
public static SXSSFWorkbook makeExcelHead(String[] titles) {
SXSSFWorkbook workbook = new SXSSFWorkbook();
CellStyle styleTitle = getTitleStyle(workbook, (short) 16);
SXSSFSheet sheet = workbook.createSheet();
SXSSFRow rowTitle = sheet.createRow(0);
for (int i = 0; i < titles.length; i++) {
sheet.setDefaultColumnWidth(25);
SXSSFCell cellTitle = rowTitle.createCell(i);
// 為標(biāo)題設(shè)置背景顏色
styleTitle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
styleTitle.setFillForegroundColor(HSSFColor.HSSFColorPredefined.GREY_25_PERCENT.getIndex());
cellTitle.setCellValue(titles[i]);
cellTitle.setCellStyle(styleTitle);
}
return workbook;
}
2.反射獲取實(shí)體的值
public static <T> Object getProperty(T t, String propertyName) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException, IndexOutOfBoundsException {
Class<?> aClass = t.getClass();
propertyName = propertyName.substring(0, 1).toUpperCase() + propertyName.substring(1);
Method method = aClass.getMethod("get" + propertyName);
Object invoke = method.invoke(t);
return invoke;
}
2.將集合轉(zhuǎn)化為Excel
@Test
public void exportExcel() throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
//初始化數(shù)據(jù)
List<ClassGrade> fileList = new ArrayList<>();
for (int m = 1; m <= 1; m++) {
fileList.addAll(getGrades());
}
//表頭名稱(chēng)
String[] title = {"班主任", "學(xué)生姓名", "學(xué)生年齡", "學(xué)生性別", "學(xué)生成績(jī)", "班級(jí)"};
SXSSFWorkbook workbook = SXSSFWorkbookUtil.makeExcelHead(title);
//每一列表頭屬性,如果子類(lèi)里面的,則提取子類(lèi)里面對(duì)應(yīng)的屬性名
String[] properties = {"leader", "name", "age", "sex", "gradeResult", "grade"};
//獲取當(dāng)前sheet
SXSSFSheet sheet = workbook.getSheetAt(0);
int initRowNum = 0;
//遍歷數(shù)據(jù),需要根據(jù)業(yè)務(wù)邏輯去處理是否合并單元格
for (int i = 0; i < fileList.size(); i++) {
ClassGrade file = fileList.get(i);
int size = file.getStudents().size();
//創(chuàng)建行,以子類(lèi)的集合數(shù)為準(zhǔn)
int startRowNum = initRowNum + 1;
int lastRowNum = startRowNum + size - 1;
SXSSFRow row = sheet.getRow(startRowNum);
if (row == null) {
row = sheet.createRow(startRowNum);
}
//班主任一列,處理合并單元格
for (int m = 0; m < 1; m++) {
if (lastRowNum - startRowNum > 0) {
sheet.addMergedRegion(new CellRangeAddress(startRowNum, lastRowNum, m, m));
}
createCell(row, m, SXSSFWorkbookUtil.getProperty(file, properties[m]));
}
//處理學(xué)生姓名~學(xué)生成績(jī)四列,非合并單元格信息
int xRowNum = startRowNum;
List<ClassGrade.Student> receiptItems = file.getStudents();
for (ClassGrade.Student student : receiptItems) {
SXSSFRow row1 = sheet.getRow(xRowNum);
if (row1 == null) {
row1 = sheet.createRow(xRowNum);
}
for (int q = 1; q <= 4; q++) {
//利用反射獲取到值,并且設(shè)置到cell里面
createCell(row1, q, SXSSFWorkbookUtil.getProperty(student, properties[q]));
}
xRowNum++;
}
//處理班級(jí)信息合并單元格
for (int n = 5; n <= 5; n++) {
if (lastRowNum - startRowNum >= 1) {
sheet.addMergedRegion(new CellRangeAddress(startRowNum, lastRowNum, n, n));
}
createCell(row, n, SXSSFWorkbookUtil.getProperty(file, properties[n]));
}
initRowNum = lastRowNum;
}
//導(dǎo)出
try (
FileOutputStream excel = new FileOutputStream("excel.xls");
BufferedOutputStream bos = new BufferedOutputStream(excel)) {
workbook.write(bos);
System.out.println("導(dǎo)出完成");
} catch (
IOException e) {
System.out.println("導(dǎo)出失敗:" + e.getMessage());
}
}
private void createCell(SXSSFRow row, int column, Object value) {
SXSSFCell cell = row.createCell(column);
if (value != null) {
cell.setCellValue(String.valueOf(value));
}
}
效果

二、Excel文件轉(zhuǎn)化為集合
如題,將獲取到的excel文件流轉(zhuǎn)化為集合進(jìn)行處理。挺簡(jiǎn)單的。思路就是將一個(gè)文件流轉(zhuǎn)化為一個(gè)備用類(lèi),再將備用類(lèi)轉(zhuǎn)化為想要的集合。
excel:

備用類(lèi)代碼:
@Data
public class ClassGrade2 {
/** 年級(jí) */
private String grade;
/** 班主任 */
private String leader;
/** 姓名 */
private String name;
/** 年齡 */
private Integer age;
/** 性別 */
private String sex;
/** 成績(jī) */
private Integer gradeResult;
}
轉(zhuǎn)化代碼:
@Test
public void test1() {
ExcelReader reader = ExcelUtil.getReader("excelToList.xls");
List<List<Object>> rows = reader.read();
//根據(jù)excel的結(jié)構(gòu),需要準(zhǔn)備一個(gè)備用類(lèi)接收數(shù)據(jù)
List<ClassGrade2> listBaks = new ArrayList<>();
//初始化屬性,屬性是備用類(lèi)的屬性名
String[] properties = {"leader", "name", "age", "sex", "gradeResult", "grade"};
for (int j = 1; j < rows.size(); j++) {
List<Object> cells = rows.get(j);
try {
//反射獲取值,組裝成備用類(lèi)
ClassGrade2 file = new ClassGrade2();
Class<?> clz = file.getClass();
Method[] methods = clz.getDeclaredMethods();
for (int i = 0; i < cells.size(); i++) {
String propertyName = properties[i].substring(0, 1).toUpperCase() + properties[i].substring(1);
Method method = Arrays.stream(methods).filter(m -> Objects.equal(m.getName(), "set" + propertyName)).findFirst().orElse(null);
Object cell = cells.get(i);
if (cell == null) {
continue;
}
Field field = clz.getDeclaredField(properties[i]);
String fieldType = field.getType().getName();
if (fieldType.equals("java.lang.String")) {
method.invoke(file, String.valueOf(cell));
} else if (fieldType.equals("java.math.BigDecimal")) {
method.invoke(file, new BigDecimal(String.valueOf(cell)));
}
}
listBaks.add(file);
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (NoSuchFieldException e) {
e.printStackTrace();
} finally {
}
}
//備用類(lèi)轉(zhuǎn)化為想要的集合類(lèi)
int i = 0;
List<ClassGrade> files = new ArrayList<>();
for (int m = 0; m < listBaks.size(); m++) {
ClassGrade2 fileBak = listBaks.get(m);
if (Strings.isNotEmpty(fileBak.getGrade())) {
ClassGrade file = BeanUtil.copyProperties(fileBak, ClassGrade.class);
files.add(file);
ClassGrade.Student item = BeanUtil.copyProperties(fileBak, ClassGrade.Student.class);
List<ClassGrade.Student> items = new ArrayList<>();
items.add(item);
file.setStudents(items);
i++;
} else {
ClassGrade.Student item = BeanUtil.copyProperties(fileBak, ClassGrade.Student.class);
ClassGrade file = files.get(i - 1);
List<ClassGrade.Student> items = CollectionUtils.isEmpty(file.getStudents()) ? new ArrayList<>() : file.getStudents();
items.add(item);
file.setStudents(items);
}
}
log.info("{}", JSONArray.toJSONString(listBaks));
log.info("{}", JSONArray.toJSONString(files));
}
實(shí)現(xiàn)效果:
11:47:03.635 [main] INFO Excel3Test - [{"grade":"八年級(jí)1班","leader":"趙老師","name":"張三","sex":"女"},{"grade":"八年級(jí)1班","leader":"趙老師","name":"李四","sex":"女"},{"grade":"八年級(jí)1班","leader":"趙老師","name":"王五","sex":"女"}]
11:47:03.647 [main] INFO Excel3Test - [{"grade":"八年級(jí)1班","leader":"趙老師","students":[{"name":"張三","sex":"女"}]},{"grade":"八年級(jí)1班","leader":"趙老師","students":[{"name":"李四","sex":"女"}]},{"grade":"八年級(jí)1班","leader":"趙老師","students":[{"name":"王五","sex":"女"}]}]
到此這篇關(guān)于Java實(shí)現(xiàn)集合和Excel文件相互轉(zhuǎn)換的文章就介紹到這了,更多相關(guān)Java集合和Excel文件相互轉(zhuǎn)換內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Springboot實(shí)現(xiàn)定時(shí)任務(wù)的4種方式舉例詳解
在我們開(kāi)發(fā)項(xiàng)目過(guò)程中經(jīng)常需要定時(shí)任務(wù)來(lái)幫助我們來(lái)做一些內(nèi)容,下面這篇文章主要給大家介紹了關(guān)于Springboot實(shí)現(xiàn)定時(shí)任務(wù)的4種方式,文中通過(guò)代碼介紹的非常詳細(xì),需要的朋友可以參考下2024-01-01
Springboot @WebFilter無(wú)法注入其他Bean的示例問(wèn)題
這篇文章主要介紹了Springboot @WebFilter無(wú)法注入其他Bean的示例問(wèn)題,本文通過(guò)示例代碼給大家分享解決方法,需要的朋友可以參考下2021-09-09
解決spring 處理request.getInputStream()輸入流只能讀取一次問(wèn)題
這篇文章主要介紹了解決spring 處理request.getInputStream()輸入流只能讀取一次問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-09-09
Spring MVC 自定義數(shù)據(jù)轉(zhuǎn)換器的思路案例詳解
本文通過(guò)兩個(gè)案例來(lái)介紹下Spring MVC 自定義數(shù)據(jù)轉(zhuǎn)換器的相關(guān)知識(shí),每種方法通過(guò)實(shí)例圖文相結(jié)合給大家介紹的非常詳細(xì),需要的朋友可以參考下2021-09-09
Java高性能本地緩存框架Caffeine的實(shí)現(xiàn)
本文主要介紹了Java高性能本地緩存框架Caffeine的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-02-02
java中獲取當(dāng)前服務(wù)器的Ip地址的方法
本篇文章主要介紹了java中獲取當(dāng)前服務(wù)器的Ip地址的方法,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-02-02
org.springframework.web.client.ResourceAccessException資源訪(fǎng)問(wèn)錯(cuò)誤
本文主要介紹了org.springframework.web.client.ResourceAccessException資源訪(fǎng)問(wèn)錯(cuò)誤的解決方法,首先需要分析異常的詳細(xì)信息,以確定具體的錯(cuò)誤原因,感興趣的可以了解一下2024-05-05
SkyWalking?自定義插件(Spring?RabbitMQ)具體分析過(guò)程
這篇文章主要介紹了SkyWalking?自定義插件(Spring?RabbitMQ)具體分析過(guò)程,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-02-02
Java數(shù)據(jù)結(jié)構(gòu)之常見(jiàn)排序算法(上)
這篇文章主要介紹了Java數(shù)據(jù)結(jié)構(gòu)之常見(jiàn)排序算法,本文章是匯總篇,且對(duì)每個(gè)排序都進(jìn)行了說(shuō)明,可以很好的理清思路,對(duì)排序算法有個(gè)總體的框架,需要的朋友可以參考下2023-01-01

