SpringBoot+EasyPoi實現(xiàn)excel導出功能
在實際項目開發(fā)中,對于Excel的導入導出還是很常見的需求,比如說將數(shù)據(jù)根據(jù)模板批量導入到數(shù)據(jù)庫中,以及將數(shù)據(jù)庫中的數(shù)據(jù)批量導出陳Excel的形式
現(xiàn)有需求: 根據(jù)檢索條件查詢列表并將結(jié)果導出到excel
Easypoi文檔:https://easypoi.mydoc.io/#text_186900
EasyPoi的主要特點
1.設計精巧,使用簡單
2.接口豐富,擴展簡單
3.默認值多,write less do more
4.spring mvc支持,web導出可以簡單明了
實現(xiàn)過程
1.創(chuàng)建一個Spring Boot項目
快速生成鏈接:start.spring.io
2.引入EasyPoi的pom依賴
<!--EasyPoi導入導出--> <dependency> <groupId>cn.afterturn</groupId> <artifactId>easypoi-base</artifactId> <version>4.3.0</version> </dependency> <dependency> <groupId>cn.afterturn</groupId> <artifactId>easypoi-web</artifactId> <version>4.3.0</version> </dependency> <dependency> <groupId>cn.afterturn</groupId> <artifactId>easypoi-annotation</artifactId> <version>4.3.0</version> </dependency>
- easypoi-base 導入導出的工具包,可以完成Excel導出,導入,Word的導出,Excel的導出功能
- easypoi-web 耦合了spring-mvc 基于AbstractView,極大的簡化spring-mvc下的導出功能
- easypoi-annotation 基礎(chǔ)注解包,作用與實體對象上,拆分后方便maven多工程的依賴管理
sax 導入使用xercesImpl這個包(這個包可能造成奇怪的問題哈),word導出使用poi-scratchpad,都作為可選包了
pom.xml中的所有依賴:
<dependencies> <!-- 導入web支持:SpringMVC開發(fā)支持,Servlet相關(guān)的程序 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <scope>runtime</scope> <optional>true</optional> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <!-- mybatis相關(guān)的依賴 --> <!--mybatis-plus自動的維護了mybatis以及mybatis-spring的依賴, 在springboot中這三者不能同時的出現(xiàn),避免版本的沖突,表示:跳進過這個坑--> <!--mybatis-plus--> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> <version>3.4.3</version> </dependency> <!--mysql驅(qū)動--> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <scope>runtime</scope> </dependency> <!-- alibaba的druid數(shù)據(jù)庫連接池 --> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> <version>1.1.20</version> </dependency> <!-- alibaba的druid數(shù)據(jù)庫連接池 --> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid-spring-boot-starter</artifactId> <version>1.1.20</version> </dependency> <!--swagger2依賴--> <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger2</artifactId> <version>2.9.2</version> <!--排除自身的依賴1.5.20版本--> <exclusions> <exclusion> <groupId>io.swagger</groupId> <artifactId>swagger-models</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger-ui</artifactId> <version>2.9.2</version> </dependency> <!--此版本解決 example="" 造成的 空字符串""無法轉(zhuǎn)成Number 問題--> <dependency> <groupId>io.swagger</groupId> <artifactId>swagger-models</artifactId> <version>1.5.21</version> </dependency> <!--EasyPoi導入導出--> <dependency> <groupId>cn.afterturn</groupId> <artifactId>easypoi-base</artifactId> <version>4.3.0</version> </dependency> <dependency> <groupId>cn.afterturn</groupId> <artifactId>easypoi-web</artifactId> <version>4.3.0</version> </dependency> <dependency> <groupId>cn.afterturn</groupId> <artifactId>easypoi-annotation</artifactId> <version>4.3.0</version> </dependency> <!--fastjson--> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.71</version> </dependency> </dependencies>
3.編寫excel工具類
package com.example.easypoiexceldemo.utils; import cn.afterturn.easypoi.excel.ExcelExportUtil; import cn.afterturn.easypoi.excel.entity.ExportParams; import cn.afterturn.easypoi.excel.entity.enmus.ExcelType; import org.apache.commons.lang3.StringUtils; import org.apache.poi.ss.usermodel.Workbook; import org.springframework.beans.BeanUtils; import javax.servlet.ServletOutputStream; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.net.URLEncoder; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Collection; import java.util.Date; import java.util.List; /** * excel工具類 * @author qzz */ public class ExcelUtils { /** * Excel導出 * * @param response response * @param fileName 文件名 * @param list 數(shù)據(jù)List * @param pojoClass 對象Class */ public static void exportExcel(HttpServletResponse response, String fileName, Collection<?> list, Class<?> pojoClass) throws IOException { if (StringUtils.isBlank(fileName)) { //當前日期 SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd"); fileName = df.format(new Date()); } Workbook workbook = ExcelExportUtil.exportExcel(new ExportParams(fileName, fileName, ExcelType.HSSF), pojoClass, list); response.setCharacterEncoding("UTF-8"); response.setHeader("content-Type", "application/vnd.ms-excel"); response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8") + ".xls"); ServletOutputStream out = response.getOutputStream(); workbook.write(out); out.flush(); } /** * Excel導出,先sourceList轉(zhuǎn)換成List<targetClass>,再導出 * * @param response response * @param fileName 文件名 * @param sourceList 原數(shù)據(jù)List * @param targetClass 目標對象Class */ public static void exportExcelToTarget(HttpServletResponse response, String fileName, Collection<?> sourceList, Class<?> targetClass) throws Exception { List targetList = new ArrayList<>(sourceList.size()); for (Object source : sourceList) { Object target = targetClass.newInstance(); BeanUtils.copyProperties(source, target); targetList.add(target); } exportExcel(response, fileName, targetList, targetClass); } /** * Excel導出----設置title---sheetName---要求Collection<?> list是Class<?> pojoClass類型的 * * @param response response * @param fileName 文件名 * @param list 數(shù)據(jù)List * @param pojoClass 對象Class */ public static void exportExcel(HttpServletResponse response, String title, String sheetName, String fileName, Collection<?> list, Class<?> pojoClass) throws IOException { if (StringUtils.isBlank(fileName)) { //當前日期 SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd"); fileName = df.format(new Date()); } Workbook workbook = ExcelExportUtil.exportExcel(new ExportParams(title, sheetName, ExcelType.HSSF), pojoClass, list); response.setCharacterEncoding("UTF-8"); response.setHeader("content-Type", "application/vnd.ms-excel"); response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8") + ".xls"); ServletOutputStream out = response.getOutputStream(); workbook.write(out); out.flush(); } }
4.在實體類上加注解@Excel
我這邊使用了lombok。getter setter和構(gòu)造方法通過注解 @Data @AllArgsConstructor進行添加,不使用lombok也可手動添加。
要導出的數(shù)據(jù)可在實體類對應屬性上方加**@Excel()注解
**。可定義導出列的名稱、寬度,以及性別可區(qū)分化(一般數(shù)據(jù)庫中存儲的性別為1和2),日期格式化等等。
package com.example.easypoiexceldemo.excel; import cn.afterturn.easypoi.excel.annotation.Excel; import lombok.Data; import java.util.Date; /** * 商品 * @author qzz */ @Data public class ProductExcel { /** * 商品id */ @Excel(name = "商品id") private Integer product_id; /** * 商品標題 */ @Excel(name="商品標題") private String title; /** * 商品副標題 */ @Excel(name="商品副標題") private String sub_title; /** * 商品售價 */ @Excel(name="商品售價") private Double sale_price; /** * 創(chuàng)建者 */ @Excel(name="創(chuàng)建者") private Integer create_by; /** * 創(chuàng)建時間 */ @Excel(name="創(chuàng)建時間", format = "yyyy-MM-dd") private Date create_time; /** * 修改時間 */ @Excel(name="修改時間", format = "yyyy-MM-dd") private Date update_time; /** * 修改者id */ @Excel(name="修改者id") private Integer update_by; }
@Excel 作用到filed上面,是對Excel一列的一個描述
@Excel 的屬性介紹:
5.Controller
/** * excel導出 * @param response */ @GetMapping("/excel") @ApiOperation("根據(jù)檢索條件查詢列表,導出excel") public void export( HttpServletResponse response) throws IOException { //根據(jù)條件檢索列表 QueryWrapper<Product> queryWrapper = new QueryWrapper(); //根據(jù)條件檢索商品列表 List<Map<String, Object>> list = productService.selectList(queryWrapper); //將List<Map<String, Object>>結(jié)果集轉(zhuǎn)換成List<ProductExcel> List<ProductExcel> productList = MapToEntity.setList(list,ProductExcel.class); //導出excel ExcelUtils.exportExcel(response,null,productList, ProductExcel.class); }
setList方法為工具類,用于將List<Map<String, Object>>結(jié)果集轉(zhuǎn)換成List
MapToEntity工具類:
package com.example.easypoiexceldemo.utils; import org.apache.commons.lang3.StringUtils; import java.lang.reflect.Field; import java.math.BigDecimal; import java.text.ParseException; import java.text.ParsePosition; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; import java.util.List; import java.util.Map; /** * List<Map<String,Object>>到List<T>數(shù)據(jù)轉(zhuǎn)換 * @author qzz */ public class MapToEntity { /** * List<Map<String, Object>> 到 List<T> 數(shù)據(jù)轉(zhuǎn)換 */ public static <T> List<T> setList(final List<Map<String, Object>> srcList, Class<T> clazz) { List<T> list = new ArrayList<>(); for (int i=0;i<srcList.size();i++){ try { T t = clazz.newInstance(); Field[] fields = t.getClass().getDeclaredFields(); for (Field field : fields) { if (!"serialVersionUID".equals(field.getName())) { //設置對象的訪問權(quán)限,保證對private的屬性的訪問 field.setAccessible(true); //讀取配置轉(zhuǎn)換字段名,并從map中取出數(shù)據(jù) Object v = srcList.get(i).get(field.getName()); field.set(t, convert(v, field.getType())); } } list.add(t); } catch (Exception ex) { ex.toString(); } }; return list; } /** * 字段類型轉(zhuǎn)換 */ private static <T> T convert(Object obj, Class<T> type) throws ParseException { if (obj != null && StringUtils.isNotBlank(obj.toString())) { if (type.equals(String.class)) { return (T) obj.toString(); } else if (type.equals(BigDecimal.class)) { return (T) new BigDecimal(obj.toString()); }else if(type.equals(Double.class)){ return (T) Double.valueOf(obj.toString()); }else if(type.equals(Integer.class)){ return (T) Integer.valueOf(obj.toString()); }else if(type.equals(Date.class)){ if(obj!=null){ String timeStr = String.valueOf(obj); String s[] = timeStr.split("T"); SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); return (T) sdf.parse(s[0]+" "+s[1]); }else{ return null; } } else{ //其他類型轉(zhuǎn)換 return (T) obj.toString(); } } return null; } }
6.啟動項目,進行測試
項目啟動成功后,在瀏覽器中輸入 http://localhost:8083/product/excel,進行訪問:
打開導出的excel文檔:
到此這篇關(guān)于SpringBoot+EasyPoi實現(xiàn)excel導出的文章就介紹到這了,更多相關(guān)SpringBoot實現(xiàn)excel導出內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
在Spring?MVC中使用@ControllerAdvice創(chuàng)建全局異常處理器的方法
在Spring?MVC中,可以使用@ControllerAdvice或@RestControllerAdvice注解來定義全局異常處理器類,并使用?@ExceptionHandler注解來定義處理特定異常的方法,本文就給大家介紹了Spring?MVC?@ControllerAdvice創(chuàng)建處理器的方法,需要的朋友可以參考下2023-08-08Java并發(fā)編程之ConcurrentLinkedQueue解讀
這篇文章主要介紹了Java并發(fā)編程之ConcurrentLinkedQueue解讀,非阻塞的實現(xiàn)方式則可以使用循環(huán)CAS的方式來實現(xiàn),而ConcurrentLinkedQueue就是juc包中自帶的經(jīng)典非堵塞方式實現(xiàn)的工具類,需要的朋友可以參考下2023-12-12Spring實現(xiàn)定時任務的幾種方式總結(jié)
Spring Task 是 Spring 框架提供的一種任務調(diào)度和異步處理的解決方案,可以按照約定的時間自動執(zhí)行某個代碼邏輯它可以幫助開發(fā)者在 Spring 應用中輕松地實現(xiàn)定時任務、異步任務等功能,提高應用的效率和可維護性,需要的朋友可以參考下本文2024-07-07