web开发excel文件上传及解析(下)

web开发excel文件上传及解析(下)

前言:

接着上一篇博客文件上传,这一篇博客实践的是excel文件的解析,通常我们会需要这样的需求,就是让用户下载一个格式的模板,然后在模板中按照要求填写资料,最后的就是将excel中的内容全部保存到数据库中,从而实现一种批量的上传的作用,节省很多时间。

准备工作:

要实现excel文件的解析,我们同样需要依赖相应的jar包。如果是maven依赖则需要在pom.xml中添加如下依赖

 <!-- 解析Excel文件的jar包 用于2003- 版本的excel -->
<!-- https://mvnrepository.com/artifact/org.apache.poi/poi -->
<dependency>
   <groupId>org.apache.poi</groupId>
   <artifactId>poi</artifactId>
   <version>3.17</version>
</dependency>
<!-- 解析Excel文件的jar包 用于2007+ 版本的excel -->
<dependency>
   <groupId>org.apache.poi</groupId>
   <artifactId>poi-ooxml</artifactId>
   <version>3.17</version>
</dependency>

如果需要下载jar包,则从下面的地址中下载相应的jar包,然后导入到项目中

链接:https://pan.baidu.com/s/1wkc7Aak4P_fwvmYoxlIwHQ 密码:wiji

功能实现:

全部代码如下:

ExcelUtil.java

package com.tools.utils;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.DateUtil;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

public class ExcelUtils {

	/**
	 * 根据文件路径,生成workbook实例
	 * @param filePath
	 * @return
	 */
	public static Workbook readExcel(String filePath) {
		Workbook workbook = null;
		if(filePath == null) return null;
		InputStream inputStream;
		try {
			inputStream = new FileInputStream(filePath);
			workbook = new XSSFWorkbook(inputStream);
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return workbook;
	}
	
	/**
	 * 通过流获取workbook的实例
	 * @param in
	 * @return
	 */
	public static Workbook readExcel(InputStream in) {
		Workbook workbook = null;
		try {
			//这里仅仅解析的是xlsx类型的excel,如果是xls格式的new HSSFWorkbook(in),大家可根据文件的后缀不同,自动适配
			workbook = new XSSFWorkbook(in);
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return workbook;
	}
	
	public static List<Map<String, String>> analysisWorkbook(Workbook workbook){
		if(workbook == null) return null;
		List<Map<String,String>> result = new ArrayList<>();
		//定义excel有哪些字段
		String[] colunms = {"name","age","score"};
		//获取第一个sheet
		Sheet firstSheet = workbook.getSheetAt(0);
		int rowNums = firstSheet.getPhysicalNumberOfRows();
		//获取第一行
		Row row = firstSheet.getRow(0);
		//获取最大的列数
		int colunmNums = row.getPhysicalNumberOfCells();
		
		for(int i=1;i<rowNums;i++) {
			row = firstSheet.getRow(i);
			Map<String,String> cellMap = new HashMap<>();
			if(row!=null) {
				for(int j=0;j<colunmNums;j++) {
					cellMap.put(colunms[j],(String) getCellValue(row.getCell(j)));
				}
			}
			result.add(cellMap);
		}
		return result;
	}
	
	/**
	 * 获取每一个excel表格中的value
	 * @param cell
	 * @return
	 */
	public static Object getCellValue(Cell cell) {
		Object result = null;
		if(cell == null) return null;
		switch (cell.getCellType()) {
		case Cell.CELL_TYPE_NUMERIC:
			result = String.valueOf(cell.getNumericCellValue());
			break;
		case Cell.CELL_TYPE_FORMULA:
			//判断cell是否是日期格式
			if(DateUtil.isCellDateFormatted(cell)) {
				result = cell.getDateCellValue();
			}else {
				result = String.valueOf(cell.getNumericCellValue());
			}
			break;
		case Cell.CELL_TYPE_STRING:
			result = cell.getRichStringCellValue().getString();
			break;
		default:
			result="";
			break;
		}
		return result;
	}
	
}

 Controller中的部分代码

@RequestMapping(value="/uploadExcelFile",method=RequestMethod.POST,produces = "text/html;charset=UTF-8")
	@ResponseBody
	public String uploadExcelFile(@RequestParam("file") CommonsMultipartFile file,HttpServletRequest request) {
		try {
			//file upload start
			String path = request.getSession().getServletContext().getRealPath("/");
			String fileName = "display.xlsx";
			File excelFile = new File(path+fileName);
			LOGGER.info("uploadExcelFile file = "+excelFile.toString());
			if(excelFile.exists()) {
				excelFile.delete();
			}
			file.transferTo(excelFile);
			//file upload end
			//解析
			InputStream in = new FileInputStream(excelFile);
			Workbook workbook = ExcelUtils.readExcel(in);
			List<Map<String, String>> list = ExcelUtils.analysisWorkbook(workbook);
			for(Map<String,String> map : list) {
				for(Entry<String,String> entry : map.entrySet()) {
					System.out.println(entry.getKey()+":"+entry.getValue());
				}
			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return "fail";
		}
		return "success";
	}

这部分代码仅仅是简单写的实践的实例,controller中不应该写这么多逻辑,这里为了简单演示功能,上面congroller中的代码,前半部分是文件上传,后半部分是文件解析。而文件的解析,我单独封装到一个ExcelUtil中了。

运行结果:

首先看下要解析的excel的内容

web开发excel文件上传及解析(下)

接下来看一下,解析的结果:

web开发excel文件上传及解析(下)

excel的简单解析的功能就介绍到这里了,大家可以以这个为demo,开发自己的解析excel的需求了,如需要了解文件上传可查看上一篇博客文件上传的实践

 

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/111240.html原文链接:https://javaforall.net

(0)
上一篇 2021年8月2日 下午8:00
下一篇 2021年8月2日 下午9:00


相关推荐

  • STM32 定时器中TIM_RepetitionCounter 作用详解

    STM32 定时器中TIM_RepetitionCounter 作用详解执笔画红颜 红颜一笑一倾城 在 STM32 中有一个这个 TIM RepetitionCo 参数 如下 定时了 0 001s 然后在中断中计数 1000 次 点亮熄灭 LED 正常情况来说 led 会亮 1s 然后灭 1s 不断重复 当 TIM RepetitionCo 参数设置为 0 时 确实是 1s 当 TIM RepetitionCo 参数设置为 1 时 明显感觉到亮灭的时

    2026年3月17日
    2
  • linux的USB驱动:gadget

    linux的USB驱动:gadget

    2021年9月7日
    116
  • 取出字符串中数字的最大值

    取出字符串中数字的最大值取出字符串中数字的最大值

    2022年4月24日
    45
  • 智谱推出Zread.ai开发效率工具 搭载GLM-4.5大模型

    智谱推出Zread.ai开发效率工具 搭载GLM-4.5大模型

    2026年3月12日
    3
  • 黑客入门 | 什么是踩点[通俗易懂]

    黑客入门 | 什么是踩点[通俗易懂]踩点就是收集目标信息的技巧,通过踩点找寻你感兴趣的信息。《孙子兵法》曰:“知已知彼,百战不殆;不知彼而知己,一胜一负;不知彼不知己,每战必殆。”通过对目标进行有计划,有步骤的踩点,收集整理出一份关于该目标的信息安防现状完整剖析图。收集方面:因特网、内联网、远程访问、外联网因特网主要收集:域名、网络地址和子网、可以直接从因特网访问的各个系统的具体IP地址、已经被发现的各个系统上运行的TCP和…

    2022年5月15日
    112
  • 向下取整和向上取整的符号_python向上取整函数

    向下取整和向上取整的符号_python向上取整函数向上取整,运算称为Ceiling,用数学符号⌈⌉(上有起止,开口向下)表示,。向下取整,运算称为Floor,用数学符号⌊⌋(下有起止,开口向上)表示。注意,向上取整和向下取整是针对有浮点数而言的;若整数向上取整和向下取整,都是整数本身。四舍五入:更接近自己的整数;把小数点后面的数字四舍五入 即:如被舍去部分的头一位数字小于五,则舍去;如大于等于五,则被保留…

    2025年8月24日
    17

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号