最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

SpringBoot整合POI導(dǎo)出通用Excel的方法示例

 更新時間:2020年08月23日 09:49:04   作者:mengdi_cao  
這篇文章主要介紹了SpringBoot整合POI導(dǎo)出通用Excel的方法示例,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

一、準(zhǔn)備工作

1、pom依賴

在pom.xml中加入POI的依賴

<dependency>
 <groupId>org.apache.poi</groupId>
 <artifactId>poi-ooxml</artifactId>
 <version>3.11-beta1</version>
</dependency>
<dependency>
 <groupId>org.apache.poi</groupId>
 <artifactId>poi-ooxml-schemas</artifactId>
 <version>3.11-beta1</version>
</dependency>

2、自定義注解

自定義注解,用于定義excel單元格的相關(guān)信息,用在需要導(dǎo)出的類上。

大家可以根據(jù)自己的實(shí)際需求來定義更多的內(nèi)容。

@Retention(RetentionPolicy.RUNTIME)
public @interface ExcelResources {
 
 int order() default 9999;//定義字段在excel的單元格列坐標(biāo)位置

 String title() default "";//定義列坐標(biāo)對應(yīng)的標(biāo)題

 int cloumn() default 100;//定義列寬

 String pattern() default "";//定義日期顯示格式

}

3、定義需要導(dǎo)出的實(shí)體

舉例說明@ExcelResources 的應(yīng)用場景,我們創(chuàng)建一個demoModel,包含姓名、年齡、性別、日期。

后邊的excel導(dǎo)出例子也采用這個實(shí)體類來舉例。

@Data
public class ExcelDemoModel {

  @ExcelResources(order=0,title = "姓名",cloumn = 10)
  private String name;

  @ExcelResources(order=1,title = "年齡",cloumn = 10)
  private Integer age;

  @ExcelResources(order=2,title = "創(chuàng)建時間",cloumn = 24,pattern = "yyyy-MM-dd HH:mm:ss")
  private Date createTime;

  @ExcelResources(order=3,title = "性別",cloumn = 10)
  private SexType sex;//枚舉
  
}

4、定義導(dǎo)出輔助類

用于存放導(dǎo)出的excel對應(yīng)標(biāo)題和列寬

@Data
@NoArgsConstructor
@AllArgsConstructor
public class TitleAndCloumn {

  private String title;//標(biāo)題
  private int cloumn;//列寬

}

二、具體的導(dǎo)出方法

1、導(dǎo)出主要方法

@Service
public class ExcelService {

  private static float title_row_height=30;//標(biāo)題行高
  private static float data_row_height=25;//數(shù)據(jù)行高

 public void exportExcel(HttpServletRequest request, HttpServletResponse response, String fileName ,List<?> excelDatas,Class<?> clz ) {
 
    try {

      HSSFWorkbook resultWb=new HSSFWorkbook();
      HSSFSheet sheet=resultWb.createSheet();//創(chuàng)建sheet

  //根據(jù)類類型信息獲取導(dǎo)出的excel對應(yīng)的標(biāo)題和列寬 key-列號,value-標(biāo)題和列寬
      HashMap<Integer, TitleAndCloumn> orderTitleAndCloumnMap=getTitleAndCloumnMap(clz);

      //設(shè)置列寬
      orderTitleAndCloumnMap.forEach((k,v) -> {
        sheet.setColumnWidth(k, v.getCloumn()*256);
      });

      HSSFRow row0=sheet.createRow(0);
      //設(shè)置標(biāo)題行高
      row0.setHeightInPoints(title_row_height);

  //創(chuàng)建標(biāo)題單元格格式
      HSSFCellStyle titleCellStyle=getCellStyle(resultWb,11,true,HSSFColor.BLACK.index);
      //填充標(biāo)題行內(nèi)容
      orderTitleAndCloumnMap.forEach((k,v) -> {
        HSSFCell row0Cell=row0.createCell(k);
        row0Cell.setCellValue(v.getTitle());
        row0Cell.setCellStyle(titleCellStyle);
      });

  //創(chuàng)建正文單元格格式
      HSSFCellStyle dataStyle = getCellStyle(resultWb,11,false,HSSFColor.BLACK.index);

  //將正文轉(zhuǎn)換為excel數(shù)據(jù)
      int rowNum=1;
      for(Object data:excelDatas){

        HSSFRow row=sheet.createRow(rowNum++);
        row.setHeightInPoints(data_row_height);
  //獲取對象值 key-列號 value-String值
        HashMap<Integer,String> orderValueMap=getValueMap(data);
        orderValueMap.forEach((k,v) ->{
          HSSFCell cell=row.createCell(k);
          cell.setCellValue(v);
          cell.setCellStyle(dataStyle);
            }
        );
      }

      String downFileName=fileName+".xls";
      response.setContentType("application/vnd.ms-excel; charset=UTF-8");// application/x-download
      response.setHeader("Content-Disposition", "attachment; "
          +encodeFileName(request, downFileName));

      OutputStream outputStream = response.getOutputStream();
      resultWb.write(outputStream);
      outputStream.flush();
      outputStream.close();
      resultWb.close();

    }catch (Exception e1) {
      e1.printStackTrace();
    }

  }
}

2、通過反射獲取excel標(biāo)題和列寬

/**
   * 獲取類的屬性對應(yīng)單元格標(biāo)題和列寬
   * @param
   * @return
   */
  private static HashMap<Integer, TitleAndCloumn> getTitleAndCloumnMap(Class<?> clz) {

    HashMap<Integer, TitleAndCloumn> orderTitleAndCloumnMap=new HashMap<>();

    Field[] fs = clz.getDeclaredFields();
    for(Field f:fs) {
      f.setAccessible(true);
      if(f.isAnnotationPresent(ExcelResources.class)) {
        Integer order=f.getAnnotation(ExcelResources.class).order();
        String title=f.getAnnotation(ExcelResources.class).title();
        int cloumn=f.getAnnotation(ExcelResources.class).cloumn();

        TitleAndCloumn titleAndCloumn=new TitleAndCloumn(title,cloumn);
        orderTitleAndCloumnMap.put(order,titleAndCloumn);
      }
    }

    return orderTitleAndCloumnMap;

  }

3、創(chuàng)建CellStyle

通過傳入?yún)?shù)定義簡單地CellStyle

public HSSFCellStyle getCellStyle(HSSFWorkbook workbook,int fontSize,boolean isBoleaWeight,short color){

    HSSFCellStyle style = workbook.createCellStyle();
    style.setAlignment(HSSFCellStyle.ALIGN_CENTER);//水平居中
    style.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);//垂直居中

    style.setBorderBottom(HSSFCellStyle.BORDER_THIN);
    style.setBorderLeft(HSSFCellStyle.BORDER_THIN);
    style.setBorderRight(HSSFCellStyle.BORDER_THIN);
    style.setBorderTop(HSSFCellStyle.BORDER_THIN);

    HSSFFont font = workbook.createFont();
    font.setFontHeightInPoints((short) fontSize);//字號
    font.setColor(color);//顏色
    font.setFontName("宋體");//字體

    if(isBoleaWeight){
      font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD); //字體加粗
    }

    style.setWrapText(true);
    style.setFont(font);

    return style;

  }

4、通過反射獲取對象信息并處理成String字符串

我這里只涉及到基本數(shù)據(jù)類型和Date以及枚舉的值獲取和轉(zhuǎn)換,小伙伴可以根據(jù)自己的實(shí)際情況進(jìn)行修改。

/**
   * 獲取對象的屬性對應(yīng)單元格坐標(biāo)和值的鍵值對
   * @param obj
   * @return
   */
  private static HashMap<Integer, String> getValueMap(Object obj) throws IllegalAccessException {

    HashMap<Integer, String> result=new HashMap<>();

    Class<?> clz=obj.getClass();
    Field[] fs = clz.getDeclaredFields();
    for(Field f:fs) {
      f.setAccessible(true);
      if(f.isAnnotationPresent(ExcelResources.class)) {
        Integer order=f.getAnnotation(ExcelResources.class).order();
        String value="";

        Object valueObj=f.get(obj);
        if(valueObj!=null) {
   //日期格式進(jìn)行特殊處理
          if(f.getType()==Date.class){

            String pattern=f.getAnnotation(ExcelResources.class).pattern();
            if(StringUtils.isEmpty(pattern)){
              pattern="yyyy-MM-dd HH:mm:ss";
            }
            SimpleDateFormat sdf=new SimpleDateFormat(pattern);
            value=sdf.format(valueObj);
          }else{
            value=valueObj.toString();//其他格式調(diào)用toString方法,這里枚舉就需要定義自己的toString方法
          }

        }

        result.put(order, value);

      }
    }

    return result;
  }

5、枚舉的定義

如果有用到枚舉存儲在數(shù)據(jù)庫的小伙伴,可以自定義枚舉的toString方法來實(shí)現(xiàn)excel導(dǎo)出時候相應(yīng)的內(nèi)容

public enum SexType {
 
 male("男"),
 female("女"),
 ;

 private String typeName;

 SexType(String typeName) {
 this.typeName = typeName;
 }

 @Override
 public String toString() {
 return typeName;
 }

}

6、encodeFileName

 /**
   * 根據(jù)不同的瀏覽器生成不同類型中文文件名編碼
   *
   * @param request
   * @param fileName
   * @return
   * @throws UnsupportedEncodingException
   */
  public static String encodeFileName(HttpServletRequest request, String fileName)
      throws UnsupportedEncodingException
  {

    String new_filename = URLEncoder.encode(fileName, "UTF8").replaceAll("\\+", "%20");

    String agent = request.getHeader("USER-AGENT").toLowerCase();
    if (null != agent && -1 != agent.indexOf("msie"))
    {
      /**
       * IE瀏覽器,只能采用URLEncoder編碼
       */
      return "filename=\"" + new_filename +"\"";
    }else if (null != agent && -1 != agent.indexOf("applewebkit")){
      /**
       * Chrome瀏覽器,只能采用ISO編碼的中文輸出
       */
      return "filename=\"" + new String(fileName.getBytes("UTF-8"),"ISO8859-1") +"\"";
    } else if (null != agent && -1 != agent.indexOf("opera")){
      /**
       * Opera瀏覽器只可以使用filename*的中文輸出
       * RFC2231規(guī)定的標(biāo)準(zhǔn)
       */
      return "filename*=" + new_filename ;
    }else if (null != agent && -1 != agent.indexOf("safari")){
      /**
       * Safani瀏覽器,只能采用iso編碼的中文輸出
       */
      return "filename=\"" + new String(fileName.getBytes("UTF-8"),"ISO8859-1") +"\"";
    }else if (null != agent && -1 != agent.indexOf("firefox"))
    {
      /**
       * Firfox瀏覽器,可以使用filename*的中文輸出
       * RFC2231規(guī)定的標(biāo)準(zhǔn)
       */
      return "filename*=" + new_filename ;
    } else
    {
      return "filename=\"" + new_filename +"\"";
    }
  }

三、方法調(diào)用案例

1、方法調(diào)用

public void exportExcelDemo(HttpServletRequest request, HttpServletResponse response) {

  //一系列查詢處理
    List<ExcelDemoModel> demoList=new ArrayList<>();
    
    excelService.exportExcel(request,response,"人員信息demo",demoList,ExcelDemoModel.class);

  }

2、導(dǎo)出效果

到此這篇關(guān)于SpringBoot整合POI導(dǎo)出通用Excel的方法示例的文章就介紹到這了,更多相關(guān)SpringBoot整合POI導(dǎo)出Excel內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java中的Semaphore信號量詳解

    Java中的Semaphore信號量詳解

    這篇文章主要介紹了Java中的Semaphore信號量詳解,Semaphore(信號量)是用來控制同時訪問特定資源的線程數(shù)量,通過協(xié)調(diào)各個線程以保證合理地使用公共資源,需要的朋友可以參考下
    2023-12-12
  • 如何通過ServletInputStream讀取http請求傳入的數(shù)據(jù)

    如何通過ServletInputStream讀取http請求傳入的數(shù)據(jù)

    這篇文章主要介紹了如何通過ServletInputStream讀取http請求傳入的數(shù)據(jù),具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-10-10
  • Java算法實(shí)戰(zhàn)之排一億個隨機(jī)數(shù)

    Java算法實(shí)戰(zhàn)之排一億個隨機(jī)數(shù)

    我們在生活中經(jīng)常遇見一些這樣的需求,隨機(jī)點(diǎn)名、公司年會抽獎、微信拼手氣紅包等,還有一些游戲比如打地鼠小游戲、俄羅斯方塊等,這些場景中都會用到一種算法:隨機(jī),這篇文章主要給大家介紹了關(guān)于Java算法實(shí)戰(zhàn)之排一億個隨機(jī)數(shù)的相關(guān)資料,需要的朋友可以參考下
    2021-11-11
  • XML操作類庫XStream使用詳解

    XML操作類庫XStream使用詳解

    這篇文章主要給大家介紹了關(guān)于XML操作類庫XStream使用的相關(guān)資料,需要的朋友可以參考下
    2023-11-11
  • Java中十六進(jìn)制和十進(jìn)制之間互相轉(zhuǎn)換代碼示例

    Java中十六進(jìn)制和十進(jìn)制之間互相轉(zhuǎn)換代碼示例

    這篇文章主要給大家介紹了關(guān)于Java中十六進(jìn)制和十進(jìn)制之間互相轉(zhuǎn)換的相關(guān)資料,我們項(xiàng)目過程中總是要用到十進(jìn)制與十六進(jìn)制相互轉(zhuǎn)換的方法,需要的朋友可以參考下
    2023-07-07
  • Java編寫實(shí)現(xiàn)窗體程序顯示日歷

    Java編寫實(shí)現(xiàn)窗體程序顯示日歷

    這篇文章主要為大家詳細(xì)介紹了Java編寫實(shí)現(xiàn)窗體程序顯示日歷,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-06-06
  • 關(guān)于@Data和@Builder注解解析

    關(guān)于@Data和@Builder注解解析

    在使用Lombok庫時,@Data和@Builder注解混用可能會導(dǎo)致編譯失敗,解決方法包括添加@NoArgsConstructor和@AllArgsConstructor注解,或者重寫無參構(gòu)造器并注解@Tolerate,這是因?yàn)锧Data自動生成的構(gòu)造器與@Builder的構(gòu)造模式存在沖突
    2024-10-10
  • Spring?Data?JPA命名約定查詢實(shí)現(xiàn)方法

    Spring?Data?JPA命名約定查詢實(shí)現(xiàn)方法

    這篇文章主要為大家介紹了Spring?Data?JPA命名約定查詢實(shí)現(xiàn)方法示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-12-12
  • Java 單例模式線程安全問題

    Java 單例模式線程安全問題

    這篇文章主要介紹了Java 單例模式線程安全問題的相關(guān)資料,希望通過本文大家能了解掌握單例模式中線程安全的使用方法,需要的朋友可以參考下
    2017-09-09
  • springboot整合mqtt客戶端示例分享

    springboot整合mqtt客戶端示例分享

    這篇文章主要介紹了springboot整合mqtt客戶端示例分享的相關(guān)資料,需要的朋友可以參考下
    2023-07-07

最新評論

郴州市| 长兴县| 金沙县| 乐亭县| 巢湖市| 莱西市| 明星| 司法| 潞城市| 高邮市| 涟水县| 象山县| 九台市| 敖汉旗| 湾仔区| 溧水县| 吴忠市| 清新县| 周至县| 尉犁县| 麻江县| 尉氏县| 阳春市| 沈丘县| 自贡市| 铁岭市| 黑水县| 兴和县| 攀枝花市| 新乡市| 禹城市| 光泽县| 武定县| 邳州市| 绥阳县| 镇江市| 梁平县| 本溪市| 广宁县| 肥东县| 昭平县|