java 读取excel表格 内容、图片、图片自动上传、图片上传后回调上传地址,并赋值到图片表格位置

本文介绍了一种通过Excel批量导入题目的方法,包括读取Excel文件、解析数据、上传图片等功能,并提供了详细的Java代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

我看到网上并没有这种例子,前两天做了一个题库app项目,刚好研究出来,分享给大家

先看实例效果:

上传效果以及代码

excel表格:

在这里插入图片描述

功能示例

在这里插入图片描述

添加成功在这里插入图片描述

在这里插入图片描述

接下来看代码 测试的代码

	//批量添加
	@RequestMapping("/addQuestions")
	@ResponseBody
	public ResponseBase addQuestions(@RequestParam("file") MultipartFile file,Integer cid) throws IOException {
		try {
			// 获取所有的内容
			Map<String, Map<Integer, Map<Integer, String>>> sheets = excel.readExcelToMap(file);
			Set<String> keys = sheets.keySet();

			List<String> steetsNames = new ArrayList<>();

			// 获取所有的key ==页名称

			for (String steetsName : keys) {
				steetsNames.add(steetsName);
			}
			
			// 遍历所有的列
			List<question> questions = new ArrayList<>();
			for (int i = 0; i < sheets.size(); i++) {
				// 根据页名称获取页
				Map<Integer, Map<Integer, String>> rows = sheets.get(steetsNames.get(i));
				if(rows.size()>0){
					//检验第一列是否达到9列 
					if(!(rows.get(0).size()==9)){
						return setResultError("请检查表中列大小是否符合添加规范");
						
					}
					// 根据所有的行 遍历
					for (int j = 1; j < rows.size(); j++) {
						// 遍历当前行的所有列
						Map<Integer, String> columns = rows.get(j);
						question question = new question();
						question.setCid(cid);
						question.setQuestiontitle(columns.get(0));
						question.setQuestion_img(columns.get(1));
						question.setSelecta(columns.get(2));
						question.setSelectb(columns.get(3));
						question.setSelectc(columns.get(4));
						question.setSelectd(columns.get(5));
						question.setQuestiontrue(columns.get(6));
						question.setQuestion_analysis(columns.get(7));
						question.setQuestion_analysisImg(columns.get(8));
						questions.add(question);	
						
					}
				}
				
			}
			
			if(questions!=null && questions.size()>0){
				Integer addQuestions = qserver.addQuestions(questions);
				if(addQuestions>0){
					return setResultSuccess(addQuestions);
				}
				return setResultError("添加时出现未知错误!错误码:10");
			}
			
			return setResultError("表中数据小于1,请检查后重试");
		} catch (Exception e) {
			// TODO: handle exception
			System.out.println(e.getMessage());
			return setResultError("表格出现未知错误!错误码:20");
		}
		
	}

util代码

	//读取上传的文件
	public Map<String, Map<Integer, Map<Integer, String>>> readExcelToMap(MultipartFile file) throws IOException {
		
		Workbook wb = null;
		Sheet sheet = null;
		Row row = null;
		// 声明所有页的集合
		Map<String, Map<Integer, Map<Integer, String>>> mapSheet = new LinkedHashMap<>();
		wb = readExcel(file);
		if (wb != null) {
			// 获取总页数
			int pageSize = wb.getNumberOfSheets();
			for (int i = 0; i < pageSize; i++) {
				
				// 声明当前页的行和列
				Map<Integer, Map<Integer, String>> map = new HashMap<>();
				// 获取当前页
				sheet = wb.getSheetAt(i);
				//声明当前页图片的集合
				Map<String, PictureData> pMap = null;
				//获取图片
				if(file.getOriginalFilename().endsWith(".xls")){
					pMap = getPictures1((HSSFSheet) sheet);
				}else{
					pMap = getPictures2((XSSFSheet) sheet);
				}
				String sheetName = sheet.getSheetName();

				// System.out.println("获取当前页的最大行数");
				int rowSize = sheet.getPhysicalNumberOfRows();
				
//				System.out.println("总行数:"+rowSize);
				// System.out.println("遍历所有行");
				for (int j = 0; j < rowSize; j++) {
					// System.out.println("获取第"+j+"行");
					row = sheet.getRow(j);
					// System.out.println("获取当前页的最大列数");
					int columnSize = row.getPhysicalNumberOfCells();
					// 声明当前列
					Map<Integer, String> columnMap = new HashMap<>();
//					System.out.println("列大小:"+columnSize);
					for (int j2 = 0; j2 < columnSize; j2++) {
						// System.out.println("获取第"+j2+"列的内容");
						String value = (String)getCellFormatValue(row.getCell(j2));
						// 添加当前列的内容 j2代表第几列 value是内容
						columnMap.put(j2, value);

					}
					// 添加当前行的内容 j代表第几行 value是列的内容 意思是第几行第几列的内容
					map.put(j, columnMap);
				}
				//解析图片并上传到服务器 并设置该字段的值为字符串类型添加到map中 进行数据库上传
				Object key[] = pMap.keySet().toArray();
				
				for (int v = 0; v < pMap.size(); v++) {
					PictureData pic = pMap.get(key[v]);
					String picName = key[v].toString();
					String ext = pic.suggestFileExtension();
					byte[] data = pic.getData();
					try {
						InputStream input = new ByteArrayInputStream(data);
						
						FileUploadResponse fileUpload = uploads.excelImgUpload(input,ext);
						if(fileUpload.getUrl()!=null){
							//解析key 并根据key 设置 某一行的某一列的 图片链接
							String[] split = picName.split("-");
							Integer rowIndex = Integer.parseInt(split[0].toString()),columnIndex = Integer.parseInt(split[1].toString());
							//根据行下标 获取所有的列
							Map<Integer, String> columns = map.get(rowIndex);
							
							//根据列下标 设置图片链接值
							columns.put(columnIndex, fileUpload.getUrl());
						}
						
					} catch (Exception e) {
						System.out.println(e.getMessage());
					}
					
					
					
					
				}
				// 添加当前页的所有内容
				mapSheet.put(sheetName, map);
			}
		}
		return mapSheet;
	}

	// 读取excel
	@SuppressWarnings("unused")
	private static Workbook readExcel(MultipartFile file) {
		Workbook wb = null;
		
		if (file == null) {
			return null;
		}
		String filename = file.getOriginalFilename();
		InputStream is = null;
		try {
			is = file.getInputStream();
			if (filename.endsWith(".xls")) {
				return wb = new HSSFWorkbook(is);
			} else if (filename.endsWith(".xlsx")) {
				return wb = new XSSFWorkbook(is);
			} else {
				return wb = null;
			}

		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return wb;
	}
	

接下来看本地测试 参数改为string 的路径,在文件上传后,上传名字需要自己改为随机名 以防重复文件名

在这里插入图片描述

工具类代码

	public static Map<String, Map<Integer, Map<Integer, String>>> readExcelToMap(String excelFilePath) throws IOException {
		
		Workbook wb = null;
		Sheet sheet = null;
		Row row = null;
		// 声明所有页的集合
		Map<String, Map<Integer, Map<Integer, String>>> mapSheet = new LinkedHashMap<>();
		wb = readExcel(excelFilePath);
		if (wb != null) {
			// 获取总页数
			int pageSize = wb.getNumberOfSheets();
			for (int i = 0; i < pageSize; i++) {
				
				// 声明当前页的行和列
				Map<Integer, Map<Integer, String>> map = new HashMap<>();
				// 获取当前页
				sheet = wb.getSheetAt(i);
				//声明当前页图片的集合
				Map<String, PictureData> pMap = null;
				//获取当前页的所有图片
				if(excelFilePath.endsWith(".xls")){
					pMap = getPictures1((HSSFSheet) sheet); //用于区分 没写方法重载
				}else{
					pMap = getPictures2((XSSFSheet) sheet); //用于区分 没写方法重载
				}
				String sheetName = sheet.getSheetName(); //获取页名称

				// System.out.println("获取当前页的最大行数");
				int rowSize = sheet.getPhysicalNumberOfRows();
				
//				System.out.println("总行数:"+rowSize);
				// System.out.println("遍历所有行");
				for (int j = 0; j < rowSize; j++) {
					// System.out.println("获取第"+j+"行");
					row = sheet.getRow(j);
					// System.out.println("获取当前页的最大列数");
					int columnSize = row.getPhysicalNumberOfCells();
					// 声明当前列
					Map<Integer, String> columnMap = new HashMap<>();
//					System.out.println("列大小:"+columnSize);
					for (int j2 = 0; j2 < columnSize; j2++) {
						// System.out.println("获取第"+j2+"列的内容");
						String value = (String)getCellFormatValue(row.getCell(j2));
						// 添加当前列的内容 j2代表第几列 value是内容
						columnMap.put(j2, value);

					}
					// 添加当前行的内容 j代表第几行 value是列的内容 意思是第几行第几列的内容
					map.put(j, columnMap);
				}
				//解析图片并上传到服务器 进行上传后 返回上传地址 并根据图片所在的表格位置 赋值表格位置为 上传后的返回地址
				Object key[] = pMap.keySet().toArray();
				
				for (int v = 0; v < pMap.size(); v++) {
					//获取图像数据对象
					PictureData pic = pMap.get(key[v]);
					//获取文件名称
					String picName = key[v].toString();
					//获取文件后缀名
					String ext = pic.suggestFileExtension();
					byte[] data = pic.getData();//图片数据
					//本地测试图片上传开始
					FileOutputStream out = new FileOutputStream("D:\\" + picName + "." + ext);
					out.write(data);
					out.flush();
					out.close();
					//服务器上传可更该代码
					/*
					 * InputStream input = new ByteArrayInputStream(data);
					 * 此处书写文件上传调用的方法
					 * 正常上传为Multipartfile 类型的文件 
					 * 但是上传时还是需要转换成Inputstream 此处直接转换成该类型 由于该类型没办法获取 后缀名 所以需要传一个后缀名参数 
					 * FileUploadResponse fileUpload = uploads.excelImgUpload(input,ext);//这是我的,此工具类没有该方法  需要根据自己的需求书写
					 * 
					 */
					//本地测试结束
					//解析key 并根据key 设置 某一行的某一列的 图片链接
					String[] split = picName.split("-");
					Integer rowIndex = Integer.parseInt(split[0].toString()),columnIndex = Integer.parseInt(split[1].toString());
					//根据行下标 获取所有的列
					Map<Integer, String> columns = map.get(rowIndex);
					
					//根据列下标 设置图片链接值
					columns.put(columnIndex, "D:\\" + picName + "." + ext);//参数2为图片上传后的路径  
					
				}
				// 添加当前页的所有内容
				mapSheet.put(sheetName, map);
			}
		}
		return mapSheet;
	}

到了最后,可不能忘了最重要的地方,贴下载链接!:https://download.csdn.net/download/q702631026/11085045

评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

发呆丶i

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值