Java實現(xiàn)對象列表導出為excel表格的實用工具類
傳入一個任意實體集合(List),通過反射獲取實體類的屬性名和屬性值。在寫入文件時,第一行為屬性名,從第二行開始為屬性值。
1.POI工具介紹
Excel的文件的組織形式,一個Excel文件對應(yīng)于一個workbook(HSSFWorkbook),一個workbook可以有多個sheet(HSSFSheet)組成,一個sheet是由多個row(HSSFRow)組成,一個row是由多個cell(HSSFCell)組成。
基本操作步驟:
1、用HSSFWorkbook打開或者創(chuàng)建“Excel文件對象”
2、用HSSFWorkbook對象返回或者創(chuàng)建Sheet對象
3、用Sheet對象返回行對象,用行對象得到Cell對象
4、對Cell對象讀寫。
以上只能導入xls的文件不能導入xlsx的。導入xlsx需要用XSSFWorkFont,基本上都一樣。
2.添加maven依賴
<!--Apache POI提供API給Java程式對Microsoft Office(Excel、WORD、PowerPoint、Visio等)格式檔案讀和寫的功能-->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>3.17</version>
</dependency>
<!--導出excel文件-->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>3.17</version>
</dependency>
3.Excel操作工具類
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.hpsf.DocumentSummaryInformation;
import org.apache.poi.hpsf.SummaryInformation;
import org.apache.poi.hssf.usermodel.*;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.nio.charset.StandardCharsets;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
/**
* @Author: funfan0517
* @CreateTime: 2022-11-07 14:36
* @Description: Excel操作工具類
*/
@Slf4j
public class PoiUtils {
/**
* 將對象集合導出到excel
* @param list
* @param <T>
* @return
*/
public static <T> ResponseEntity<byte[]> exportToExcel(List<T> list,String excelName) {
if(list.isEmpty()) return null;//列表為空直接返回null
// 1、創(chuàng)建一個excel文檔
HSSFWorkbook workbook = new HSSFWorkbook();
// 2、創(chuàng)建文檔摘要
workbook.createInformationProperties();
// 3、獲取并配置文檔摘要信息
DocumentSummaryInformation docInfo = workbook.getDocumentSummaryInformation();
// 文檔類別
docInfo.setCategory("導出文檔");
// 文檔管理員
docInfo.setManager("UT");
// 設(shè)置公司信息
docInfo.setCompany("www.ut.com.cn");
// 4、獲取文檔摘要信息
SummaryInformation summaryInformation = workbook.getSummaryInformation();
// 文檔標題
summaryInformation.setTitle("導出文檔");
// 文檔作者
summaryInformation.setAuthor("UT");
// 備注信息
summaryInformation.setComments("本文檔由 優(yōu)特科技 提供");
// 5、創(chuàng)建樣式
// 創(chuàng)建標題行的樣式
HSSFCellStyle headerStyle = workbook.createCellStyle();
headerStyle.setFillForegroundColor(IndexedColors.GREEN.getIndex()); // 背景顏色
headerStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND); // 填充模式
HSSFSheet sheet = workbook.createSheet();// 不傳name 默認為sheet1
// 6、創(chuàng)建標題行 第一行數(shù)據(jù)
// 只循環(huán)一次目的是將對象名寫入到excel標題上
for (T t : list) {
HSSFRow row = sheet.createRow(0);
String[] fieldNames = getFiledNames(t);
for (int i = 0; i < fieldNames.length; i++) {
HSSFCell cell = row.createCell(i);
cell.setCellValue(fieldNames[i]);
cell.setCellStyle(headerStyle);
}
break;
}
// 7、創(chuàng)建后面行
for (int j = 0; j < list.size(); j++) {
T t = list.get(j);
String[] fieldValues = getFieldValues(t);
// 由于第一行已經(jīng)寫入了標題,所以這里從第二行開始寫
HSSFRow rows = sheet.createRow(j + 1);
for (int i = 0; i < fieldValues.length; i++) {
rows.createCell(i).setCellValue(fieldValues[i]);
}
}
HttpHeaders headers = new HttpHeaders();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
// FileOutputStream baos = null;
try {
// baos = new FileOutputStream("D:\\data\\test.xls");
// 防止亂碼
headers.setContentDispositionFormData("attachment", new String(excelName.getBytes(StandardCharsets.UTF_8), "ISO-8859-1"));//ISO-8859-1
headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
workbook.write(baos);
} catch (IOException e) {
e.printStackTrace();
}
return new ResponseEntity<>(baos.toByteArray(), headers, HttpStatus.CREATED);//null;//
}
/**
* 獲取所有對象屬性名稱
* @param o
* @return
*/
public static String[] getFiledNames(Object o) {
Field[] fields=o.getClass().getDeclaredFields();
String[] fieldNames=new String[fields.length];
for(int i=0;i<fields.length;i++){
fieldNames[i]=fields[i].getName();
}
return fieldNames;
}
/**
* 獲取對象屬性值
* @param o
* @return
* @throws NoSuchMethodException
* @throws InvocationTargetException
* @throws IllegalAccessException
*/
private static String[] getFieldValues(Object o) {
Field[] fields=o.getClass().getDeclaredFields();
String[] fieldNames=new String[fields.length];
String[] fieldValues = new String[fieldNames.length];
for(int i=0;i<fields.length;i++){
fieldNames[i]=fields[i].getName();
}
try {
for (int i=0; i<fieldNames.length; i++) {
String fieldName = fieldNames[i];
Object invoke = o.getClass().getMethod("get" + returnFirstCapital(fieldName)).invoke(o);
String field = invoke == null? null:invoke.toString();//數(shù)據(jù)為null時做特殊處理
if(invoke instanceof Date) {
field = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(invoke);
}
fieldValues[i] = field;
}
} catch(Exception e) {
log.error("獲取實體類對象屬性異常:", e);
}
return fieldValues;
}
/**
* 判斷字符串首字母是否為大寫,如果不是轉(zhuǎn)化為大寫
* @param str
* @return
*/
public static String returnFirstCapital(String str) {
if (str.charAt(0) >= 'A' && str.charAt(0) <= 'Z') {
return str;
}
char[] ch = str.toCharArray();
ch[0] -= 32;
return String.valueOf(ch);
}
/**
* 將對象集合導出到excel
*/
public static <T> String exportToExcelFile(List<T> list, String excelName) {
if(list.isEmpty()) return null;//列表為空直接返回null
// 1、創(chuàng)建一個excel文檔
HSSFWorkbook workbook = new HSSFWorkbook();
// 2、創(chuàng)建文檔摘要
workbook.createInformationProperties();
// 3、獲取并配置文檔摘要信息
DocumentSummaryInformation docInfo = workbook.getDocumentSummaryInformation();
// 文檔類別
docInfo.setCategory("導出文檔");
// 文檔管理員
docInfo.setManager("UT");
// 設(shè)置公司信息
docInfo.setCompany("www.ut.com.cn");
// 4、獲取文檔摘要信息
SummaryInformation summaryInformation = workbook.getSummaryInformation();
// 文檔標題
summaryInformation.setTitle("導出文檔");
// 文檔作者
summaryInformation.setAuthor("UT");
// 備注信息
summaryInformation.setComments("本文檔由 優(yōu)特科技 提供");
// 5、創(chuàng)建樣式
// 創(chuàng)建標題行的樣式
HSSFCellStyle headerStyle = workbook.createCellStyle();
headerStyle.setFillForegroundColor(IndexedColors.GREEN.getIndex()); // 背景顏色
headerStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND); // 填充模式
HSSFSheet sheet = workbook.createSheet();// 不傳name 默認為sheet1
// 6、創(chuàng)建標題行 第一行數(shù)據(jù)
// 只循環(huán)一次目的是將對象名寫入到excel標題上
for (T t : list) {
HSSFRow row = sheet.createRow(0);
String[] fieldNames = getFiledNames(t);
for (int i = 0; i < fieldNames.length; i++) {
HSSFCell cell = row.createCell(i);
cell.setCellValue(fieldNames[i]);
cell.setCellStyle(headerStyle);
}
break;
}
// 7、創(chuàng)建后面行
for (int j = 0; j < list.size(); j++) {
T t = list.get(j);
String[] fieldValues = getFieldValues(t);
// 由于第一行已經(jīng)寫入了標題,所以這里從第二行開始寫
HSSFRow rows = sheet.createRow(j + 1);
for (int i = 0; i < fieldValues.length; i++) {
rows.createCell(i).setCellValue(fieldValues[i]);
}
}
File file=new File("D:\\"+excelName+".xls");
FileOutputStream baos = null;
try {
baos = new FileOutputStream(file);
workbook.write(baos);
} catch (IOException e) {
e.printStackTrace();
}
String absolutePath = file.getAbsolutePath();
return "導出文件存放路徑為:"+absolutePath;
}
/**
* 將對象集合導出到excel
* SXSSFWorkbook對于大型excel的創(chuàng)建且不會內(nèi)存溢出的,就只有SXSSFWorkbook了。它的原理很簡單,用硬盤空間換內(nèi)存(就像hash map用空間換時間一樣)
* @param list
* @param <T>
* @reurn
*/
public static <T> void exportExcel(HttpServletRequest request, HttpServletResponse response, List<T> list, String sheetName) {
// 1、創(chuàng)建一個excel文檔
SXSSFWorkbook workbook = new SXSSFWorkbook();
// 5、創(chuàng)建樣式
// 創(chuàng)建標題行的樣式
CellStyle headerStyle = workbook.createCellStyle();
headerStyle.setFillForegroundColor(IndexedColors.GREEN.getIndex()); // 背景顏色
headerStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND); // 填充模式
Sheet sheet = workbook.createSheet();// 不傳name 默認為sheet1
// 6、創(chuàng)建標題行 第一行數(shù)據(jù)
// 只循環(huán)一次目的是將對象名寫入到excel標題上
for (T t : list) {
Row row = sheet.createRow(0);
String[] fieldNames = getFiledNames(t);
for (int i = 0; i < fieldNames.length; i++) {
Cell cell = row.createCell(i);
cell.setCellValue(fieldNames[i]);
cell.setCellStyle(headerStyle);
}
break;
}
// 7、創(chuàng)建后面行
for (int j = 0; j < list.size(); j++) {
T t = list.get(j);
String[] fieldValues = getFieldValues(t);
// 由于第一行已經(jīng)寫入了標題,所以這里從第二行開始寫
Row rows = sheet.createRow(j + 1);
for (int i = 0; i < fieldValues.length; i++) {
rows.createCell(i).setCellValue(fieldValues[i]);
}
}
//聲明輸出流
OutputStream outputStream = null;
//響應(yīng)到客戶端
try {
//表格文件名稱
String codedFileName = java.net.URLEncoder.encode(sheetName, "UTF-8");
//設(shè)置響應(yīng)頭
response.setContentType("application/vnd.ms-excel");
String agent = request.getHeader("USER-AGENT").toLowerCase();
if (agent.contains("firefox")) {
response.setCharacterEncoding("utf-8");
response.setHeader("content-disposition", "attachment;filename=" + new String(sheetName.getBytes(), "ISO8859-1") + ".xlsx");
} else {
response.setHeader("content-disposition", "attachment;filename=" + codedFileName + ".xlsx");
}
//獲取輸出流
outputStream = response.getOutputStream();
//用文檔寫輸出流
workbook.write(outputStream);
//刷新輸出流
outputStream.flush();
} catch (Exception e) {
e.printStackTrace();
} finally {
//關(guān)閉輸出流
if (outputStream != null) {
try {
outputStream.close();
workbook.dispose();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
參考文章:java使用POI實現(xiàn)excel文件的導入和導出(通用方法)
到此這篇關(guān)于Java實現(xiàn)對象列表導出為excel表格的實用工具類的文章就介紹到這了,更多相關(guān)Java列表導出為excel內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
解析SpringBoot?搭建基于?MinIO?的高性能存儲服務(wù)的問題
Minio是Apache?License?v2.0下發(fā)布的對象存儲服務(wù)器,使用MinIO構(gòu)建用于機器學習,分析和應(yīng)用程序數(shù)據(jù)工作負載的高性能基礎(chǔ)架構(gòu)。這篇文章主要介紹了SpringBoot?搭建基于?MinIO?的高性能存儲服務(wù),需要的朋友可以參考下2022-03-03
解決Nacos成功啟動但是無法訪問 (Connection refused)
這篇文章主要介紹了解決Nacos成功啟動但是無法訪問 (Connection refused)問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-06-06
SpringBoot實現(xiàn)應(yīng)用開機自啟動與進程守護配置方案
機房意外斷電,恢復(fù)供電后所有服務(wù)器重啟,但SpringBoot應(yīng)用沒有自動啟動,事后排查發(fā)現(xiàn),沒有留下開機自啟動配置文檔,所以本文整理了兩套SpringBoot應(yīng)用開機自啟動與進程守護方案,需要的朋友可以參考下2025-07-07
Java中使用StackWalker和Stream API進行堆棧遍歷
StackWalking API是添加到Java中最酷的(并且對大多數(shù)開發(fā)人員來說完全不切實際,一般不會用,除非深層跟蹤調(diào)優(yōu))的功能之一。在這篇簡短的文章中,我們將看到它是什么以及使用它有多么容易,很快的認識它2018-09-09
基于springBoot配置文件properties和yml中數(shù)組的寫法
這篇文章主要介紹了springBoot配置文件properties和yml中數(shù)組的寫法,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-11-11
java發(fā)郵件錯誤javax.net.ssl.SSLHandshakeException:No appropr
這篇文章主要介紹了java發(fā)郵件錯誤javax.net.ssl.SSLHandshakeException:No appropriate protocol問題及解決,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2026-05-05

