poi读取excel中的内容(带图片)

【POI稀有技巧】获取excel导入的图片并存储 最近公司要通过excel进行图片导入导出多行试题数据,发现网上资料较少,并且很多教程也用不了,特此记录分享,让各位道友减少查找资料时间。 阅读详情

项目中有一需求:需要读取excel中的信息,带图片,需要将每一行的图片,做对应,整理方法如下:

主要逻辑:
1,获取excel对象,
2,读取excel中所有的图片流,将图片所处的位置和图片流存在map中getPictures()方法
4,根据图片所处位置,获取图片流,上传图片,并将图片的所处位置和上传路径存在map中printImg()方法
5,读取excel中的每一行文字,当读取到图片列时,根据key获取第四步的map中的value,将路径以及文字信息存入list中;readData()方法

  1. controller层
	@PostMapping("/uploadFile")
	public List<Map<String, String>> uploadMonitorItem(MultipartFile upfile, String providerId) throws Exception {

		InputStream in = null;
		List<Map<String, String>> listob = null;
		in = upfile.getInputStream();
		listob = ExcelUtil.readExcelByInputStream(in, providerId);

		return listob;
	}

2.service层


import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.apache.poi.ss.usermodel.PictureData;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

import com.qskj.framework.config.ERPConfig;

public class ExcelUtil {
	/**
	 * 读取 Excel文件内容
	 *
	 * @param inputstream 文件输入流
	 * @return
	 * @throws Exception
	 */
	public static List<Map<String, String>> readExcelByInputStream(InputStream inputstream, String providerId)
			throws Exception {
		// 结果集
		List<Map<String, String>> list = new ArrayList<Map<String, String>>();

		XSSFWorkbook wb = new XSSFWorkbook(inputstream);
		String filePath = ERPConfig.getProfile() + "/" + "pic/" + providerId + "/";//图片保存路径
		final XSSFSheet sheet = wb.getSheetAt(0);// 得到Excel工作表对象

		Map<String, PictureData> map = ExcelImgUtil.getPictures(sheet);//获取图片和位置

		Map<String, String> pathMap = ExcelImgUtil.printImg(map, filePath);//写入图片,并返回图片路径,key:图片坐标,value:图片路径
		list = ExcelImgUtil.readData(sheet, pathMap,providerId);
		return list;
	}
}

3,工具类

package com.qskj.project.util;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.poi.POIXMLDocumentPart;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.PictureData;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.xssf.usermodel.XSSFClientAnchor;
import org.apache.poi.xssf.usermodel.XSSFDrawing;
import org.apache.poi.xssf.usermodel.XSSFPicture;
import org.apache.poi.xssf.usermodel.XSSFShape;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.CTMarker;

import com.qskj.common.utils.security.Md5Utils;
import com.qskj.framework.config.ERPConfig;

public class ExcelImgUtil {
	private static int counter = 0;

	/**
	 * 获取图片和位置 (xlsx)
	 * 
	 * @param sheet
	 * @return
	 * @throws IOException
	 */
	public static Map<String, PictureData> getPictures(XSSFSheet sheet) throws IOException {
		Map<String, PictureData> map = new HashMap<String, PictureData>();
		List<POIXMLDocumentPart> list = sheet.getRelations();
		for (POIXMLDocumentPart part : list) {
			if (part instanceof XSSFDrawing) {
				XSSFDrawing drawing = (XSSFDrawing) part;
				List<XSSFShape> shapes = drawing.getShapes();
				for (XSSFShape shape : shapes) {
					XSSFPicture picture = (XSSFPicture) shape;
					XSSFClientAnchor anchor = picture.getPreferredSize();
					CTMarker marker = anchor.getFrom();
					String key = marker.getRow() + "-" + marker.getCol();
					byte[] data = picture.getPictureData().getData();
					map.put(key, picture.getPictureData());
				}
			}
		}
		return map;
	}

	public static Map<String, String> printImg(Map<String, PictureData> sheetList, String path) throws IOException {
		Map<String, String> pathMap = new HashMap<String, String>();
		Object[] key = sheetList.keySet().toArray();
		File f = new File(path);
		if (!f.exists()) {
			f.mkdirs(); // 创建目录
		}
		for (int i = 0; i < sheetList.size(); i++) {
			// 获取图片流
			PictureData pic = sheetList.get(key[i]);
			// 获取图片索引
			String picName = key[i].toString();
			// 获取图片格式
			String ext = pic.suggestFileExtension();
			String fileName = encodingFilename(picName);
			byte[] data = pic.getData();

			// 图片保存路径
			String imgPath = path + fileName + "." + ext;
			FileOutputStream out = new FileOutputStream(imgPath);

			imgPath = imgPath.substring(ERPConfig.getProfile().length(), imgPath.length());// 截取图片路径
			pathMap.put(picName, imgPath);
			out.write(data);
			out.close();
		}
		return pathMap;
	}

	private static final String encodingFilename(String fileName) {
		fileName = fileName.replace("_", " ");
		fileName = Md5Utils.hash(fileName + System.nanoTime() + counter++);
		return fileName;
	}

	/**
	 * 读取excel文字
	 * 
	 * Excel 07版本以上
	 * 
	 * @param sheet
	 */
	public static List<Map<String, String>> readData(XSSFSheet sheet, Map<String, String> map,String providerId) {
	
		List<Map<String, String>> newList = new ArrayList<Map<String, String>>();// 单行数据
		try {

			int rowNum = sheet.getLastRowNum() + 1;
			for (int i = 1; i < rowNum; i++) {// 从第三行开始读取数据,第一行是备注,第二行是标头

				Row row = sheet.getRow(i);// 得到Excel工作表的行
				if (row != null) {
					int col = row.getPhysicalNumberOfCells();
					// 单行数据
					
					Map<String, String> mapRes = new HashMap<String, String>();// 每格数据
					for (int j = 0; j < col; j++) {
						Cell cell = row.getCell(j);
						if (cell == null) {
							// arrayString.add("");
						} else if (cell.getCellType() == 0) {// 当时数字时的处理

							mapRes.put(getMapKey(j), new Double(cell.getNumericCellValue()).toString());
						} else {// 如果EXCEL表格中的数据类型为字符串型
							mapRes.put(getMapKey(j), cell.getStringCellValue().trim());

						}

					}

					if (i != 1) {// 不是标头列时,添加图片路径

						String path = map.get(i + "-9");
						mapRes.put(getMapKey(9), path);

					}
					mapRes.put("providerId", providerId);
					newList.add(mapRes);
				
				}

			}

		} catch (Exception e) {
		}
		return newList;
	}

	public static String getMapKey(int num) {
		String res = "";
		switch (num) {
		case 0:// 分类
			res = "secondDictCode";
			break;
		case 1:// 产品名称
			res = "productName";
			break;
		case 2:// 规格型号
			res = "specification";
			break;
		case 3:// 计量单位
			res = "unit";
			break;
		case 4:// 风格
			res = "style";
			break;
		case 5:// 颜色
			res = "color";
			break;
		case 6:// 采购单价
			res = "purchasePrice";
			break;
		case 7:// 材质
			res = "material";
			break;
		case 8:// 备注
			res = "remark";
			break;

		case 9:// 产品图片
			res = "picture";
			break;

		default:
			break;
		}
		return res;
	}
}

  1. postman请求测试:/poi/uploadFile?providerId=5
  2. 最终效果
[
    {
        "unit": "计量单位",
        "color": "颜色",
        "material": "材质",
        "providerId": "5",
        "specification": "规格型号",
        "style": "风格",
        "remark": "备注",
        "purchasePrice": "采购单价",
        "secondDictCode": "分类",
        "productName": "产品名称",
        "picture": "产品图片"
    },
    {
        "unit": "平方米",
        "color": "白色,绿色,红色",
        "material": "木质1",
        "providerId": "5",
        "specification": "600*900",
        "style": "美式,北欧,中式",
        "remark": "大萨达十大1",
        "purchasePrice": "66.8",
        "secondDictCode": "家具",
        "productName": "床",
        "picture": "/pic/5/b3e42b2d741cc16bff4fefaa6bb61d87.jpeg"
    },
    {
        "providerId": "5",
        "picture": null
    }
]

github代码demo,及使用说明

csdn资源文件,代码demo及使用说明

java poi 获取excel中的图片(包含wps中嵌入单元格图片) 上面我们发现如果有图片ID和图片名称的对应关系 那么我们就能确定图片ID和代码中获取的图片对应关系,但是很遗憾 这里没有这个对应关系 接下来继续找。已知这个图片公式中的图片ID是 ID_DAF859A2B4904BF7A304D49029CAD99C。poi方法可以获取到工作表中所有图片 那么问题来了 如何将图片和图片ID对应起来。可以看到这个文件里面有图片ID的数据结构 但是又是如何和图片对应起来的呢。wps中可以插入浮动图片,也可以插入嵌入单元格图片; 阅读详情

相关推荐

JAVA POI读取带有多张图片的excel时发生的问题

业务场景:读取excel数据,该excel中每行都会有图片,各个图片可以重复,现在需要拿到每行对应的图片。 测试用excel,如图可见有两个一样的图片,但是其实是复制的两个不同文件: poi获取图片我所知道的只有一个方法,为了测试我输出图片到了本地: 打印出的结果: 明明excel中有三张图片,却只打印了两张,输出到本地的图片也确实是去过重的两张。无论是改文件名还是怎么样,那两张图片永远都被视为一张。 不死心的我又拿到了他单元格的数据,单元格类型为FORMULA,但确实是三张图片: 那就奇怪了,三个单元

BUGSLAYER_的博客 1773

java使用POI读取Excel表格中的图片(包含嵌入单元格图片,浮动图片,xls-2003,xlsx-2007)

EasyExcel读取数据非常好用,但是不支持读取表格中的图片数据, java使用POI读取Excel表格中的图片(包含嵌入单元格图片,浮动图片,xls-2003,xlsx-2007)

qq_23123177的博客 2万+

详解使用poi读取Excel中的数据和图片信息

背景 在一些业务需求下,比如导入excel数据,而这些excel文档中又包含图片等内容,那如何读取到excel图片内容,并保存下来呢? 解决方案 首先,在Springboot 环境下导入poi包,pom.xml如下 <!--poi excel --> <dependency> <groupId>org.apache.poi</groupId> <artifactId>p

weixin_39098944的博客 3458

POI导入excel读取excel中图片

5.根据此内容可以扩展保存数据库功能,在此暂不实现。1.首先excel图片需要跟单元格绑定。3.编写测试方法进行导入。

lianyunpeng的博客 2748

Spring boot 读取Excel并且带图片

业务需求,需要读取excel数据,数据中有带图片的形式。网上的教程多且杂,很少整合在一起。所以就整理了一份详细的文档。 一、Maven依赖,使用的是apache的poi依赖 &lt;dependency&gt; &lt;groupId&gt;org.apache.poi&lt;/groupId&gt; &lt;artifactId&gt;poi&lt;/artifactId...

GRW 3745

Java语言利用POI读取excel文档,利用Freemarker建立word模板(带图片),excel每一行数据生成单个word文档,再利用POI合并成一个word文档

需求: 现有一个excel文档,该文档从第三行开始,每一行代表一个化石及其相关的登记资料,如图1,现在需要将每一行数据的内容,填写到对应的word文档中,并将入库照片编号对应的照片插入对应位置,如图2,最后要求不能生成单个的word文档,因为文档个数多了,不方便整理和打印,需要合并成一个或者多个; 图1: 图2: 实现思路: Java语言利用...

the blog of alunSemiconductor 2882

POI读取带有图片(图片有的是合并单元格的)的商品列表Excel

首先明确的是:(案例是在2003基础上的,2007版的相同)           暂时还是不清楚poi读取Excel的顺序问题!!!!   但是,POI在读取Excel文件中的文字是的顺序,首先是sheet名称,其次是按照列进行读取文字、文本(无论文本是不是合并过单元格)         ###如果遇到图片是不能按照其默认的CELL_TYPE_FORMULA(公式型-2)、CELL...

weixin_30381793的博客 432

POI 实现excel中的数据及图片导入数据库

POI 实现excel中的数据及图片导入数据库 一、 引言: 把excel中的内容转换到数据库中,是一个常见的工作。 而如果excel中有图片应该如何进行图片的操作,以及确定图片到底是属于哪一行的内容。在图片的解析中发现,图片的解析和文字的解析是分开的。能够直接读取图片左上角所处的单元格的位置,但是图片在excel中可以一定,并不特定的属于某一个单元格。 二、代码 pom.xml 文件引入jar 注意:请用Poi jar 3.9 版本 不然读取图片代码会报错 <!-- 引入poi,解析workbo

yayayu_的博客 2903

Java读取WPS Excel嵌入式图片:POI增强方案与实战避坑指南

在Java后端开发中,处理Excel文件是常见需求,Apache POI库是处理Microsoft Office格式文件的标准工具。其原理是基于Office Open XML(OOXML)标准解析ZIP压缩包内的XML与资源文件。然而,当需要读取WPS Office生成的.xlsx文件中的嵌入式图片时,由于WPS在实现OOXML标准时存在细微差异,POI默认的`getAllPictures()`方法常失效,导致图片读取为null或位置错乱,影响了数据导入导出、报表生成和内容审核等应用场景的完整性。为此,本文

weixin_33695450的博客 483

Java读取WPS excel.xlsx嵌入图片

首先我们知道不管是word,excel还是ppt文件本质上就是一个zip的压缩包,里面有个许多xml格式的文件保存相关的信息,思路就是我们可以把wps编辑的.xlsx文件当做zip包解压缩,然后去找图片文件的存储位置,再结合相关的xml配置文件对应文件和单元格的关系就能够提取出wps格式excel嵌入图片了。解决方案有两种,第一种在wps编辑的时候改变图片的插入方式改为浮动,自然就是和标准的office兼容的,apache poi相关的工具就能够读取了。通过这种方式就可以获取了wps的内容了。

WAXXD的博客 2776

使用POI对excel文件进行读取

使用POI对excel文件进行读取 Excel转换为HTML表格(包括样式) Excel读取图片 Excel读取附件 使用POI对excel文件进行读取 excel转换HTML 代码块 ReadExcel2Html 类 ColorInfo 类 ColorUtil 类 OperaColor 类 Excel读取图片 代码块 Picture 类主要用于保存图片所在位置x和y分别

aiquan2016的博客 2710

JAVA POI的excel中包含图片进行读取保存,单张图片,多张图片

JAVA POI的excel中包含图片进行读取保存,单张图片,多张图片 ---------------------------------------------效果----------------------------------------------------------- 2.多张图片 1.单张图片 import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; impo

weixin_43964403的博客 5044

Java 通过POI快速导入带图片的excel并且图片不会丢失

Java 导入带图片的excel Java 通过poi快速导入带图片的excel并且图片不丢失 Java 图片excel导入

Mou_O的博客 5630

java poi方式读取Excel的图片

JAVA poi读取excel表格

h1403635700的博客 4646

POI读取word文档的文字内容和图片内容

POI读取word文档的文字内容和图片内容

杂记 | 使用keycloak实现SSO单点登录(新手向,概念、原理、逻辑、详细步骤、难点解释)

使用keycloak实现SSO单点登录(概念、原理、逻辑、详细步骤、难点解释)

野生猿林仔的博客 2万+

Java读取Excel中的图片,并保存

说明 本文代码转载自以下博客 https://www.cnblogs.com/shuilangyizu/p/11937039.html 原博文更强更猛。 注意: ● 以下代码按我自己的实际需求,略作修改。 ● 以下代码只具有读取xls文件中的图片,并保存到指定位置的功能; ● 保存的图片都是jpg格式 代码 import java.io.BufferedInputStream; import java.io.File; import java.io.FileInputStream; import jav

qq_25844803的博客 8589

速腾R128雷达+海康全景相机ROS数据采集避坑实录:从‘雷达不转’到MATLAB标定的完整流程

本文详细记录了速腾R128激光雷达与海康威视全景相机在ROS环境下的数据采集与MATLAB标定全流程。从硬件配置的常见陷阱(如雷达旋转参数设置)、驱动编译的依赖管理,到多传感器同步的实战技巧和MATLAB标定方法,提供了完整的避坑指南和技术方案。特别针对RoboSense R128雷达和海康相机的特殊需求给出了具体解决方案。

weixin_28717807的博客 1218

java读取Excel,(支持WPS嵌入式图片)

java读取Excel,java读取WPS内嵌图片,POI读取不到内嵌图片

maudboy的博客 1万+

多节阶梯阻抗变换器工程设计的公式推导

  多节阶梯阻抗变换器工程设计的公式推导,仔细看此文,有点烧脑,所以碎片十分钟,收获一丢丢。   现在就来设计一个超宽带多节阶梯阻抗变换器,要求带内纹波符合切比雪夫分布。   其实,此文已经是省去了大量中间公式推导,只剩下精炼内容了。   阶梯阻抗变换器指标需求   假设现在有一项目需求分析结果是:做一个微带线超宽带阶梯阻抗变换器,指标如下:   从50欧变换到100欧;   回波损耗22dB;   功率容量:2W;   频率范围2~18GHz;   插损能做多少就多少,用30mil板厚.

wusuowei1010的博客 7806

Cortex-M TrustZone实战:从硬件隔离到安全交互的嵌入式开发指南

在嵌入式系统开发中,硬件安全隔离是构建可信执行环境(TEE)的核心技术。其原理是通过处理器硬件机制,将系统资源划分为安全与非安全域,实现内存、外设和代码的强制访问控制。这项技术的核心价值在于,它能在单一芯片上为资源受限的物联网(IoT)设备、智能传感器等提供芯片级的安全基础,无需依赖外置安全元件,从而降低BOM成本并简化设计。典型的应用场景包括保护设备密钥、实现安全启动、构建安全服务(如加密、密钥管理)以供应用程序调用。本文聚焦于Arm Cortex-M系列微控制器上的TrustZone技术实现,针对开发中

weixin_42639246的博客 300

poi 读取excel中的图片,并获取图片做业务处理

  import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.util.HashMap; import java.util.List; import java.util.Map; import org....

qq_36457575的博客 8000

基于Spring Boot在线远程考试系统的设计与实现

结合先进的互联网技术,开发符合需求的软件,让数据内容管理不管是从录入的及时性,查看的及时性还是汇总分析的及时性,都能让正确率达到最高,管理更加的科学和便捷。目前的信息时代,对信息的管理趋于高效化,便捷化,这也是计算机大力普及所带来的便利,此程序软件在设备选用上,依靠的是比较大众的电脑设备,对电脑的配置没有过多要求,一般学校的计算机机房的电脑都可以满足程序开发需求,另外,开发出此款程序,让信息处理变得高效率,其所带来的高效益是远超程序开发的低成本的,因此程序开发的资金投入是可以忽略不计的。

ITbiyesheji的博客 1215
上一篇: windows下安装redis,实现远程访问
下一篇: linux或windows下定时备份mysql数据库
只会debug
博客等级 码龄9年 69粉丝 41原创
评论 23
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值