亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

Java?EasyExcel導(dǎo)入帶圖片的完整過(guò)程記錄

 更新時(shí)間:2024年12月07日 10:45:27   作者:王疏蔬  
這篇文章主要介紹了關(guān)于結(jié)合EasyExcel和ApachePOI來(lái)實(shí)現(xiàn)Excel數(shù)據(jù)批量導(dǎo)入并讀取圖片的過(guò)程,文中通過(guò)圖文以及代碼介紹的非常詳細(xì),需要的朋友可以參考下

前言

項(xiàng)目中,要求批量導(dǎo)入 Excel 數(shù)據(jù)并讀取其中圖片,目前 EasyExcel 不支持讀取圖片,因此需要使用 Apache POI 進(jìn)行導(dǎo)入。然而Apache POI 需要開發(fā)者手動(dòng)管理行、列、單元格等對(duì)象,相對(duì)較為底層且繁瑣。

作者隨即想到了一種方法,既能夠使用 EasyExcel 的簡(jiǎn)便導(dǎo)入方式,又能夠識(shí)別圖片并進(jìn)行處理。

相關(guān)依賴

        <!-- Apache POI -->
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi</artifactId>
            <version>5.2.3</version>
        </dependency>
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-ooxml</artifactId>
            <version>5.2.3</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/com.alibaba/easyexcel -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>easyexcel</artifactId>
            <version>3.2.1</version>
        </dependency>

Java 代碼展示

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.IdUtil;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.read.listener.ReadListener;
import com.alibaba.excel.util.ListUtils;
import com.bi.my.vo.ExcelVo;
import lombok.extern.slf4j.Slf4j;
import net.dreamlu.mica.core.result.R;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.xssf.usermodel.*;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
 * 數(shù)據(jù)+圖片導(dǎo)入
 *
 * @author wss
 */
@Slf4j
@RestController
@RequestMapping("/easy")
public class EasyExcelController {

    /**
     * 數(shù)據(jù)導(dǎo)入并識(shí)別圖片
     *
     * @param file file
     * @return R<Object>
     * @author wss
     */
    @PostMapping("/import")
    public R<Object> dataImport(@RequestParam("file") MultipartFile file) {
        List<ExcelVo> excelVos = new ArrayList<>();
        //數(shù)據(jù)處理
        this.dataProcess(file, excelVos);
        //圖像處理
        this.imageProcess(file, excelVos);
        //返回結(jié)果,這里也可以處理excelVos數(shù)據(jù),如往mysql存儲(chǔ)
        return R.success(excelVos);
    }

    /**
     * 圖片處理
     */
    public void imageProcess(MultipartFile file, List<ExcelVo> excelVos) {
        try {
            XSSFWorkbook book = new XSSFWorkbook(file.getInputStream());
            //方式1 獲取sheet數(shù)量,采用下標(biāo)方式遍歷讀取每個(gè)工作表數(shù)據(jù)
            int sheetsNos = book.getNumberOfSheets();
            for (int sheetNo = 0; sheetNo < sheetsNos; sheetNo++) {
                Sheet sheet = book.getSheetAt(sheetNo);
                //...省略,內(nèi)容為方式2
            }
            //方式2 獲取sheet數(shù)量,直接遍歷讀取每個(gè)工作表數(shù)據(jù)
            for (Sheet sheet : book) {
                XSSFSheet xssSheet = (XSSFSheet) sheet;
                //獲取工作表中繪圖包
                XSSFDrawing drawing = xssSheet.getDrawingPatriarch();
                if (drawing == null) {
                    break;
                }
                //獲取所有圖像形狀
                List<XSSFShape> shapes = drawing.getShapes();
                //遍歷所有形狀
                for (XSSFShape shape : shapes) {
                    //獲取形狀在工作表中的頂點(diǎn)位置信息(anchor錨點(diǎn))
                    XSSFClientAnchor anchor = (XSSFClientAnchor) shape.getAnchor();
                    //圖片形狀在工作表中的位置, 所在行列起點(diǎn)和終點(diǎn)位置
                    short c1 = anchor.getCol1();
                    int r1 = anchor.getRow1();
                    String key = r1 + "行," + c1 + "列";
                    if (shape instanceof XSSFPicture) {
                        try {
                            XSSFPicture pic = (XSSFPicture) shape;
                            //形狀獲取對(duì)應(yīng)的圖片數(shù)據(jù)
                            XSSFPictureData picData = pic.getPictureData();
                            //保存圖片到本地
                            byte[] data = picData.getData();
                            //TODO 這里上傳文件至oss并生成鏈接,這里不做過(guò)多描述,有疑問(wèn)請(qǐng)參照oss服務(wù)調(diào)用
                            String fileName = "https://oss.cn/" + DateUtil.today() + "/" + IdUtil.simpleUUID() + "/" + picData.suggestFileExtension();
                            //fileTemplate.putObject(properties.getBucketName(), fileName, new ByteArrayInputStream(data));
                            //TODO 放入excel集合,這里行數(shù)要減去1,獲取圖片是從表頭開始(表頭位置為0),獲取excelVos是從數(shù)據(jù)開始(第一條數(shù)據(jù)位置為0)他們相差一個(gè)表頭,所以要減去1才能對(duì)應(yīng)
                            excelVos.get(r1 - 1).setPicture(fileName);
                        } catch (Exception e) {
                            log.error("asyncImportList XSSFClientAnchor key|{} error|{}", key, e.getMessage());
                        }
                    }
                }
            }
        } catch (Exception e) {
            log.error("asyncImportList XSSFWorkbook error|{}", e.getMessage());
        }
    }

    /**
     * 數(shù)據(jù)處理
     */
    public void dataProcess(MultipartFile file, List<ExcelVo> excelVos) {
        // 這里默認(rèn)讀取第一個(gè)sheet
        try {
            EasyExcel.read(file.getInputStream(), ExcelVo.class, new ReadListener() {
                /**
                 * 單次緩存的數(shù)據(jù)量
                 */
                public static final int BATCH_COUNT = 100;
                /**
                 *臨時(shí)存儲(chǔ)
                 */
                private List<ExcelVo> cachedDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT);

                @Override
                public void invoke(Object object, AnalysisContext context) {
                    ExcelVo data = (ExcelVo) object;
                    cachedDataList.add(data);
                    if (cachedDataList.size() >= BATCH_COUNT) {
                        saveData();
                        // 存儲(chǔ)完成清理 list
                        cachedDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT);
                    }
                }

                @Override
                public void doAfterAllAnalysed(AnalysisContext context) {
                    saveData();
                }

                /**
                 * 加上存儲(chǔ)數(shù)據(jù)庫(kù)
                 */
                private void saveData() {
                    log.info("已獲取數(shù)據(jù)|{}條", cachedDataList.size());
                    excelVos.addAll(cachedDataList);
                }
            }).sheet().doRead();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
import com.alibaba.excel.annotation.ExcelProperty;
import lombok.Data;

/**
 * 導(dǎo)入VO
 *
 * @author wss
 */
@Data
public class ExcelVo {
    @ExcelProperty("序號(hào)")
    private Integer ordinal;
    @ExcelProperty("標(biāo)題")
    private String title;
    @ExcelProperty("圖片")
    private String picture;
}

Excel 表格準(zhǔn)備

excel表頭需和實(shí)體字段相對(duì)應(yīng)

Postman 調(diào)用測(cè)試

打開圖片鏈接發(fā)現(xiàn)與excel中圖片一致,對(duì)應(yīng)數(shù)據(jù)一致,讀取圖片成功!

結(jié)尾

到這里,EasyExcel 導(dǎo)入帶圖片已完成!讀取圖片速度較慢,可以通過(guò)異步或其它方式優(yōu)化處理,根據(jù)自己需求修改即可,這里就不進(jìn)行說(shuō)明了。

補(bǔ)充

項(xiàng)目中本人是通過(guò)@RequestExcel注解直接獲取的excel數(shù)據(jù),file專用于圖片讀取,即方法中不用再進(jìn)行數(shù)據(jù)處理,代碼更加簡(jiǎn)化。

這篇文章主要是用來(lái)處理讀取圖片的,這里就不再詳細(xì)說(shuō)明該注解了,感興趣的小伙伴可以查閱一下相關(guān)資料。

    /**
     * 數(shù)據(jù)導(dǎo)入并識(shí)別圖片
     *
     * @param file file
     * @return R<Object>
     * @author wss
     */
    @PostMapping("/import")
    public R<Object> dataImport(@RequestParam("file") MultipartFile file, @RequestExcel List<ExcelVo> excelVos) {
        //圖像處理
        this.imageProcess(file, excelVos);
        //返回結(jié)果,這里也可以處理excelVos數(shù)據(jù),如往庫(kù)里存儲(chǔ)
        return R.success(excelVos);
    }

到此這篇關(guān)于Java EasyExcel導(dǎo)入帶圖片的文章就介紹到這了,更多相關(guān)Java EasyExcel導(dǎo)入帶圖內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • kotlin和Java的相互調(diào)用示例詳解

    kotlin和Java的相互調(diào)用示例詳解

    Kotlin 的設(shè)計(jì)過(guò)程中就考慮到了與 Java 的互操作性。在 Kotlin 中可以直接調(diào)用既有的 Java 代碼, 反過(guò)來(lái)在 Java 中也可以很流暢地使用 Kotlin 代碼,下面這篇文章主要給大家介紹了關(guān)于kotlin和Java的相互調(diào)用的相關(guān)資料,需要的朋友可以參考下。
    2018-02-02
  • Mybatis-flex整合達(dá)夢(mèng)數(shù)據(jù)庫(kù)的實(shí)現(xiàn)示例

    Mybatis-flex整合達(dá)夢(mèng)數(shù)據(jù)庫(kù)的實(shí)現(xiàn)示例

    本文討論了國(guó)產(chǎn)達(dá)夢(mèng)數(shù)據(jù)庫(kù)與Mybatis-flex框架的整合過(guò)程,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2024-10-10
  • Spring中的Sentinel熔斷降級(jí)原理詳解

    Spring中的Sentinel熔斷降級(jí)原理詳解

    這篇文章主要介紹了Spring中的Sentinel熔斷降級(jí)原理詳解,熔斷是為了起到保護(hù)作用,如果某個(gè)目標(biāo)服務(wù)調(diào)用比較慢或者大量的超時(shí),這個(gè)時(shí)候如果觸發(fā)熔斷機(jī)制,則可以保證后續(xù)的請(qǐng)求不會(huì)繼續(xù)發(fā)送到目標(biāo)服務(wù)上,而是直接返回降級(jí)的邏輯并且快速釋放資源,需要的朋友可以參考下
    2023-09-09
  • 淺析Mybatis 在CS程序中的應(yīng)用

    淺析Mybatis 在CS程序中的應(yīng)用

    如果是自己用的Mybatis,不需要考慮對(duì)配置文件加密,如果不是,那就需要考慮加密,這篇文章主要講如何配置CS的Mybatis
    2013-07-07
  • java遞歸讀取目錄下所有文件的方法

    java遞歸讀取目錄下所有文件的方法

    這篇文章主要為大家詳細(xì)介紹了java遞歸讀取目錄下所有文件的方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-02-02
  • SpringBoot集成WebServlet出現(xiàn)自定義servlet請(qǐng)求失敗的問(wèn)題解決方案

    SpringBoot集成WebServlet出現(xiàn)自定義servlet請(qǐng)求失敗的問(wèn)題解決方案

    SpringBoot中以Bean方式注冊(cè)Servlet時(shí)遇到的問(wèn)題,通過(guò)了解DispatcherServlet的原理,發(fā)現(xiàn)默認(rèn)路徑?jīng)_突是主要原因,本文介紹SpringBoot集成WebServlet出現(xiàn)自定義servlet請(qǐng)求失敗的問(wèn)題解決方案,感興趣的朋友一起看看吧
    2025-03-03
  • 解讀maven配置阿里云鏡像問(wèn)題

    解讀maven配置阿里云鏡像問(wèn)題

    這篇文章主要介紹了解讀maven配置阿里云鏡像問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-11-11
  • java數(shù)據(jù)隨機(jī)分頁(yè)實(shí)現(xiàn)方案

    java數(shù)據(jù)隨機(jī)分頁(yè)實(shí)現(xiàn)方案

    本文主要介紹了java數(shù)據(jù)隨機(jī)分頁(yè)實(shí)現(xiàn)方案,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-06-06
  • 深入解析MybatisPlus多表連接查詢

    深入解析MybatisPlus多表連接查詢

    在一些復(fù)雜的業(yè)務(wù)場(chǎng)景中,我們經(jīng)常會(huì)遇到多表連接查詢的需求,本文主要介紹了深入解析MybatisPlus多表連接查詢,具有一定的參考價(jià)值,感興趣的可以了解一下
    2024-06-06
  • Java編程獲取經(jīng)緯度之間距離的方法

    Java編程獲取經(jīng)緯度之間距離的方法

    這篇文章主要介紹了Java編程獲取經(jīng)緯度之間距離的方法,涉及Java數(shù)學(xué)運(yùn)算的相關(guān)技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下
    2015-11-11

最新評(píng)論