Apache POI的簡單介紹與應用

介紹

Apache POI 是一個處理Miscrosoft Office各種文件格式的開源項目。我們可以使用 POI 在 Java 程序中對Miscrosoft Office各種文件進行讀寫操作。PS: 一般情況下,POI 都是用于操作 Excel 文件,如圖:
在這里插入圖片描述
Apache POI 的應用場景:

  • 銀行網銀系統導出交易明細
  • 各種業務系統導出Excel報表
  • 批量導入業務數據

入門案例

  1. 導入Apache POI的maven坐標:
<dependency><groupId>org.apache.poi</groupId><artifactId>poi</artifactId>
</dependency>
<dependency><groupId>org.apache.poi</groupId><artifactId>poi-ooxml</artifactId>
</dependency>
  1. 數據寫入Excel文件:
public class POITest {/*** 通過POI創建Excel,并寫入文件內容*/public static void write() throws Exception {// 在內存中創建一個Excel文件XSSFWorkbook excel = new XSSFWorkbook();// 在Excel文件中創建一個sheet頁XSSFSheet sheet = excel.createSheet("info");// 在sheet頁中創建行對象,rownum的編號從0開始,寫1表示創建第2行XSSFRow row = sheet.createRow(1);// 在行中創建單元格, columnIndex也是從0開始,使用setCellValue寫入文本內容row.createCell(1).setCellValue("姓名");row.createCell(2).setCellValue("城市");// 創建新的一行row = sheet.createRow(2);row.createCell(1).setCellValue("張三");row.createCell(2).setCellValue("成都");row = sheet.createRow(3);row.createCell(1).setCellValue("李四");row.createCell(2).setCellValue("北京");FileOutputStream out = new FileOutputStream("/home/zxy/Projects/info.xlsx");excel.write(out);// 關閉資源out.close();excel.close();}public static void main(String[] args) throws Exception{write();}
}

運行效果:
在這里插入圖片描述

  1. 從Excel中讀取數據
    /*** 通過POI讀取Excel中的內容* @throws Exception*/public static void read() throws Exception{// 讀取磁盤上已經存在的Excel文件FileInputStream in = new FileInputStream(new File("/home/zxy/Projects/info.xlsx"));XSSFWorkbook excel = new XSSFWorkbook(in);// 讀取Excel文件中的第一個Sheet頁XSSFSheet sheet = excel.getSheetAt(0);// 獲取sheet頁中數據所在最后一行的行號int lastRowNum = sheet.getLastRowNum();for (int i = 1; i <= lastRowNum; i++) {// 獲得某一行XSSFRow row = sheet.getRow(i);// 獲得單元格對象String cellValue1 = row.getCell(1).getStringCellValue();String cellValue2 = row.getCell(2).getStringCellValue();System.out.println(cellValue1 + "  " + cellValue2);}// 關閉資源excel.close();in.close();}public static void main(String[] args) throws Exception{read();}

效果:
在這里插入圖片描述

應用

場景:導出(并下載)商戶最近30天的運營數據
注意:對導出數據的請求并沒有返回數據,因為報表導出功能本質上是文件下載,服務端會通過輸出流將Excel文件下載到客戶端瀏覽器。
實現步驟:

  1. 設計Excel模板文件
  2. 查詢近30天的運營數據
  3. 將查詢到的運營數據寫入模板文件
  4. 通過輸出流將Excel文件下載到客戶端瀏覽器

雖然POI可以設置文件的字體、字號、合并單元格等格式,但這會使得代碼變得非常復雜,所以提前在文本編輯器中設置好Excel的模版文件,然后通過讀取模版文件來填充數據,從而可以簡化代碼。

具體代碼:
controller部分:

	/*** 導出運營數據報表* @param response*/@GetMapping("/export")@ApiOperation("導出運營數據報表")public void export(HttpServletResponse response){reportService.exportBusinessData(response);}

Service部分:

	/*** 導出運營數據報表* @param response*/void exportBusinessData(HttpServletResponse response);

重點: Service的實現類中對應的方法:

	/*** 導出運營數據報表** @param response*/@Overridepublic void exportBusinessData(HttpServletResponse response) {// 1. 查詢數據庫,獲取營業數據 --- 查詢最近30天的數據LocalDate dateBegin = LocalDate.now().minusDays(30);LocalDate dateEnd = LocalDate.now().minusDays(1);// 查詢概覽數據BusinessDataVO businessData = workspaceService.getBusinessData(LocalDateTime.of(dateBegin, LocalTime.MIN), LocalDateTime.of(dateEnd, LocalTime.MAX));// 2. 通過POI將數據寫入到Excel文件中InputStream in = this.getClass().getClassLoader().getResourceAsStream("template/運營數據報表模板.xlsx");try {// 基于模板文件創建一個新的Excel文件XSSFWorkbook excel = new XSSFWorkbook(in);// 獲取表格文件的Sheet頁XSSFSheet sheet = excel.getSheet("Sheet1");// 填充數據——時間sheet.getRow(1).getCell(1).setCellValue("時間:" + dateBegin + "至" + dateEnd);// 獲取第4行XSSFRow row = sheet.getRow(3);row.getCell(2).setCellValue(businessData.getTurnover());row.getCell(4).setCellValue(businessData.getOrderCompletionRate());row.getCell(6).setCellValue(businessData.getNewUsers());// 獲取第5行row = sheet.getRow(4);row.getCell(2).setCellValue(businessData.getValidOrderCount());row.getCell(4).setCellValue(businessData.getUnitPrice());// 填充明細數據for (int i = 0; i < 30; i++) {LocalDate date = dateBegin.plusDays(i);// 查詢某一天的數據BusinessDataVO businessDataVO = workspaceService.getBusinessData(LocalDateTime.of(date, LocalTime.MIN), LocalDateTime.of(date, LocalTime.MAX));// 獲得某一行row = sheet.getRow(7 + i);row.getCell(1).setCellValue(date.toString());row.getCell(2).setCellValue(businessDataVO.getTurnover());row.getCell(3).setCellValue(businessDataVO.getValidOrderCount());row.getCell(4).setCellValue(businessDataVO.getOrderCompletionRate());row.getCell(5).setCellValue(businessDataVO.getUnitPrice());row.getCell(6).setCellValue(businessDataVO.getNewUsers());}// 3. 通過輸出流將Excel文件下載到客戶端瀏覽器ServletOutputStream out = response.getOutputStream();excel.write(out);// 關閉資源out.close();excel.close();} catch (IOException e) {throw new RuntimeException(e);}}

代碼細節補充:
workspaceService.getBusinessData:

@Overridepublic BusinessDataVO getBusinessData(LocalDateTime begin, LocalDateTime end) {/*** 營業額:當日完成訂單的總額* 有效訂單:當日完成訂單的數量* 訂單完成率:有效訂單數 / 總訂單數* 新增用戶:當日新增用戶的數量*/Map map = new HashMap();map.put("begin",begin);map.put("end",end);// 查詢訂單總數Integer totalOrderCount = orderMapper.getByMap(map);map.put("status", Orders.COMPLETED);// 營業額Double turnover = orderMapper.sumByMap(map);turnover = turnover ==null? 0.0 :turnover;// 有效訂單數Integer validOrderCount = orderMapper.getByMap(map);Double unitPrice = 0.0;Double orderCompletionRate = 0.0;if(totalOrderCount != 0 && validOrderCount != 0){// 訂單完成率orderCompletionRate = validOrderCount.doubleValue() / totalOrderCount;//平均客單價unitPrice = turnover / validOrderCount;}// 新增用戶數Integer newUsers = userMapper.countByMap(map);return BusinessDataVO.builder().turnover(turnover).validOrderCount(validOrderCount).orderCompletionRate(orderCompletionRate).unitPrice(unitPrice).newUsers(newUsers).build();}

實現效果:
在這里插入圖片描述

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/717855.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/717855.shtml
英文地址,請注明出處:http://en.pswp.cn/news/717855.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

SQL無列名注入

SQL無列名注入 ? 前段時間&#xff0c;隊里某位大佬發了一個關于sql注入無列名的文章&#xff0c;感覺好像很有用&#xff0c;特地研究下。 關于 information_schema 數據庫&#xff1a; ? 對于這一個庫&#xff0c;我所知曉的內容并不多&#xff0c;并且之前總結SQL注入的…

設計模式-橋接模式實踐案例

橋接模式&#xff08;Bridge Pattern&#xff09;是一種結構型設計模式&#xff0c;用于將抽象與實現分離&#xff0c;使它們可以獨立地變化。這種模式通過提供一個橋接結構&#xff0c;可以將實現接口的實現部分和抽象層中可變化的部分分離開來。 以下是一個使用 Java 實現橋…

【數據結構】_包裝類與泛型

目錄 1. 包裝類 1.1 基本數據類型和對應的包裝類 1.2 &#xff08;自動&#xff09;裝箱和&#xff08;自動&#xff09;拆箱 1.2.1 裝箱與拆箱 1.2.2 自動&#xff08;顯式&#xff09;裝箱與自動&#xff08;顯式&#xff09;拆箱 1.3 valueOf()方法 2. 泛型類 2.1 泛…

【深度學習筆記】計算機視覺——目標檢測和邊界框

目標檢測和邊界框 前面的章節&#xff08;例如 sec_alexnet— sec_googlenet&#xff09;介紹了各種圖像分類模型。 在圖像分類任務中&#xff0c;我們假設圖像中只有一個主要物體對象&#xff0c;我們只關注如何識別其類別。 然而&#xff0c;很多時候圖像里有多個我們感興趣…

某大型制造企業數字化轉型規劃方案(附下載)

目錄 一、項目背景和目標 二、業務現狀 1. 總體應用現狀 2. 各模塊業務問題 2.1 設計 2.2 仿真 2.3 制造 2.4 服務 2.5 管理 三、業務需求及預期效果 1. 總體業務需求 2. 各模塊業務需求 2.1 設計 2.2 仿真 2.3 制造 2.4 服務 2.5 管理 四、…

在vue中對keep-alive的理解,它是如何實現的,具體緩存的是什么?

對keep-alive的理解&#xff0c;它是如何實現的&#xff0c;具體緩存的是什么&#xff1f; &#xff08;1&#xff09;keep-alive有以下三個屬性&#xff1a;注意&#xff1a;keep-alive 包裹動態組件時&#xff0c;會緩存不活動的組件實例。主要流程 &#xff08;2&#xff09…

數字化轉型導師堅鵬:證券公司數字化營銷

證券公司數字化營銷 ——借力數字化技術實現零售業務的批量化、精準化、場景化、智能化營銷 課程背景&#xff1a; 很多證券公司存在以下問題&#xff1a; 不知道如何提升證券公司數字化營銷能力&#xff1f; 不知道證券公司如何開展數字化營銷工作&#xff1f; 不知道…

胎神游戲集第二期

延續上一期 一、海島奇胎 #include<bits/stdc.h> #include<windows.h> #include<stdio.h> #include<conio.h> #include<time.h> using namespace std; typedef BOOL (WINAPI *PROCSETCONSOLEFONT)(HANDLE, DWORD); PROCSETCONSOLEFONT SetCons…

Linux 安裝pip和換源

一 配置文檔 Linux和macOS&#xff1a; 全局配置&#xff1a;/etc/pip.conf 用戶級配置&#xff1a;~/.pip/pip.conf 或 ~/.config/pip/pip.conf 二 下載 和 安裝 # pip 安裝 wget https://bootstrap.pypa.io/get-pip.py python get-pip.py 三 查看和升級 pip -Vpython -m…

GO語言學習筆記(與Java的比較學習)(十一)

協程與通道 什么是協程 一個應用程序是運行在機器上的一個進程&#xff1b;進程是一個運行在自己內存地址空間里的獨立執行體。一個進程由一個或多個操作系統線程組成&#xff0c;這些線程其實是共享同一個內存地址空間的一起工作的執行體。 并行是一種通過使用多處理器以提…

Java虛擬機 - JVM

JVM的內存區域劃分 JVM它其實也是一個進程,進程運行的過程中,會從操作系統中申請一些資源.內存就是其中的一種.這些內存就支撐了java程序的運行.JVM從系統中申請的一大塊內存,會根據實際情況和使用用途來劃分出不同的空間,這個就是區域劃分.它一般分為 堆區, 棧區, 程序計數器…

springboot240基于Spring boot的名城小區物業管理系統

基于Spring boot的名城小區物業管理系統的設計與實現 摘要 當下&#xff0c;正處于信息化的時代&#xff0c;許多行業順應時代的變化&#xff0c;結合使用計算機技術向數字化、信息化建設邁進。以前相關行業對于物業信息的管理和控制&#xff0c;采用人工登記的方式保存相關數…

InnoDB存儲引擎對MVCC的實現

MVCC MVCC的目的 在搞清楚MVCC之前,我們要搞懂一個問題,MVCC到底解決的是什么問題? 我用一句話概括,那就是為了解決讀-寫可以一起的問題! 在我們的印象里,InnoDB可以讀讀并發,不能讀寫并發,或者寫寫并發 這是很正常的想法,因為如果讀寫并發的化,會有并發問題 而對于寫寫…

帶壓縮路徑的并查集

find帶壓縮路徑的并查集 int fa[]; void init(int _size) {for(int i0;i<_size;i){fa[i] i;} } int find(int aim) {int cur aim;while (fa[aim] ! aim){aim fa[aim];}while (fa[cur] ! cur){int tmp cur;cur fa[cur];fa[tmp] aim;}return aim; } void join(int a,in…

構建安全的REST API:OAuth2和JWT實踐

引言 大家好&#xff0c;我是小黑&#xff0c;小黑在這里跟咱們聊聊&#xff0c;為什么REST API這么重要&#xff0c;同時&#xff0c;為何OAuth2和JWT在構建安全的REST API中扮演著不可或缺的角色。 想象一下&#xff0c;咱們每天都在使用的社交媒體、在線購物、銀行服務等等…

file-upload-download

方式一 情況1&#xff1a; PostMapping("/download1")public ResponseEntity<byte[]> download1() throws Exception {// 下載文件目錄位置FileInputStream fis new FileInputStream("C:\\Users\\wsd\\Pictures\\susu.jpg");// 一次讀取bytes.leng…

Sqli-labs靶場第16關詳解[Sqli-labs-less-16]自動化注入-SQLmap工具注入

Sqli-labs-Less-16 #自動化注入-SQLmap工具注入 SQLmap用戶手冊&#xff1a;文檔介紹 - sqlmap 用戶手冊 以非交互式模式運行 --batch 當你需要以批處理模式運行 sqlmap&#xff0c;避免任何用戶干預 sqlmap 的運行&#xff0c;可以強制使用 --batch 這個開關。這樣&#xff0…

【視頻編碼\VVC】多樣化視頻編碼工具了解

除了通用編碼工具&#xff0c;VVC還針對特定特性的全景視頻、屏幕視頻開發了特定的編碼工具。 全景視頻編碼 360度全包圍視角的球面視頻。為了采用傳統的視頻編碼&#xff0c;全景視頻需要轉換為平面視頻&#xff0c;經緯度等角映射&#xff08;ERF&#xff09;、立方體映射&…

PostgreSQL操作筆記

基礎操作 數據庫相關 -- 查看所有數據庫 \l-- 切換到指定數據庫 \c 庫名-- 查看庫中所有表 \d執行SQL腳本 如果有現成的SQL腳本&#xff1a; \i 腳本路徑路徑一般需要用單引號引起來。 如果需要當場編輯一次性的SQL腳本&#xff0c;可以&#xff1a; \e執行上述命令后會進…

GC機制以及Golang的GC機制詳解

要了解Golang的GC機制,就需要了解什么事GC,以及GC有哪幾種實現方式 一.什么是GC 當一個電腦上的動態內存不再需要時&#xff0c;就應該予以釋放&#xff0c;以讓出內存&#xff0c;這種內存資源管理&#xff0c;稱為垃圾回收&#xff08;Garbage Collection&#xff09;&#x…