Springboot——使用poi实现excel动态图片导入解析

文章目录

  • 前言
  • 依赖引入
  • 导入实现
    • 方式一
    • 方式二
  • 导出参考

前言

最近要实现一个导入导出的功能点,需要能将带图片的列表数据导出到excel中,且可以导入带图片的excel列表数据。

考虑到低代码平台的表头与数据的不确定性,技术框架上暂定使用Apache-POI。

依赖引入

由于POI的包很多种,为了避免引入不全导致的运行报错问题,这里使用Springboot技术,引入主要依赖如下:

<dependency>
    <groupId>cn.afterturn</groupId>
    <artifactId>easypoi-spring-boot-starter</artifactId>
    <version>4.1.3</version>
</dependency>

导入实现

经过查阅相关的资料、案例等,目前导入解析有两种方式。

本次自测使用的excel模板如下样式
在这里插入图片描述

方式一

该方式可以解析所有的数据,多张图片仅能解析出一张,但不能定位出图片的下标位置信息。仅用于参考。

import org.apache.commons.compress.utils.Lists;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFPictureData;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Base64;
import java.util.Iterator;
import java.util.List;

@RestController
@RequestMapping("/poi")
public class TestController {

    /**
     * excel上传解析,能获取数据和图片
     * 但图片多张只能拿到一张,且无法获取位置点
     * @param file
     * @return
     * @throws IOException
     */
    @PostMapping("/upload")
    public String upload(MultipartFile file) throws IOException {
        List<List<String>> data = Lists.newArrayList();
        Workbook workbook = new XSSFWorkbook(file.getInputStream());
        Sheet sheet = workbook.getSheetAt(0);
        Iterator<Row> rowIterator = sheet.iterator();
        while (rowIterator.hasNext()) {
            Row row = rowIterator.next();
            List<String> rowData = new ArrayList<>();
            Iterator<Cell> cellIterator = row.iterator();
            while (cellIterator.hasNext()) {
                Cell cell = cellIterator.next();
                rowData.add(getCellValueAsString(cell));
            }
            data.add(rowData);
        }

        // 处理图片
        List<String> imageList = new ArrayList<>();
        List<XSSFPictureData> allPictures = (List<XSSFPictureData>) workbook.getAllPictures();
        for (XSSFPictureData pictureData : allPictures) {
            byte[] bytes = pictureData.getData();
            String mimeType = pictureData.getMimeType();
            imageList.add(new String(bytes,"UTF-8"));
        }
        workbook.close();
        return "";
    }

    private String getCellValueAsString(Cell cell) {
        CellType cellType = cell.getCellType();
        switch (cellType) {
            case STRING:
                return cell.getStringCellValue();
            case NUMERIC:
                return String.valueOf(cell.getNumericCellValue());
            case BOOLEAN:
                return String.valueOf(cell.getBooleanCellValue());
            default:
                return "";
        }
    }
}

断点查看导入解析的信息结果,如下所示:
在这里插入图片描述

方式二

相比方式一的逻辑,采取一种新的解析方式,迭代 sheet.getDrawingPatriarch()的结果集进行判断。

但这样只能拿到图片,数据部分可以参考方式一去取。

/**
 * excel 上传解析图片
 * 多张都能获取,且能获取位置点
 * 行 row 与 列 col 从下标 0 开始计算
 * @param file
 * @return
 * @throws IOException
 */
@PostMapping("/upload2")
public String upload2(MultipartFile file) throws IOException {
    // 多张图片,以一样的时间戳开头,行与列组成名称
    long timeMillis = System.currentTimeMillis();
    XSSFWorkbook tempWorkBook = new XSSFWorkbook(file.getInputStream());
    // 获取模板sheet页
    Sheet sheet = tempWorkBook.getSheetAt(0);
    Drawing<?> drawing = sheet.getDrawingPatriarch();
    for (Shape shape : drawing) {
        if (shape instanceof Picture) {
            System.out.println("  ");
            Picture picture = (Picture) shape;
            ClientAnchor anchor = picture.getClientAnchor();

            int row1 = anchor.getRow1();
            short col1 = anchor.getCol1();
            System.out.println("row:"+row1+" col:"+col1);

            PictureData pictureData = picture.getPictureData();
            byte[] data = pictureData.getData();
            System.out.println(Base64.getEncoder().encodeToString(data));
            String imgType = pictureData.suggestFileExtension();
            // 将图片保存到项目路径下
            OutputStream outputStream = new FileOutputStream(timeMillis+"__"+row1+"_"+col1+"_img."+imgType);
            outputStream.write(data);
            outputStream.close();
        }
    }
    tempWorkBook.close();
    return "";
}

运行后的效果如下所示:
在这里插入图片描述
通过控制台中的打印位置信息,对比excel文件,能够定位图片所在单元格。
在这里插入图片描述

导出参考

Li-Zzz 的 导出Excel实现一单元格导出多图片

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/889984.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

线性代数在大一计算机课程中的重要性

线性代数在大一计算机课程中的重要性 线性代数是一门研究向量空间、矩阵运算和线性变换的数学学科&#xff0c;在计算机科学中有着广泛的应用。大一的计算机课程中&#xff0c;线性代数的学习为学生们掌握许多计算机领域的关键概念打下了坚实的基础。本文将介绍线性代数的基本…

C++一个很好的计时方法

C一个很好的计时方法 //记时LARGE_INTEGER t1;LARGE_INTEGER t2;LARGE_INTEGER f;QueryPerformanceFrequency(&f);QueryPerformanceCounter(&t1);Sleep(100);QueryPerformanceCounter(&t2);double time;time (double)(t2.QuadPart-t1.QuadPart)/(double)f.QuadPar…

【Flutter】合并多个流Stream

1.说明 无意间发现了一个好用的库rxdart&#xff0c;它为 Dart 的 Stream 添加了额外的功能。 2.功能 &#xff08;1&#xff09;合并多个流Stream 借助Rx.combineLatest2()合并两个流stream1和stream2。 注意&#xff1a;如果dart文件中同时使用了getx&#xff0c;需要隐…

UE4 材质学习笔记03(翻书(Flipbook)动画/环境混合)

一.FlipBook Animation 如果你想让游戏以每秒30帧的速度运行&#xff0c;所有内容都必须在33毫秒内渲染出来&#xff0c; 如果你想让游戏以每秒60帧的速度运行的话&#xff0c;必须在16毫秒内。 所以当一个效果需要很多细节的时候&#xff0c;往往会离线创建它&#xff0c;然…

LLM | Tokenization 从原理与代码了解GPT的分词器

声明&#xff1a;以上内容全是学习Andrej Karpathy油管教学视频的总结。 --------------------------------------------------------------------------------------------------------------------------------- 大家好。在今天我们学习llm中的Tokenization&#xff0c;即分…

springboot 整合 rabbitMQ(1)

目录 一、MQ概述 二、MQ的优势和劣势 三、常见的MQ产品 RabbitMQ使用步骤 第一步&#xff1a;确保rabbitmq启动并且可以访问15672 第二步&#xff1a;导入依赖 第三步&#xff1a;配置 auto自动确认 manual手工确认&#xff08;推荐使用&#xff01;可以防止消息丢失&a…

东华大学《2023年+2019年824自动控制原理真题》 (完整版)

本文内容&#xff0c;全部选自自动化考研联盟的&#xff1a;《东华大学824自控考研资料》的真题篇。后续会持续更新更多学校&#xff0c;更多年份的真题&#xff0c;记得关注哦~ 目录 2023年真题 2019年真题 Part1&#xff1a;2023年2019年完整版真题 2023年真题 2019年真题…

人工智能AI等级划分

人工智能等级划分 第一级“聊天机器人”。 第二级“推理者”水平。这一级别的AI系统具备类似拥有博士学位教育但未配备任何工具的人类&#xff0c;能执行基础的问题解决任务。据悉&#xff0c;OpenAI的管理层在会议中还向员工们展示了涉及GPT-4 AI模型的一个研究项目&#xff…

ip地址距离多远会变城市

在探讨“IP地址距离多远会变城市”这一话题时&#xff0c;我们首先需要理解几个核心概念&#xff1a;IP地址、地理位置定位以及网络架构的基本原理。这一问题实质上触及了互联网通信的底层逻辑与地理位置信息服务的交集。 一、IP地址与地理位置的关联 IP地址&#xff0c;即互联…

【计算机方向】三本计算机视觉IEEE系列,发文量高,影响因子呈上升趋势,备受国人追捧!

本期将为您带来三本计算机SCI 妥妥毕业神刊&#xff01; IEEE Transactions on Pattern Analysis and Machine Intelligence IEEE Transactions on Knowledge and Data Engineering IEEE Transactions on Cognitive and Developmental Systems 期刊名称&#xff1a;IEEE Tr…

【YOLOv11】ultralytics最新作品yolov11 AND 模型的训练、推理、验证、导出 以及 使用

​目录 一 ultralytics公司的最新作品YOLOV11 1 yolov11的创新 2 安装YOLOv11 3 PYTHON Guide 二 训练 三 验证 四 推理 五 导出模型 六 使用 文档&#xff1a;https://docs.ultralytics.com/models/yolo11/ 代码链接&#xff1a;https://github.com/ultralytics/ult…

【MLP-Mixer】核心方法解读

abstract&#xff1a; 我们提出MLP-Mixer架构(或简称“Mixer”)&#xff0c;这是一个具有竞争力但在概念和技术上都很简单的替代方案&#xff0c;它不使用卷积或自关注。相反&#xff0c;Mixer的架构完全基于多层感知器(mlp)&#xff0c;这些感知器可以在空间位置或特征通道上…

JQuery基本操作(二)

遍历 $(选择器).each(function(下标,值){//代码块 });$.each(数组名,function(下标,值){//代码块 }); <body><button> 获得数组下标和值</button> </body> <script>$(function(){$("button").click(function(){var arr [1,2,3,4,5,…

Ansible 工具从入门到使用

1. Ansible概述 Ansible是一个基于Python开发的配置管理和应用部署工具&#xff0c;现在也在自动化管理领域大放异彩。它融合了众多老牌运维工具的优点&#xff0c;Pubbet和Saltstack能实现的功能&#xff0c;Ansible基本上都可以实现。 Ansible能批量配置、部署、管理上千台主…

基于 CSS Grid 的简易拖拉拽 Vue3 组件,从代码到NPM发布(2)- NPM发布、在线示例

这里分享一下本开源项目是如何构建组件库及其如何发布到NPM上的&#xff0c;还有组件库与在线示例的构建有什么差异。 请大家动动小手&#xff0c;给我一个免费的 Star 吧~ 大家如果发现了 Bug&#xff0c;欢迎来提 Issue 哟~ github源码 NPM 示例地址 版本更新信息 这两天抽空…

自动化测试中如何高效进行元素定位!

前言 在自动化测试中&#xff0c;元素定位是一项非常重要的工作。良好的元素定位可以帮助测试人员处理大量的测试用例&#xff0c;加快测试进度&#xff0c;降低工作负担。但是在实际的测试工作中&#xff0c;我们常常遇到各种各样的定位问题&#xff0c;比如元素定位失败、元…

鸿蒙开发之ArkUI 界面篇 三十三 Builder(封装容器)

鸿蒙开发中遇到容器相同、容器下面的子组件相同&#xff0c;就是子组件的文字不同&#xff0c;背景颜色不同&#xff0c;文字颜色不同之类&#xff0c;就可以使用Builder来封装&#xff0c;语法格式如下&#xff1a; 例如下面的界面&#xff1a; Row4个ColumImageText来实现&am…

Python WebSocket 的原理及其应用

Python WebSocket 的原理及其应用 在现代 Web 开发中&#xff0c;实时通信成为了越来越多应用的重要组成部分。尤其是像聊天应用、实时数据更新、在线游戏等场景&#xff0c;服务器与客户端之间的即时数据传输需求非常迫切。在传统的 HTTP 协议中&#xff0c;通信往往是基于请…

麒麟V10系统下的调试工具(网络和串口调试助手)

麒麟V10系统下的调试工具&#xff08;网络和串口调试助手&#xff09; 1.安装网络调试助手mnetassist arm64-main ①在linux下新建一个文件夹 mkdir /home/${USER}/NetAssist②将mnetassist arm64-main.zip拷贝到上面文件夹中&#xff0c;并解压给权限 cd /home/${USER}/Ne…