欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

教您如何3分鐘快速搞定EasyExcel導(dǎo)入與導(dǎo)出功能

 更新時(shí)間:2024年01月20日 09:55:12   作者:陳序員->陳  
對(duì)于EasyExcel庫,我們可以使用它來實(shí)現(xiàn)數(shù)據(jù)的導(dǎo)入和導(dǎo)出,下面這篇文章主要給大家介紹了關(guān)于如何3分鐘快速搞定EasyExcel導(dǎo)入與導(dǎo)出功能的相關(guān)資料,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下

前言

該文章主要是介紹如何快速實(shí)現(xiàn)導(dǎo)入與導(dǎo)出功能

一、EasyExcel是什么?

引用官方的說明:EasyExcel是一個(gè)基于Java的、快速、簡潔、解決大文件內(nèi)存溢出的Excel處理工具。
他能讓你在不用考慮性能、內(nèi)存的等因素的情況下,快速完成Excel的讀、寫等功能。

二、使用步驟

1.引入庫

pom.xml引入jar依賴包:

<!-- EasyExcel -->
<dependency>
	<groupId>com.alibaba</groupId>
	<artifactId>easyexcel</artifactId>
	<version>2.2.6</version>
</dependency>

2.導(dǎo)入

2.1創(chuàng)建對(duì)應(yīng)excel表格的實(shí)體類

@ExcelProperty該注解的value是對(duì)應(yīng)excle表格的列名稱,index對(duì)應(yīng)的是excel列的下標(biāo)

@Data
public class ImportModel {
    /**
     * 樹根
     */
    @ExcelProperty(value = "名稱", index = 0)
    private String ;
    /**
     * 樹根標(biāo)題
     */
    @ExcelProperty(value = "編碼", index = 1)
    private String code;
}

2.2后端接收請(qǐng)求入口

    /**
     * 導(dǎo)入
     */
    @ApiOperation("導(dǎo)入")
    @PostMapping("/importTree")
    public R importTree(@RequestParam("file") MultipartFile file) {
/** 根據(jù)自己的業(yè)務(wù)自行選擇在哪處理 */
/** 直接在controllerr處理 */
//        EasyExcel.read(file.getInputStream(), BigTreeImportCommand.class, new ExcelListener(urbanFacilityManageService)).sheet().doRead();
/** 在service實(shí)現(xiàn)類處理 */
        Boolean flag = treeService.importTree(file, tenantId);
        return R.ok("導(dǎo)入成功");
    }

2.3業(yè)務(wù)處理

    @Override
    public Boolean importTree(MultipartFile file) {

        try {
            /** 處理數(shù)據(jù)的監(jiān)聽器,有參構(gòu)造,根據(jù)自己的業(yè)務(wù)決定 */
            TreeExcelListener excelListener = new TreeExcelListener(importService,tenantId);

            // 這里 需要指定讀用哪個(gè)class去讀,然后讀取第一個(gè)sheet 文件流會(huì)自動(dòng)關(guān)閉
            //EasyExcel.read(文件流,對(duì)應(yīng)的Model實(shí)體類,監(jiān)聽器).sheet(那張sheet表,可以使用下標(biāo)或者使用sheet名字).head(表頭對(duì)應(yīng)的實(shí)體類).headRowNumber(表頭占幾行).registerReadListener(處理數(shù)據(jù)的監(jiān)聽器類).doRead()
            EasyExcel.read(file.getInputStream(), ImportModel.class, excelListener).sheet(0).head(ImportModel.class).headRowNumber(1).doRead();
            return true;
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

2.4監(jiān)聽器處理數(shù)據(jù)

import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.ieds.back.interfaces.sys.web.command.BigTreeImportModel;

/**
 * @Author: ChenFB
 * @CreateTime: 2023-04-23 17:18
 * @Description: 導(dǎo)入監(jiān)聽器
 */
public class ImportListener extends AnalysisEventListener<BigTreeImportModel> {


    private ImportService importService;

    private String tenantId;

    /** 有參構(gòu)造,建議將serverjie接口以參數(shù)的方式參進(jìn)來,方便數(shù)據(jù)入庫處理,這個(gè)參數(shù)自行界定 */
    public ImportListener(ImportService importService, String tenantId) {
        this.importService = importService;
        this.tenantId = tenantId;
    }

    /** 讀取每一行數(shù)據(jù)都會(huì)進(jìn)入該方法,數(shù)據(jù)處理與校驗(yàn)可以在該方法進(jìn)行處理 */
    @Override
    public void invoke(BigTreeImportModel data, AnalysisContext context) {

    }

    /** 所有數(shù)據(jù)讀取完畢后,最終會(huì)執(zhí)行這個(gè)方法,所以建議數(shù)據(jù)處理完后,批量在該方法進(jìn)行入庫處理 */
    @Override
    public void doAfterAllAnalysed(AnalysisContext context) {

    }
}

3.導(dǎo)出

3.1創(chuàng)建導(dǎo)出格式生成對(duì)應(yīng)的excel表格的實(shí)體類,這個(gè)可以看2.1

3.2后端接收請(qǐng)求入口

    /**
     * 導(dǎo)出
     */
    @ApiOperation("導(dǎo)出")
    @GetMapping("/exportTree")
    public void exportTree(HttpServletResponse response, @RequestParam("tenantId") String tenantId) {
        treeService.exportTree(response,tenantId);
    }

3.3業(yè)務(wù)處理

@Override
    public void exportTree(HttpServletResponse response, String tenantId) {
        ExcelWriter writer = null;
        try {
            response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"); //設(shè)置響應(yīng)內(nèi)容類型
            response.setCharacterEncoding("utf-8");//編碼
            // 設(shè)置文件名, ps:把字符串中所有的'+'替換成'%20',在URL中%20代表空格
            String fileName = URLEncoder.encode("文件名,根據(jù)業(yè)務(wù)決定", "UTF-8").replaceAll("\\+", "%20");
            response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");//設(shè)置響應(yīng)頭
            response.setHeader("fileName", fileName + ".xlsx");//設(shè)置響應(yīng)頭
            /** 導(dǎo)出的數(shù)據(jù)集合 */
            List<ExportModel> modelList = new ArrayList<>();
            /** registerWriteHandler(合并行數(shù),那些列需要合并) */
            writer = EasyExcel.write(response.getOutputStream(), BigTreeImportModel.class).registerWriteHandler(new MergeStrategy(modelList.size(), 0, 1, 2, 7, 8, 10, 11)).build();//獲取寫出流
            WriteSheet sheet = EasyExcel.writerSheet("sheet名稱,自行決定").build();//創(chuàng)建表格,設(shè)置表格頁名稱
            writer.write(modelList, sheet);//讀出

        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            if (null != writer) {
                writer.finish();//關(guān)閉流
            }
        }
    }

4.合并工具類

import com.alibaba.excel.metadata.Head;
import com.alibaba.excel.write.merge.AbstractMergeStrategy;
import org.apache.commons.collections.map.HashedMap;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.util.CellRangeAddress;

import java.util.*;

/**
 * @Author: ChenFB
 * @CreateTime: 2023-04-20 10:56
 * @Description: Excel單元格合并工具類
 */
public class MergeStrategy extends AbstractMergeStrategy {

    // 合并的列編號(hào),從0開始,指定的index或自己按字段順序數(shù)
    private Set<Integer> mergeCellIndex = new HashSet<>();

    // 數(shù)據(jù)集大小,用于區(qū)別結(jié)束行位置
    private Integer maxRow = 0;

    // 禁止無參聲明
    private MergeStrategy() {
    }

    public MergeStrategy(Integer maxRow, int... mergeCellIndex) {
        Arrays.stream(mergeCellIndex).forEach(item -> {
            this.mergeCellIndex.add(item);
        });
        this.maxRow = maxRow;
    }

    // 記錄上一次合并的信息
    private Map<Integer, MergeRange> lastRow = new HashedMap();

    // 每行每列都會(huì)進(jìn)入,絕對(duì)不要在這寫循環(huán)
    @Override
    protected void merge(Sheet sheet, Cell cell, Head head, Integer relativeRowIndex) {
        int currentCellIndex = cell.getColumnIndex();
        // 判斷該行是否需要合并
        if (mergeCellIndex.contains(currentCellIndex)) {
            String currentCellValue = cell.getStringCellValue();
            int currentRowIndex = cell.getRowIndex();
            if (!lastRow.containsKey(currentCellIndex)) {
                // 記錄首行起始位置
                lastRow.put(currentCellIndex, new MergeRange(currentCellValue, currentRowIndex, currentRowIndex, currentCellIndex, currentCellIndex));
                return;
            }
            //有上行這列的值了,拿來對(duì)比.
            MergeRange mergeRange = lastRow.get(currentCellIndex);
            if (!(mergeRange.lastValue != null && mergeRange.lastValue.equals(currentCellValue))) {
                // 結(jié)束的位置觸發(fā)下合并.
                // 同行同列不能合并,會(huì)拋異常
                if (mergeRange.startRow != mergeRange.endRow || mergeRange.startCell != mergeRange.endCell) {
                    sheet.addMergedRegionUnsafe(new CellRangeAddress(mergeRange.startRow, mergeRange.endRow, mergeRange.startCell, mergeRange.endCell));
                }
                // 更新當(dāng)前列起始位置
                lastRow.put(currentCellIndex, new MergeRange(currentCellValue, currentRowIndex, currentRowIndex, currentCellIndex, currentCellIndex));
            }
            // 合并行 + 1
            mergeRange.endRow += 1;
            // 結(jié)束的位置觸發(fā)下最后一次沒完成的合并
            if (relativeRowIndex.equals(maxRow - 1)) {
                MergeRange lastMergeRange = lastRow.get(currentCellIndex);
                // 同行同列不能合并,會(huì)拋異常
                if (lastMergeRange.startRow != lastMergeRange.endRow || lastMergeRange.startCell != lastMergeRange.endCell) {
                    sheet.addMergedRegionUnsafe(new CellRangeAddress(lastMergeRange.startRow-1, lastMergeRange.endRow, lastMergeRange.startCell, lastMergeRange.endCell));
                }
            }
        }
    }
}

class MergeRange {
    public int startRow;
    public int endRow;
    public int startCell;
    public int endCell;
    public String lastValue;

    public MergeRange(String lastValue, int startRow, int endRow, int startCell, int endCell) {
        this.startRow = startRow;
        this.endRow = endRow;
        this.startCell = startCell;
        this.endCell = endCell;
        this.lastValue = lastValue;
    }
}

附:EasyExcel結(jié)合Mybatis plus的分頁功能進(jìn)行分頁導(dǎo)出

工具類

import cn.hutool.core.collection.CollUtil;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.Builder;
import lombok.Data;
import org.springframework.http.HttpHeaders;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List;
public class EasyExcelUtil {
    @Data
    @Builder
    public static class ExcelParam {
        /**
         * 查詢 Mapper
         */
        private BaseMapper baseMapper;
        /**
         * Lambda查詢方式
         */
        private LambdaQueryWrapper lambdaQueryWrapper;
        /**
         * 頁碼,默認(rèn)從1開始
         */
        private Integer pageNo = 1;
        /**
         * 分頁條數(shù),,默認(rèn)每個(gè)sheet 1000 條數(shù)據(jù)
         */
        private Integer pageSize = 1000;
        /**
         * 用于存放查詢到的結(jié)果,讓Excel生成
         */
        private Class<?> respClazz;
        /**
         * 生成的Excel 名稱,不加后綴
         */
        private String fileName;
        /**
         * Excel sheet名稱
         */
        private String sheetName;
    }
    public static void exportExcel(ExcelParam excelParam, HttpServletResponse response) {
        response.setContentType("application/vnd.ms-excel;charset=utf-8");
        response.setCharacterEncoding("utf-8");
        response.setHeader(HttpHeaders.ACCESS_CONTROL_EXPOSE_HEADERS, HttpHeaders.CONTENT_DISPOSITION);
        response.setHeader(HttpHeaders.CONTENT_DISPOSITION, "attachment;filename=" + excelParam.getFileName() + ".xlsx");
        try (
                ServletOutputStream outputStream = response.getOutputStream();
                ExcelWriter excelWriter = EasyExcel.write(outputStream, excelParam.getRespClazz()).build();
        ) {
            Page page = new Page(excelParam.getPageNo(), excelParam.getPageSize());
            page = (Page) excelParam.getBaseMapper().selectPage(page, excelParam.getLambdaQueryWrapper());
            /** 構(gòu)建 */
            WriteSheet writeSheet1 = EasyExcel.writerSheet(1, excelParam.getSheetName() + "第" + excelParam.getPageNo() + "頁").build();
            /** 獲取總數(shù) */
            Long totalPage = page.getPages();
            List records = page.getRecords();
            /** 寫入內(nèi)容 */
            excelWriter.write(records, writeSheet1);
            writeSheet1 = null; // GC
            // 若為空表
            if (CollUtil.isEmpty(page.getRecords())) {
                /** 生成完畢 */
                excelWriter.finish();
                /** 立即刷回 */
                outputStream.flush();
                return;
            }
            for (int i = excelParam.pageNo + 1, index = 2; i <= totalPage; i++, index++) {
                /** 清空*/
                records.clear();
                WriteSheet writeSheet = EasyExcel.writerSheet(index, excelParam.getSheetName() + "第" + i + "頁").build();
                page.setCurrent(i);
                /** 新的查詢 */
                page = (Page) excelParam.getBaseMapper().selectPage(page, excelParam.getLambdaQueryWrapper());
                records = page.getRecords();
                /** 輸入內(nèi)容內(nèi)容 */
                excelWriter.write(records, writeSheet);
            }
            /** 生成完畢 */
            excelWriter.finish();
            /** 立即刷回 */
            outputStream.flush();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
}

使用

EasyExcelUtil.ExcelParam p = EasyExcelUtil.ExcelParam.builder()
                .baseMapper(workRollPlanService.getBaseMapper())           // 傳Service類的BaseMapper進(jìn)去
                .lambdaQueryWrapper(new LambdaQueryWrapper<WorkRollPlan>() // 構(gòu)建查詢條件
                        .eq(true, WorkRollPlan::getIsDeleted, 0)
                )
                .pageNo(1)                     // 數(shù)據(jù)從第一行開始,如果表頭只有一行就是1,表頭有兩行的話就寫2
                .respClazz(WorkRollPlan.class) // 這里寫實(shí)體類
                .pageSize(1000)                // Excel每頁數(shù)據(jù)大小
                .fileName("test")              // 文件名
                .sheetName("測試sheet")        // 頁名
                .build();

        EasyExcelUtil.exportExcel(p, response);

總結(jié)

到此這篇關(guān)于如何3分鐘快速搞定EasyExcel導(dǎo)入與導(dǎo)出功能的文章就介紹到這了,更多相關(guān)EasyExcel導(dǎo)入與導(dǎo)出內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java日常練習(xí)題,每天進(jìn)步一點(diǎn)點(diǎn)(49)

    Java日常練習(xí)題,每天進(jìn)步一點(diǎn)點(diǎn)(49)

    下面小編就為大家?guī)硪黄狫ava基礎(chǔ)的幾道練習(xí)題(分享)。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧,希望可以幫到你
    2021-08-08
  • Hadoop源碼分析一架構(gòu)關(guān)系簡介

    Hadoop源碼分析一架構(gòu)關(guān)系簡介

    本篇是Hadoop源碼分析系列文章第一篇,主要介紹一下Hadoop的基礎(chǔ)簡介以及框架關(guān)系,后續(xù)本系列文章會(huì)持續(xù)更新,有需要的朋友可以借鑒參考下
    2021-09-09
  • 解決2022.3.1版本中?IDEA中?XML文件提示屎黃色背景的方法

    解決2022.3.1版本中?IDEA中?XML文件提示屎黃色背景的方法

    這篇文章主要介紹了解決2022.3.1版本中?IDEA中?XML文件屎黃色背景?的方法,本文通過圖文并茂的形式給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-01-01
  • springboot自帶線程池ThreadPoolTaskExecutor使用

    springboot自帶線程池ThreadPoolTaskExecutor使用

    本文主要介紹了springboot自帶線程池ThreadPoolTaskExecutor使用,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-04-04
  • Java繼承與多態(tài)的正確打開方式

    Java繼承與多態(tài)的正確打開方式

    這篇文章主要為大家介紹了Java的繼承與多態(tài),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2022-01-01
  • Java整合Jackson實(shí)現(xiàn)反序列化器流程

    Java整合Jackson實(shí)現(xiàn)反序列化器流程

    Jackson是一個(gè)開源的Java序列化和反序列化工具,可以將Java對(duì)象序列化為XML或JSON格式的字符串,以及將XML或JSON格式的字符串反序列化為Java對(duì)象。由于其使用簡單,速度較快,且不依靠除JDK外的其他庫,被眾多用戶所使用
    2023-01-01
  • 通過Java實(shí)現(xiàn)帶干擾線的驗(yàn)證碼

    通過Java實(shí)現(xiàn)帶干擾線的驗(yàn)證碼

    帶干擾線的驗(yàn)證碼是一種常見的安全驗(yàn)證方式,目的是通過圖像中的干擾線增加機(jī)器識(shí)別的難度,確保只有人類用戶能夠順利識(shí)別并輸入驗(yàn)證碼,本項(xiàng)目的目的是通過Java實(shí)現(xiàn)一個(gè)帶有干擾線的驗(yàn)證碼生成器,需要的朋友可以參考下
    2025-02-02
  • Spring?Boot?如何通過ServletRequestHandledEvent事件實(shí)現(xiàn)接口請(qǐng)求的性能監(jiān)控

    Spring?Boot?如何通過ServletRequestHandledEvent事件實(shí)現(xiàn)接口請(qǐng)求的性能監(jiān)控

    在Spring框架中,監(jiān)控接口請(qǐng)求的性能可以通過ServletRequestHandledEvent事件實(shí)現(xiàn),這篇文章給大家介紹Spring?Boot?如何通過ServletRequestHandledEvent事件實(shí)現(xiàn)接口請(qǐng)求的性能監(jiān)控,感興趣的朋友跟隨小編一起看看吧
    2024-08-08
  • SpringBoot整合高德地圖天氣查詢的全過程

    SpringBoot整合高德地圖天氣查詢的全過程

    這篇文章主要給大家介紹了關(guān)于SpringBoot整合高德地圖天氣查詢的相關(guān)資料,文中通過圖文介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用springboot具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2021-12-12
  • springBoot使用openfeign來遠(yuǎn)程調(diào)用的實(shí)現(xiàn)

    springBoot使用openfeign來遠(yuǎn)程調(diào)用的實(shí)現(xiàn)

    這篇文章主要介紹了springBoot使用openfeign來遠(yuǎn)程調(diào)用的實(shí)現(xiàn)方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-03-03

最新評(píng)論