Java實(shí)現(xiàn)對(duì)象列表導(dǎo)出為excel表格的實(shí)用工具類
傳入一個(gè)任意實(shí)體集合(List),通過反射獲取實(shí)體類的屬性名和屬性值。在寫入文件時(shí),第一行為屬性名,從第二行開始為屬性值。
1.POI工具介紹
Excel的文件的組織形式,一個(gè)Excel文件對(duì)應(yīng)于一個(gè)workbook(HSSFWorkbook),一個(gè)workbook可以有多個(gè)sheet(HSSFSheet)組成,一個(gè)sheet是由多個(gè)row(HSSFRow)組成,一個(gè)row是由多個(gè)cell(HSSFCell)組成。
基本操作步驟:
1、用HSSFWorkbook打開或者創(chuàng)建“Excel文件對(duì)象”
2、用HSSFWorkbook對(duì)象返回或者創(chuàng)建Sheet對(duì)象
3、用Sheet對(duì)象返回行對(duì)象,用行對(duì)象得到Cell對(duì)象
4、對(duì)Cell對(duì)象讀寫。
以上只能導(dǎo)入xls的文件不能導(dǎo)入xlsx的。導(dǎo)入xlsx需要用XSSFWorkFont,基本上都一樣。
2.添加maven依賴
<!--Apache POI提供API給Java程式對(duì)Microsoft Office(Excel、WORD、PowerPoint、Visio等)格式檔案讀和寫的功能--> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi</artifactId> <version>3.17</version> </dependency> <!--導(dǎo)出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 { /** * 將對(duì)象集合導(dǎo)出到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)建一個(gè)excel文檔 HSSFWorkbook workbook = new HSSFWorkbook(); // 2、創(chuàng)建文檔摘要 workbook.createInformationProperties(); // 3、獲取并配置文檔摘要信息 DocumentSummaryInformation docInfo = workbook.getDocumentSummaryInformation(); // 文檔類別 docInfo.setCategory("導(dǎo)出文檔"); // 文檔管理員 docInfo.setManager("UT"); // 設(shè)置公司信息 docInfo.setCompany("www.ut.com.cn"); // 4、獲取文檔摘要信息 SummaryInformation summaryInformation = workbook.getSummaryInformation(); // 文檔標(biāo)題 summaryInformation.setTitle("導(dǎo)出文檔"); // 文檔作者 summaryInformation.setAuthor("UT"); // 備注信息 summaryInformation.setComments("本文檔由 優(yōu)特科技 提供"); // 5、創(chuàng)建樣式 // 創(chuàng)建標(biāo)題行的樣式 HSSFCellStyle headerStyle = workbook.createCellStyle(); headerStyle.setFillForegroundColor(IndexedColors.GREEN.getIndex()); // 背景顏色 headerStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND); // 填充模式 HSSFSheet sheet = workbook.createSheet();// 不傳name 默認(rèn)為sheet1 // 6、創(chuàng)建標(biāo)題行 第一行數(shù)據(jù) // 只循環(huán)一次目的是將對(duì)象名寫入到excel標(biāo)題上 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)寫入了標(biāo)題,所以這里從第二行開始寫 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;// } /** * 獲取所有對(duì)象屬性名稱 * @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; } /** * 獲取對(duì)象屬性值 * @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時(shí)做特殊處理 if(invoke instanceof Date) { field = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(invoke); } fieldValues[i] = field; } } catch(Exception e) { log.error("獲取實(shí)體類對(duì)象屬性異常:", 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); } /** * 將對(duì)象集合導(dǎo)出到excel */ public static <T> String exportToExcelFile(List<T> list, String excelName) { if(list.isEmpty()) return null;//列表為空直接返回null // 1、創(chuàng)建一個(gè)excel文檔 HSSFWorkbook workbook = new HSSFWorkbook(); // 2、創(chuàng)建文檔摘要 workbook.createInformationProperties(); // 3、獲取并配置文檔摘要信息 DocumentSummaryInformation docInfo = workbook.getDocumentSummaryInformation(); // 文檔類別 docInfo.setCategory("導(dǎo)出文檔"); // 文檔管理員 docInfo.setManager("UT"); // 設(shè)置公司信息 docInfo.setCompany("www.ut.com.cn"); // 4、獲取文檔摘要信息 SummaryInformation summaryInformation = workbook.getSummaryInformation(); // 文檔標(biāo)題 summaryInformation.setTitle("導(dǎo)出文檔"); // 文檔作者 summaryInformation.setAuthor("UT"); // 備注信息 summaryInformation.setComments("本文檔由 優(yōu)特科技 提供"); // 5、創(chuàng)建樣式 // 創(chuàng)建標(biāo)題行的樣式 HSSFCellStyle headerStyle = workbook.createCellStyle(); headerStyle.setFillForegroundColor(IndexedColors.GREEN.getIndex()); // 背景顏色 headerStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND); // 填充模式 HSSFSheet sheet = workbook.createSheet();// 不傳name 默認(rèn)為sheet1 // 6、創(chuàng)建標(biāo)題行 第一行數(shù)據(jù) // 只循環(huán)一次目的是將對(duì)象名寫入到excel標(biāo)題上 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)寫入了標(biāo)題,所以這里從第二行開始寫 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 "導(dǎo)出文件存放路徑為:"+absolutePath; } /** * 將對(duì)象集合導(dǎo)出到excel * SXSSFWorkbook對(duì)于大型excel的創(chuàng)建且不會(huì)內(nèi)存溢出的,就只有SXSSFWorkbook了。它的原理很簡(jiǎn)單,用硬盤空間換內(nèi)存(就像hash map用空間換時(shí)間一樣) * @param list * @param <T> * @reurn */ public static <T> void exportExcel(HttpServletRequest request, HttpServletResponse response, List<T> list, String sheetName) { // 1、創(chuàng)建一個(gè)excel文檔 SXSSFWorkbook workbook = new SXSSFWorkbook(); // 5、創(chuàng)建樣式 // 創(chuàng)建標(biāo)題行的樣式 CellStyle headerStyle = workbook.createCellStyle(); headerStyle.setFillForegroundColor(IndexedColors.GREEN.getIndex()); // 背景顏色 headerStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND); // 填充模式 Sheet sheet = workbook.createSheet();// 不傳name 默認(rèn)為sheet1 // 6、創(chuàng)建標(biāo)題行 第一行數(shù)據(jù) // 只循環(huán)一次目的是將對(duì)象名寫入到excel標(biāo)題上 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)寫入了標(biāo)題,所以這里從第二行開始寫 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實(shí)現(xiàn)excel文件的導(dǎo)入和導(dǎo)出(通用方法)
到此這篇關(guān)于Java實(shí)現(xiàn)對(duì)象列表導(dǎo)出為excel表格的實(shí)用工具類的文章就介紹到這了,更多相關(guān)Java列表導(dǎo)出為excel內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
java8中NIO緩沖區(qū)(Buffer)的數(shù)據(jù)存儲(chǔ)詳解
在本篇文章中小編給大家分享了關(guān)于java8中NIO緩沖區(qū)(Buffer)的數(shù)據(jù)存儲(chǔ)的相關(guān)知識(shí)點(diǎn),需要的朋友們參考下。2019-04-04logback高效狀態(tài)管理器StatusManager源碼解析
這篇文章主要為大家介紹了logback高效狀態(tài)管理器StatusManager源碼解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-11-11java調(diào)用chatgpt接口來(lái)實(shí)現(xiàn)專屬于自己的人工智能助手
這篇文章主要介紹了用java來(lái)調(diào)用chatget的接口,實(shí)現(xiàn)自己的聊天機(jī)器人,對(duì)人工智能感興趣的小伙伴可以參考閱讀2023-03-03淺析Java8新特性Lambda表達(dá)式和函數(shù)式接口
Lambda表達(dá)式理解為是 一段可以傳遞的代碼。最直觀的是使用Lambda表達(dá)式之后不用再寫大量的匿名內(nèi)部類,簡(jiǎn)化代碼,提高了代碼的可讀性2017-08-08Java原生方法實(shí)現(xiàn) AES 算法示例
這篇文章主要介紹了Java原生方法實(shí)現(xiàn) AES 算法,結(jié)合實(shí)例形式分析了Java實(shí)現(xiàn)AES加密算法的相關(guān)操作技巧,需要的朋友可以參考下2019-03-03SpringBoot采用Dynamic-Datasource方式實(shí)現(xiàn)多JDBC數(shù)據(jù)源
在某些情況下,如果我們需要配置多個(gè)數(shù)據(jù)源,本文主要介紹了SpringBoot采用Dynamic-Datasource方式實(shí)現(xiàn)多JDBC數(shù)據(jù)源,具有一定的參考價(jià)值,感興趣的可以了解一下2023-10-10java的Object里wait()實(shí)現(xiàn)原理講解
這篇文章主要介紹了java的Object里wait()實(shí)現(xiàn)原理,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-09-09SpringMVC中Json數(shù)據(jù)格式轉(zhuǎn)換
本文主要介紹了SpringMVC中Json數(shù)據(jù)格式轉(zhuǎn)換的相關(guān)知識(shí)。具有很好的參考價(jià)值。下面跟著小編一起來(lái)看下吧2017-03-03一文搞懂Spring中@Autowired和@Resource的區(qū)別
@Autowired?和?@Resource?都是?Spring/Spring?Boot?項(xiàng)目中,用來(lái)進(jìn)行依賴注入的注解。它們都提供了將依賴對(duì)象注入到當(dāng)前對(duì)象的功能,但二者卻有眾多不同,并且這也是常見的面試題之一,所以我們今天就來(lái)盤它2022-08-08