JAVA 使用 POI實現資料匯出到Excel
前言:
人生中第一次釋出部落格,怎麼說還是有點緊張的。希望各位看官多多支援~~~!
引入:
就在上個禮拜,專案中有一個需求就是把一些資料匯出到Excel中,並且要求Excel要按照規定的內容和排版顯示匯出來的資料。
當時看到這個需求內心還是有點小壓力的,畢竟剛剛做後臺沒多久(ps:我在外包公司,有什麼就寫什麼。哈哈【Fuck!】)
當然有壓力還是沒壓力,該寫還是要寫的,我就開始上網查了一些關於 JAVA匯出資料到Excel的一些相關文章 ,被一些只展示部分程式碼的那些自認為大佬的那些朋友們坑的不輕,展示的都是很簡單的東西而且大家都會的,原始碼有的還有花錢才能下載!面對這些我決定自己研究研究,如果搞出來的話就免費釋出出來,給大家提供方便或者解決一些大家出現的問題。
還好,我搞出來了。
說了一堆廢話,諷刺一下那些大佬們。鼓勵一下遇到問題沒有找到合適答案的朋友們,多去研究咱們一樣可以解決問題。
進入主題:
我使用的是JAVA POI實現的匯出Excel。
當然一看名字就知道是一個庫或者是一個框架,那當然少不了jar包啦!
第一步:這邊因為需求是要用SpringBoot寫,所以我使用了POM檔案匯入依賴,【如下圖】
<dependency> <groupId>org.apache.poi</groupId> <artifactId>poi</artifactId><version>3.15</version> </dependency> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-ooxml-schemas</artifactId> <version>3.15</version> </dependency> <dependency> <groupId>org.apache.poi</groupId><artifactId>poi-ooxml</artifactId> <version>3.15</version> </dependency>
第二步:匯入了依賴之後,切記不要著急,等待右下角提示匯入依賴選擇後才是真正的匯入了POI的依賴!【如下圖】
選擇Import Changes 或者 Enable Auto-Import都可以,左邊是每次修改依賴都需要手動去匯入,右邊是每次修改依賴之後自動匯入,選擇任意一個都可以!
第三步:擴充套件一下知識點
這裡說一個小小的擴充套件:
POI 提供了對2003版本的Excel的支援 ---- HSSFWorkbook
POI 提供了對2007版本以及更高版本的支援 ---- XSSFWorkbook
這個不用犯愁很好記: 2003版本的就記住一個H,2007以及更高版本的就記住一個X!
第四步: 進入重頭戲
1、我們要拿到對應版本的物件,因為現在都是高本的的Excel,所以我使用了上面提到的 XSSFWorkbook
XSSFWorkbook wb = new XSSFWorkbook();
2、拿到了wb之後,我們就可以對Excel進行排版佈局了,是不是有點小激動
3、新增一個頁
Sheet sheet = wb.createSheet("0");
這一步我們實現的就是Excel開啟之後左下角的那個Sheet,也就是當前頁!
4、開始設定Excel的排版樣式【ps:具體樣式根據專案需求來定,這裡我舉一個很大眾化的佈局】
相信大多數的需求應該都和這個差不多吧,開始啦。
【1】 拿到設定Excel表格樣式的物件 CellStyle
然後需要把我們最開始獲取的那個wb傳進來,就可以對單元格進行排版了。
這裡我提供一些最常用的樣式:
(單元格樣式) 為什麼只有後兩條有註釋呢,那是因為我相信聰明伶俐的你們都看得懂。。哈哈哈 border很明顯邊框嘛
CellStyle cellStyle = wb.createCellStyle(); cellStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND); cellStyle.setBorderTop(BorderStyle.THIN); cellStyle.setBorderBottom(BorderStyle.THIN); cellStyle.setBorderLeft(BorderStyle.THIN); cellStyle.setBorderRight(BorderStyle.THIN); cellStyle.setTopBorderColor(HSSFColor.BLACK.index); cellStyle.setBottomBorderColor(HSSFColor.BLACK.index); cellStyle.setLeftBorderColor(HSSFColor.BLACK.index); cellStyle.setRightBorderColor(HSSFColor.BLACK.index); cellStyle.setAlignment(HSSFCellStyle.ALIGN_CENTER); // 水平居中 cellStyle.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER); // 上下居中
(標題樣式)
XSSFFont titleFont = wb.createFont(); titleFont.setFontHeight(24); titleFont.setBold(true); CellStyle titleCellStyle = setCellStyle(wb); titleCellStyle.setFont(titleFont);
這裡可以看到,在第四行我又建立了一個 CellStyle 那是因為標題需要加粗顯示並且字型變大如果使用同一套樣式,那麼我相信,老闆會對你產生懷疑
(具體的標題實現 如下圖)
/** * 主 標題 在這裡插入主標題 */ Row titleRow; Cell titleCell; sheet.addMergedRegion(new CellRangeAddress((short)0, (short)2, (short)0, (short)8)); for (int i = 0; i <= 2; i++) { titleRow = sheet.createRow(i); for (int j = 0; j < 9; j++) { titleCell = titleRow.createCell(j); titleCell.setCellType(CellType.STRING); titleCell.setCellStyle(titleCellStyle); titleCell.setCellValue("這裡是大標題"); } }
外面的那兩個標題分別是建立一行和列
第三行,就是合併單元格的操作,這裡要記住Excel下標也是從0開始!
注意看圖中的CellType.STRING這個很重要,如果你不寫你會發現你的樣式根本不會生效!
【有一個小擴充套件來了】
因為Excel的每一個單元格是Cell型別,如同我們JAVA中的變數,如果你非要把 double 放入到 int 裡面會出現什麼情況?那麼Excel也不例外,所以我們統一轉換成String!
然後使用迴圈去建立對應的單元格,並且要記得把你寫好的樣式加到每一個單元格里面。
(資料展示)
標題都會寫了,那展示資料還有什麼難的?
/** * 列 資料 在這裡插入資料 */ Row rowCheck; Cell cellCheck; for (int i = 3; i < 2000; i++) { rowCheck = sheet.createRow((i + 1)); for (int j = 0; j < 9; j++) { cellCheck = rowCheck.createCell(j); cellCheck.setCellType(CellType.STRING); cellCheck.setCellStyle(cellStyle); cellCheck.setCellValue("測試 - 0" + (i - 2)); } }
這裡和標題的實現是一樣的,切記一定把那個樣式改了。。。。
(最激動的時候到了 匯出!!!)
try { File file = new File(exportPositionPath); FileOutputStream fileOutputStream = new FileOutputStream(file); wb.write(fileOutputStream); fileOutputStream.close(); } catch (IOException e) { System.err.println(e.getMessage()); }
其中File裡面的引數就是你要匯出檔案的位置,也就是你要把Excel放到哪裡,這裡贈送你們一個桌面地址,哈哈哈。
//當前使用者桌面 File desktopDir = FileSystemView.getFileSystemView() .getHomeDirectory(); String desktopPath = desktopDir.getAbsolutePath(); File file = new File(desktopPath + "\\這是生成的Excel表格.xlsx");
對了差點忘記說一點,如果你的單個欄位資料量比較大怎麼辦?
1、 讓使用者自己把單元格擴寬,檢視詳情
2、我們固定一個最小寬度,是不是會更好一些?
Sheet sheet = wb.createSheet("0");
sheet.setColumnWidth(i, 4300);上面實現的就是拿到當前第一頁的物件,然後給第一頁的每一行設定最小寬度,4300並不是隨便寫的,其實他並不是很大,具體這個需要你們去測試,匹配適合自己的值,第一個引數 i 可能已經被猜到了吧,我用了一個迴圈而已,去迴圈每一行!
【具體實現流程】
import org.apache.poi.hssf.usermodel.HSSFCellStyle; import org.apache.poi.hssf.util.HSSFColor; import org.apache.poi.ss.usermodel.*; import org.apache.poi.ss.util.CellRangeAddress; import org.apache.poi.xssf.usermodel.XSSFFont; import org.apache.poi.xssf.usermodel.XSSFWorkbook;import java.io.*; import java.util.ArrayList; import java.util.List; public class ZxExportExcel { /** * 生成Excel */ public void zxExprotExcelXLSX() { XSSFWorkbook wb = new XSSFWorkbook(); Sheet sheet = wb.createSheet("0"); for (int i = 0; i < 9; i++) { sheet.setColumnWidth(i, 4300); } /** * 單元格 樣式 */ CellStyle cellStyle = wb.createCellStyle(); cellStyle.setBorderTop(BorderStyle.THIN); cellStyle.setBorderBottom(BorderStyle.THIN); cellStyle.setBorderLeft(BorderStyle.THIN); cellStyle.setBorderRight(BorderStyle.THIN); cellStyle.setTopBorderColor(HSSFColor.BLACK.index); cellStyle.setBottomBorderColor(HSSFColor.BLACK.index); cellStyle.setLeftBorderColor(HSSFColor.BLACK.index); cellStyle.setRightBorderColor(HSSFColor.BLACK.index); cellStyle.setAlignment(HSSFCellStyle.ALIGN_CENTER); // 水平居中 cellStyle.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER); // 上下居中 /** * 標題樣式 樣式 */ XSSFFont titleFont = wb.createFont(); titleFont.setFontHeight(24); titleFont.setBold(true); CellStyle titleCellStyle = wb.createCellStyle(); titleCellStyle.setBorderTop(BorderStyle.THIN); titleCellStyle.setBorderBottom(BorderStyle.THIN); titleCellStyle.setBorderLeft(BorderStyle.THIN); titleCellStyle.setBorderRight(BorderStyle.THIN); titleCellStyle.setTopBorderColor(HSSFColor.BLACK.index); titleCellStyle.setBottomBorderColor(HSSFColor.BLACK.index); titleCellStyle.setLeftBorderColor(HSSFColor.BLACK.index); titleCellStyle.setRightBorderColor(HSSFColor.BLACK.index); titleCellStyle.setAlignment(HSSFCellStyle.ALIGN_CENTER); // 水平居中 titleCellStyle.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER); // 上下居中 titleCellStyle.setFont(titleFont); /** * 主 標題 在這裡插入主標題 */ Row titleRow; Cell titleCell; sheet.addMergedRegion(new CellRangeAddress((short) 0, (short) 2, (short) 0, (short) 8)); for (int i = 0; i <= 2; i++) { titleRow = sheet.createRow(i); for (int j = 0; j < 9; j++) { titleCell = titleRow.createCell(j); titleCell.setCellType(CellType.STRING); titleCell.setCellStyle(titleCellStyle); titleCell.setCellValue("2018年度能源科技進步獎"); } } /** * 列 標題 在這裡插入標題 */ Row rowLabel; Cell cellLabel; for (int i = 3; i < 4; i++) { rowLabel = sheet.createRow(i); for (int j = 0; j < 9; j++) { cellLabel = rowLabel.createCell(j); cellLabel.setCellType(CellType.STRING); cellLabel.setCellStyle(cellStyle); cellLabel.setCellValue("測試標題列【" + (j + 1) + "】"); } } /** * 列 資料 在這裡插入資料 */ Row rowCheck; Cell cellCheck; for (int i = 3; i < 2000; i++) { rowCheck = sheet.createRow((i + 1)); for (int j = 0; j < 9; j++) { cellCheck = rowCheck.createCell(j); cellCheck.setCellType(CellType.STRING); cellCheck.setCellStyle(cellStyle); cellCheck.setCellValue("測試 - 0" + (i - 2)); } } /** * 頁尾 */ setExcelFooterName("測試", 0, wb); /** * 進行匯出 */ exportOutPutExcel("C:\\Users\\Admin\\Desktop\\ExportExcel.xlsx", wb); } /** * 設定Excel頁尾 */ public void setExcelFooterName(String customExcelFooterName, int setExcelFooterNumber, XSSFWorkbook wb) { wb.setSheetName(setExcelFooterNumber, customExcelFooterName); } /** * 輸出流 匯出Excel到桌面 */ public void exportOutPutExcel(String exportPositionPath, XSSFWorkbook wb) { try { File file = new File(exportPositionPath); FileOutputStream fileOutputStream = new FileOutputStream(file); wb.write(fileOutputStream); fileOutputStream.close(); } catch (IOException e) { System.err.println(e.getMessage()); } } public static void main(String[] args) { new ZxExportExcel().zxExprotExcelXLSX();} }
簡單的使用了JAVA類去匯出,仔細一看是不是很簡單。
過段時間出一個Excel匯入的部落格! 期待吧!!