天天看點

excel開發

easyexcel
https://www.jianshu.com/p/78cc1729fbd1      
https://blog.csdn.net/daisy_apk/article/details/84635620
invoke方法每解析一行執行一次,analysisEventListener 還有一個doAfterAllAnalysed()方法這個方法會在整個excel解析結束後執行。      

Excel解析工具easyexcel全面探索

1.2. Excel讀

1.2.1. 例子

/**
     * 最簡單的讀
     * <p>1. 建立excel對應的實體對象 參照{@link DemoData}
     * <p>2. 由于預設異步讀取excel,是以需要建立excel一行一行的回調監聽器,參照{@link DemoDataListener}
     * <p>3. 直接讀即可
     */
    @Test
    public void simpleRead() {
        String fileName = TestFileUtil.getPath() + "demo" + File.separator + "demo.xlsx";
        // 這裡 需要指定讀用哪個class去讀,然後讀取第一個sheet 檔案流會自動關閉
        EasyExcel.read(fileName, DemoData.class, new DemoDataListener()).sheet().doRead();
    }      

對應我們使用者需要手寫的代碼,我們的監聽器

DemoDataListener

中有兩個實作方法如下,

invoke

就對應了上述代碼中的

parseXmlSource

doAfterAllAnalysed

對應了上述方法中的

notifyAfterAllAnalysed

,分别表示了先解析每一條資料和當最後一頁讀取完畢通知所有監聽器

@Override
    public void invoke(DemoData data, AnalysisContext context) {
        LOGGER.info("解析到一條資料:{}", JSON.toJSONString(data));
        list.add(data);
        if (list.size() >= BATCH_COUNT) {
            saveData();
            list.clear();
        }
    }

    @Override
    public void doAfterAllAnalysed(AnalysisContext context) {
        saveData();
        LOGGER.info("所有資料解析完成!");
    }      

 Excel寫

/**
     * 最簡單的寫
     * <p>1. 建立excel對應的實體對象 參照{@link com.alibaba.easyexcel.test.demo.write.DemoData}
     * <p>2. 直接寫即可
     */
    @Test
    public void simpleWrite() {
        String fileName = TestFileUtil.getPath() + "write" + System.currentTimeMillis() + ".xlsx";
        // 這裡 需要指定寫用哪個class去讀,然後寫到第一個sheet,名字為模闆 然後檔案流會自動關閉
        // 如果這裡想使用03 則 傳入excelType參數即可
        EasyExcel.write(fileName, DemoData.class).sheet("模闆").doWrite(data());
    }
    
    private List<DemoData> data() {
        List<DemoData> list = new ArrayList<DemoData>();
        for (int i = 0; i < 10; i++) {
            DemoData data = new DemoData();
            data.setString("字元串" + i);
            data.setDate(new Date());
            data.setDoubleData(0.56);
            list.add(data);
        }
        return list;
    }      

檔案上傳

/**
     * 檔案上傳
     * <p>
     * 1. 建立excel對應的實體對象 參照{@link UploadData}
     * <p>
     * 2. 由于預設異步讀取excel,是以需要建立excel一行一行的回調監聽器,參照{@link UploadDataListener}
     * <p>
     * 3. 直接讀即可
     */
    @PostMapping("upload")
    @ResponseBody
    public String upload(MultipartFile file) throws IOException {
        EasyExcel.read(file.getInputStream(), UploadData.class, new UploadDataListener()).sheet().doRead();
        return "success";
    }      

檔案下載下傳

/**
     * 檔案下載下傳
     * <p>
     * 1. 建立excel對應的實體對象 參照{@link DownloadData}
     * <p>
     * 2. 設定傳回的 參數
     * <p>
     * 3. 直接寫,這裡注意,finish的時候會自動關閉OutputStream,當然你外面再關閉流問題不大
     */
    @GetMapping("download")
    public void download(HttpServletResponse response) throws IOException {
        // 這裡注意 有同學反應使用swagger 會導緻各種問題,請直接用浏覽器或者用postman
        response.setContentType("application/vnd.ms-excel");
        response.setCharacterEncoding("utf-8");
        // 這裡URLEncoder.encode可以防止中文亂碼 當然和easyexcel沒有關系
        String fileName = URLEncoder.encode("測試", "UTF-8");
        response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx");
        EasyExcel.write(response.getOutputStream(), DownloadData.class).sheet("模闆").doWrite(data());
    }      

Excel讀取多頁

/**
     * 讀多個或者全部sheet,這裡注意一個sheet不能讀取多次,多次讀取需要重新讀取檔案
     * <p>
     * 1. 建立excel對應的實體對象 參照{@link DemoData}
     * <p>
     * 2. 由于預設異步讀取excel,是以需要建立excel一行一行的回調監聽器,參照{@link DemoDataListener}
     * <p>
     * 3. 直接讀即可
     */
    @Test
    public void repeatedRead() {
        String fileName = TestFileUtil.getPath() + "demo" + File.separator + "demo.xlsx";
        // 讀取全部sheet
        // 這裡需要注意 DemoDataListener的doAfterAllAnalysed 會在每個sheet讀取完畢後調用一次。然後所有sheet都會往同一個DemoDataListener裡面寫
        EasyExcel.read(fileName, DemoData.class, new DemoDataListener()).doReadAll();

        // 讀取部分sheet
        fileName = TestFileUtil.getPath() + "demo" + File.separator + "demo.xlsx";
        ExcelReader excelReader = EasyExcel.read(fileName).build();
        // 這裡為了簡單 是以注冊了 同樣的head 和Listener 自己使用功能必須不同的Listener
        ReadSheet readSheet1 =
            EasyExcel.readSheet(0).head(DemoData.class).registerReadListener(new DemoDataListener()).build();
        ReadSheet readSheet2 =
            EasyExcel.readSheet(1).head(DemoData.class).registerReadListener(new DemoDataListener()).build();
        // 這裡注意 一定要把sheet1 sheet2 一起傳進去,不然有個問題就是03版的excel 會讀取多次,浪費性能
        excelReader.read(readSheet1, readSheet2);
        // 這裡千萬别忘記關閉,讀的時候會建立臨時檔案,到時磁盤會崩的
        excelReader.finish();
    }      

重複多次寫入

  • 分為三種:1. 重複寫入同一個sheet;2. 同一個對象寫入不同sheet;3. 不同的對象寫入不同的sheet
/**
     * 重複多次寫入
     * <p>
     * 1. 建立excel對應的實體對象 參照{@link ComplexHeadData}
     * <p>
     * 2. 使用{@link ExcelProperty}注解指定複雜的頭
     * <p>
     * 3. 直接調用二次寫入即可
     */
    @Test
    public void repeatedWrite() {
        // 方法1 如果寫到同一個sheet
        String fileName = TestFileUtil.getPath() + "repeatedWrite" + System.currentTimeMillis() + ".xlsx";
        // 這裡 需要指定寫用哪個class去讀
        ExcelWriter excelWriter = EasyExcel.write(fileName, DemoData.class).build();
        // 這裡注意 如果同一個sheet隻要建立一次
        WriteSheet writeSheet = EasyExcel.writerSheet("模闆").build();
        // 去調用寫入,這裡我調用了五次,實際使用時根據資料庫分頁的總的頁數來
        for (int i = 0; i < 5; i++) {
            // 分頁去資料庫查詢資料 這裡可以去資料庫查詢每一頁的資料
            List<DemoData> data = data();
            writeSheet.setSheetName("模闆");
            excelWriter.write(data, writeSheet);
        }
        /// 千萬别忘記finish 會幫忙關閉流
        excelWriter.finish();

        // 方法2 如果寫到不同的sheet 同一個對象
        fileName = TestFileUtil.getPath() + "repeatedWrite" + System.currentTimeMillis() + ".xlsx";
        // 這裡 指定檔案
        excelWriter = EasyExcel.write(fileName, DemoData.class).build();
        // 去調用寫入,這裡我調用了五次,實際使用時根據資料庫分頁的總的頁數來。這裡最終會寫到5個sheet裡面
        for (int i = 0; i < 5; i++) {
            // 每次都要建立writeSheet 這裡注意必須指定sheetNo
            writeSheet = EasyExcel.writerSheet(i, "模闆"+i).build();
            // 分頁去資料庫查詢資料 這裡可以去資料庫查詢每一頁的資料
            List<DemoData> data = data();
            excelWriter.write(data, writeSheet);
        }
        /// 千萬别忘記finish 會幫忙關閉流
        excelWriter.finish();

        // 方法3 如果寫到不同的sheet 不同的對象
        fileName = TestFileUtil.getPath() + "repeatedWrite" + System.currentTimeMillis() + ".xlsx";
        // 這裡 指定檔案
        excelWriter = EasyExcel.write(fileName).build();
        // 去調用寫入,這裡我調用了五次,實際使用時根據資料庫分頁的總的頁數來。這裡最終會寫到5個sheet裡面
        for (int i = 0; i < 5; i++) {
            // 每次都要建立writeSheet 這裡注意必須指定sheetNo。這裡注意DemoData.class 可以每次都變,我這裡為了友善 是以用的同一個class 實際上可以一直變
            writeSheet = EasyExcel.writerSheet(i, "模闆"+i).head(DemoData.class).build();
            // 分頁去資料庫查詢資料 這裡可以去資料庫查詢每一頁的資料
            List<DemoData> data = data();
            excelWriter.write(data, writeSheet);
        }
        /// 千萬别忘記finish 會幫忙關閉流
        excelWriter.finish();
    }      

内容位址:

https://www.jianshu.com/p/996d5fffdb0f