<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          優(yōu)雅的實現(xiàn) Excel 導入導出

          共 17098字,需瀏覽 35分鐘

           ·

          2021-08-18 20:55

          日常在做后臺系統(tǒng)的時候會很頻繁的遇到Excel導入導出的問題,正好這次在做一個后臺系統(tǒng),就想著寫一個公用工具來進行Excel的導入導出。

          一般我們在導出的時候都是導出的前端表格,而前端表格同時也會對應的在后臺有一個映射類。

          所以在寫這個工具的時候我們先理一下我們需要實現(xiàn)的效果:

          • 導出方法接收一個list集合,和一個Class類型,和HttpServletResponse 對象

          • 導出是可能會有下拉列表,所以需要一個map存儲下拉列表數(shù)據(jù)源,傳入?yún)?shù)后只需一行代碼即可導出

          • 導入方法需要傳入file文件,以及一個Class類型,導入之后將會返回一個list集合,里面的對象就是傳入類型的對象,傳入?yún)?shù)后只需一行代碼即可導入

          實現(xiàn)過程:

          首先需要創(chuàng)建三個注解

          一個是EnableExport ,必須有這個注解才能導出

          /**
           * 設置允許導出
           */

          @Target(ElementType.TYPE)
          @Retention(RetentionPolicy.RUNTIME)
          public @interface EnableExport {
               String fileName();

          }

          然后就是EnableExportField,有這個注解的字段才會導出到Excel里面,并且可以設置列寬

          /**
           * 設置該字段允許導出
           * 并且可以設置寬度
           */

          @Target(ElementType.FIELD)
          @Retention(RetentionPolicy.RUNTIME)
          public @interface EnableExportField {
               int colWidth() default  100;
               String colName();
          }

          再就是ImportIndex,導入的時候設置Excel中的列對應的序號

          /**
           * 導入時索引
           */

          @Target(ElementType.FIELD)
          @Retention(RetentionPolicy.RUNTIME)
          public @interface ImportIndex {
               int index() ;

          }

          注解使用示例

          三個注解創(chuàng)建好之后就需要開始操作Excel了

          首先,導入方法。在后臺接收到前端上傳的Excel文件之后,使用poi來讀取Excel文件

          我們根據(jù)傳入的類型上面的字段注解的順序來分別為不同的字段賦值,然后存入集合中,再返回

          代碼如下:


          /**
           * 將Excel轉換為對象集合
           * @param excel Excel 文件
           * @param clazz pojo類型
           * @return
           */

          public static List<Object> parseExcelToList(File excel,Class clazz){
              List<Object> res = new ArrayList<>();
              // 創(chuàng)建輸入流,讀取Excel
              InputStream is = null;
              Sheet sheet = null;
              try {
                  is = new FileInputStream(excel.getAbsolutePath());
                  if (is != null) {
                      Workbook workbook = WorkbookFactory.create(is);
                      //默認只獲取第一個工作表
                      sheet = workbook.getSheetAt(0);
                      if (sheet != null) {
                       //前兩行是標題
                          int i = 2;
                          String values[] ;
                          Row row = sheet.getRow(i);
                          while (row != null) {
                              //獲取單元格數(shù)目
                              int cellNum = row.getPhysicalNumberOfCells();
                              values = new String[cellNum];
                              for (int j = 0; j <= cellNum; j++) {
                                  Cell cell =   row.getCell(j);
                                  if (cell != null) {
                                      //設置單元格內容類型
                                      cell.setCellType(Cell.CELL_TYPE_STRING );
                                      //獲取單元格值
                                      String value = cell.getStringCellValue() == null ? null : cell.getStringCellValue();
                                      values[j]=value;
                                  }
                              }
                              Field[] fields = clazz.getDeclaredFields();
                              Object obj = clazz.newInstance();
                              for(Field f : fields){
                                  if(f.isAnnotationPresent(ImportIndex.class)){
                                      ImportIndex annotation = f.getDeclaredAnnotation(ImportIndex.class);
                                      int index = annotation.index();
                                      f.setAccessible(true);
                                      //此處使用了阿里巴巴的fastjson包里面的一個類型轉換工具類
                                      Object val =TypeUtils.cast(values[index],f.getType(),null);
                                      f.set(obj,val);
                                  }
                              }
                              res.add(obj);
                              i++;
                              row=sheet.getRow(i);
                          }

                      }
                  }
              } catch (Exception e) {
                  e.printStackTrace();
              }
              return res;
          }

          接下來就是導出方法。

          導出分為幾個步驟:

          1. 建立一個工作簿,也就是類型新建一個Excel文件
          1. 建立一張sheet表
          1. 設置標的行高和列寬
          1. 繪制標題和表頭

          這兩個方法是自定義方法,代碼會貼在后面

          1. 寫入數(shù)據(jù)到Excel
          1. 創(chuàng)建下拉列表
          1. 寫入文件到response

          到這里導出工作就完成了

          下面是一些自定義方法的代碼

          /**
           * 獲取一個基本的帶邊框的單元格
           * @param workbook
           * @return
           */

          private static HSSFCellStyle getBasicCellStyle(HSSFWorkbook workbook){
              HSSFCellStyle hssfcellstyle = workbook.createCellStyle();
              hssfcellstyle.setBorderLeft(HSSFCellStyle.BORDER_THIN);
              hssfcellstyle.setBorderBottom(HSSFCellStyle.BORDER_THIN);
              hssfcellstyle.setBorderRight(HSSFCellStyle.BORDER_THIN);
              hssfcellstyle.setBorderTop(HSSFCellStyle.BORDER_THIN);
              hssfcellstyle.setAlignment(HSSFCellStyle.ALIGN_CENTER);
              hssfcellstyle.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);
              hssfcellstyle.setWrapText(true);
              return hssfcellstyle;
          }

          /**
           * 獲取帶有背景色的標題單元格
           * @param workbook
           * @return
           */

          private static HSSFCellStyle getTitleCellStyle(HSSFWorkbook workbook){
              HSSFCellStyle hssfcellstyle =  getBasicCellStyle(workbook);
              hssfcellstyle.setFillForegroundColor((short) HSSFColor.CORNFLOWER_BLUE.index); // 設置背景色
              hssfcellstyle.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);
              return hssfcellstyle;
          }

          /**
           * 創(chuàng)建一個跨列的標題行
           * @param workbook
           * @param hssfRow
           * @param hssfcell
           * @param hssfsheet
           * @param allColNum
           * @param title
           */

          private static void createTitle(HSSFWorkbook workbook, HSSFRow hssfRow , HSSFCell hssfcell, HSSFSheet hssfsheet,int allColNum,String title){
              //在sheet里增加合并單元格
              CellRangeAddress cra = new CellRangeAddress(000, allColNum);
              hssfsheet.addMergedRegion(cra);
              // 使用RegionUtil類為合并后的單元格添加邊框
              RegionUtil.setBorderBottom(1, cra, hssfsheet, workbook); // 下邊框
              RegionUtil.setBorderLeft(1, cra, hssfsheet, workbook); // 左邊框
              RegionUtil.setBorderRight(1, cra, hssfsheet, workbook); // 有邊框
              RegionUtil.setBorderTop(1, cra, hssfsheet, workbook); // 上邊框

              //設置表頭
              hssfRow = hssfsheet.getRow(0);
              hssfcell = hssfRow.getCell(0);
              hssfcell.setCellStyle( getTitleCellStyle(workbook));
              hssfcell.setCellType(HSSFCell.CELL_TYPE_STRING);
              hssfcell.setCellValue(title);
          }

          /**
           * 設置表頭標題欄以及表格高度
           * @param workbook
           * @param hssfRow
           * @param hssfcell
           * @param hssfsheet
           * @param colNames
           */

          private static void createHeadRow(HSSFWorkbook workbook,HSSFRow hssfRow , HSSFCell hssfcell,HSSFSheet hssfsheet,List<String> colNames){
              //插入標題行
              hssfRow = hssfsheet.createRow(1);
              for (int i = 0; i < colNames.size(); i++) {
                  hssfcell = hssfRow.createCell(i);
                  hssfcell.setCellStyle(getTitleCellStyle(workbook));
                  hssfcell.setCellType(HSSFCell.CELL_TYPE_STRING);
                  hssfcell.setCellValue(colNames.get(i));
              }
          }
          /**
           * excel添加下拉數(shù)據(jù)校驗
           * @param sheet 哪個 sheet 頁添加校驗
           * @return
           */

          public static void createDataValidation(Sheet sheet,Map<Integer,String[]> selectListMap) {
              if(selectListMap!=null) {
                  selectListMap.forEach(
                          // 第幾列校驗(0開始)key 數(shù)據(jù)源數(shù)組value
                          (key, value) -> {
                              if(value.length>0) {
                                  CellRangeAddressList cellRangeAddressList = new CellRangeAddressList(265535, key, key);
                                  DataValidationHelper helper = sheet.getDataValidationHelper();
                                  DataValidationConstraint constraint = helper.createExplicitListConstraint(value);
                                  DataValidation dataValidation = helper.createValidation(constraint, cellRangeAddressList);
                                  //處理Excel兼容性問題
                                  if (dataValidation instanceof XSSFDataValidation) {
                                      dataValidation.setSuppressDropDownArrow(true);
                                      dataValidation.setShowErrorBox(true);
                                  } else {
                                      dataValidation.setSuppressDropDownArrow(false);
                                  }
                                  dataValidation.setEmptyCellAllowed(true);
                                  dataValidation.setShowPromptBox(true);
                                  dataValidation.createPromptBox("提示""只能選擇下拉框里面的數(shù)據(jù)");
                                  sheet.addValidationData(dataValidation);
                              }
                          }
                  );
              }
          }

          使用實例

          導出數(shù)據(jù)

          導入數(shù)據(jù)(返回對象List)

          源碼地址:

          https://github.com/xyz0101/excelutils
          來源:blog.csdn.net/youzi1394046585/article/details/86670203

          推薦閱讀:

          世界的真實格局分析,地球人類社會底層運行原理

          不是你需要中臺,而是一名合格的架構師(附各大廠中臺建設PPT)

          企業(yè)IT技術架構規(guī)劃方案

          論數(shù)字化轉型——轉什么,如何轉?

          華為干部與人才發(fā)展手冊(附PPT)

          企業(yè)10大管理流程圖,數(shù)字化轉型從業(yè)者必備!

          【中臺實踐】華為大數(shù)據(jù)中臺架構分享.pdf

          華為的數(shù)字化轉型方法論

          華為如何實施數(shù)字化轉型(附PPT)

          超詳細280頁Docker實戰(zhàn)文檔!開放下載

          華為大數(shù)據(jù)解決方案(PPT)


          瀏覽 25
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  超碰在线偷 | 一个色导航五月天伊人网站 | 蜜桃四季春秘 一区二区三区 | 精品国产伦子伦免费看 | 日韩v欧美v日本v亚洲v国产v |