Java實現(xiàn)對象列表導出為excel表格的實用工具類
傳入一個任意實體集合(List),通過反射獲取實體類的屬性名和屬性值。在寫入文件時,第一行為屬性名,從第二行開始為屬性值。
1.POI工具介紹
Excel的文件的組織形式,一個Excel文件對應于一個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");
// 設置公司信息
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");
// 設置公司信息
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;
//響應到客戶端
try {
//表格文件名稱
String codedFileName = java.net.URLEncoder.encode(sheetName, "UTF-8");
//設置響應頭
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 {
//關閉輸出流
if (outputStream != null) {
try {
outputStream.close();
workbook.dispose();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
參考文章:java使用POI實現(xiàn)excel文件的導入和導出(通用方法)
到此這篇關于Java實現(xiàn)對象列表導出為excel表格的實用工具類的文章就介紹到這了,更多相關Java列表導出為excel內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
java8中NIO緩沖區(qū)(Buffer)的數(shù)據(jù)存儲詳解
在本篇文章中小編給大家分享了關于java8中NIO緩沖區(qū)(Buffer)的數(shù)據(jù)存儲的相關知識點,需要的朋友們參考下。2019-04-04
logback高效狀態(tài)管理器StatusManager源碼解析
這篇文章主要為大家介紹了logback高效狀態(tài)管理器StatusManager源碼解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-11-11
java調(diào)用chatgpt接口來實現(xiàn)專屬于自己的人工智能助手
這篇文章主要介紹了用java來調(diào)用chatget的接口,實現(xiàn)自己的聊天機器人,對人工智能感興趣的小伙伴可以參考閱讀2023-03-03
淺析Java8新特性Lambda表達式和函數(shù)式接口
Lambda表達式理解為是 一段可以傳遞的代碼。最直觀的是使用Lambda表達式之后不用再寫大量的匿名內(nèi)部類,簡化代碼,提高了代碼的可讀性2017-08-08
SpringBoot采用Dynamic-Datasource方式實現(xiàn)多JDBC數(shù)據(jù)源
在某些情況下,如果我們需要配置多個數(shù)據(jù)源,本文主要介紹了SpringBoot采用Dynamic-Datasource方式實現(xiàn)多JDBC數(shù)據(jù)源,具有一定的參考價值,感興趣的可以了解一下2023-10-10
java的Object里wait()實現(xiàn)原理講解
這篇文章主要介紹了java的Object里wait()實現(xiàn)原理,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-09-09
SpringMVC中Json數(shù)據(jù)格式轉(zhuǎn)換
本文主要介紹了SpringMVC中Json數(shù)據(jù)格式轉(zhuǎn)換的相關知識。具有很好的參考價值。下面跟著小編一起來看下吧2017-03-03
一文搞懂Spring中@Autowired和@Resource的區(qū)別
@Autowired?和?@Resource?都是?Spring/Spring?Boot?項目中,用來進行依賴注入的注解。它們都提供了將依賴對象注入到當前對象的功能,但二者卻有眾多不同,并且這也是常見的面試題之一,所以我們今天就來盤它2022-08-08

