EasyExcel的基本使用


  • 官方網址:https://www.yuque.com/easyexcel/doc/easyexcel
  • 應用場景
    • 數據導入:減少錄入工作量
    • 數據導出:統計信息歸檔
    • 數據傳輸:異構系統之間數據傳輸
  • EasyExcel特點
    • 它是阿里巴巴開源的一個excel處理框架,以使用簡單、節省內存著稱。EasyExcel能大量減少占用內存的主要原因是在解析Excel時沒有將文件數據一次性全部加載到內存中,而是從磁盤中一行行讀取數據,逐個解析。
    • EasyExcel采用一行一行的解析模式,並將一行的解析結果以觀察者的模式通知處理(AnalysisEventListener)
  • EasyExcel寫操作
    • 導入依賴的版本對應關系(版本慎重選擇,否則發生沖突)
      <dependency>
          <groupId>com.alibaba</groupId>
          <artifactId>easyexcel</artifactId>
          <version>2.1.1</version>
      </dependency>
      
      <!--xls-->
      <dependency>
          <groupId>org.apache.poi</groupId>
          <artifactId>poi</artifactId>
          <version>3.17</version>
      </dependency>
      <!--xlsx-->
      <dependency>
          <groupId>org.apache.poi</groupId>
          <artifactId>poi-ooxml</artifactId>
          <version>3.17</version>
      </dependency>
      
    • 創建一個與excel表格字段相對應的實體類(字段==屬性)
      package com.xsha.demo.excel;
      
      import com.alibaba.excel.annotation.ExcelProperty;
      import lombok.Data;
      
      @Data
      public class MyData {
          // 設置excel表表頭
          @ExcelProperty(value = "學生編號")
          private String sno;
      
          @ExcelProperty(value = "學生姓名")
          private String sname;
      }
      
    • 代碼測試
        // 實現EasyExcel寫操作
        @Test
        public void writeExcel() {
            // 1.設置寫入文件夾地址和excel文件名稱
            String filename = "存放文件的絕對路徑\\write.xlsx";
            // 2.准備數據集
            List<MyData> list = new ArrayList<>();
            for (int i = 0; i < 5; i++) {
                MyData data = new MyData();
                data.setSno(i);
                data.setSname("xiansen"+i);
                list.add(data);
            }
            // 3.調用EasyExcel里面的方法實現寫的操作,第一個參數是文件路徑,第二個參數是實體類名稱
            EasyExcel.write(filename, MyData.class).sheet("學生列表").doWrite(list);
        }  
      
  • 示例:文件導出(文件下載)
  • 控制層代碼,其中的response參數可以傳遞給業務層
@RestController
@RequestMapping("/file")
@CrossOrigin
public class LocalFileController {
    @Autowired
    private LocalFileService localFileService;

    /** 文件導出(下載) */
    @GetMapping("/download")
    public Result download(HttpServletResponse response) {
        return Result.bingo(localFileService.download(response));
    }
}
  • 業務層(只顯示實現類),通過給response設置一些參數,提供用戶選擇下載路徑的功能
@Service
public class LocalFileServiceImpl extends ServiceImpl<LocalFileMapper, LocalFile> implements LocalFileService {

    /**
     * 文件導出(下載)
     * @param response 響應
     * @return int
     */
    @Override
    public int download(HttpServletResponse response) {
        response.setContentType("application/vnd.ms-excel");
        response.setCharacterEncoding("utf-8");
        String filename = "dict";
        response.setHeader("Content-disposition", "attachment:filename="+filename+".xlsx");
        // 查詢數據庫
        List<LocalFile> fileList = baseMapper.selectList(null);
        List<LocalFileEeVo> list = BeanUtil.copyToList(fileList, LocalFileEeVo.class);
        try {
            EasyExcel.write(response.getOutputStream(), LocalFileEeVo.class).sheet("dict").doWrite(list);
            return 1;
        } catch (Exception e) {
            throw new MyException("文件讀取失敗!");
        }
    }
}
  • 提供的LocalFileEeVo類,供導出Excel表的格式數據
@Data
public class LocalFileEeVo {

    @ExcelProperty(value = "id", index = 0)
    private Long id;

    @ExcelProperty(value = "名稱", index = 1)
    private String name;

    @ExcelProperty(value = "年齡", index = 2)
    private Integer age;

    @ExcelProperty(value = "性別", index = 3)
    private String gender;

    @ExcelProperty(value = "班級", index = 4)
    private Long classId;
}
  • 最后允許詢問即可

  • EasyExcel讀操作

    • 導入的依賴及版本控制是一樣的
    • 創建的實體類也是excel表格字段一致,只不過在注解中增加一個屬性,指定表格的第幾個字段(從0開始)
      package com.xsha.demo.excel;
      
      import com.alibaba.excel.annotation.ExcelProperty;
      import lombok.Data;
      
      @Data
      public class MyData {
      
          // 設置excel表表頭
          @ExcelProperty(value = "學生編號", index = 0)
          private Integer sno;
      
          @ExcelProperty(value = "學生姓名", index = 1)
          private String sname;
      }
      
      
    • 創建一個“監聽器”進行excel表的讀取(結構較為固定,內容根據需求變動)
      package com.xsha.demo.excel;
      
      import com.alibaba.excel.context.AnalysisContext;
      import com.alibaba.excel.event.AnalysisEventListener;
      
      import java.util.Map;
      
      public class ExcelListener extends AnalysisEventListener<MyData> {
          // 逐行讀取excel表格的內容
          @Override
          public void invoke(MyData data, AnalysisContext analysisContext) {
              System.out.println(data.getSno()+"-----"+data.getSname());
          }
          
          // 讀取表頭的內容
          @Override
          public void invokeHeadMap(Map<Integer, String> headMap, AnalysisContext context) {
              System.out.println("表頭:"+headMap);
          }
          
          // 讀取完成之后
          @Override
          public void doAfterAllAnalysed(AnalysisContext analysisContext) {
          
          }
      }  
      
    • 代碼測試
      // 實現EasyExcel讀操作
      @Test
      public void readExcel() {
          // 1.設置讀取文件夾地址和excel文件名稱
          String filename = "D:\\xusha\\SpringProjects\\guli_parent\\service\\service_education\\src\\test\\java\\com\\xsha\\demo\\excel\\files\\write.xlsx";
          // 3.調用EasyExcel里面的方法實現讀的操作,第一個參數是文件路徑,第二個參數是實體類名稱,第三個參數是監聽器
          EasyExcel.read(filename, MyData.class, new ExcelListener()).sheet("學生列表").doRead();
      }
      
  • 示例:文件導入(文件上傳)

  • 控制層代碼,其中的file參數是前端上傳的文件(可理解為模板)

@RestController
@RequestMapping("/file")
@CrossOrigin
public class LocalFileController {
    @Autowired
    private LocalFileService localFileService;

    /** 文件導入(上傳) */
    @PostMapping("/upload")
    public Result upload(MultipartFile file) {
        return Result.bingo(dictService.upload(file));
    }
}
  • 業務層(只顯示實現類)
@Service
public class LocalFileServiceImpl extends ServiceImpl<LocalFileMapper, LocalFile> implements LocalFileService {

    @Autowired
    private LocalFileMapper localFileMapper;
    /**
     * 文件導入(上傳)
     * @param file 文件
     * @return int
     */
    @Override
    public int importData(MultipartFile file) {
        try {
            EasyExcel.read(file.getInputStream(), LocalFileEeVo.class, new LocalFileListener(LocalFileMapper)).sheet("dict").doRead();
            return 1;
        } catch (IOException e) {
            e.printStackTrace();
            return 0;
        }
    }
}
  • 編寫LocalFileListener類,Excel文件監聽器(作用:逐行讀取)
public class LocalFileListener extends AnalysisEventListener<LocalFileEeVo> {
    private LocalFileMapper localFileMapper;

    public LocalFileListener(LocalFileMapper localFileMapper) {
        this.localFileMapper = localFileMapper;
    }

    @Override
    public void invoke(LocalFileEeVo localFileEeVo, AnalysisContext analysisContext) {
        LocalFile localFile = new LocalFile();
        // 逐行讀取
        BeanUtils.copyProperties(localFileEeVo, localFile);
        // 逐行保存(當然這里可以使用批量保存,這里就留給親們優化了)
        dictMapper.insert(dict);
    }

    @Override
    public void doAfterAllAnalysed(AnalysisContext analysisContext) {

    }
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM