java在线读取Excel内容

时间:2023-02-16 18:59:46

本示例采用Springboot的Thymeleaf做前台展示,核心还是java代码,想了解Thymeleaf的可以点击​​《SpringBoot入门十六,添加Thymeleaf模板支持》​​进行入门学习,这里就只做关于Excel内容读取的记录了。

1、pom.xml添加相关引用

<!-- 开启thymeleaf模板引擎支持 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>

<!-- Excel文件处理配置开始 -->
<!-- 引入poi依赖,Excel2003使用 -->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>4.0.0</version>
</dependency>

<!-- 引入poi-ooxml依赖,Excel2007+使用 -->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>4.0.1</version>
</dependency>
<!-- Excel文件处理配置结束 -->

2、配置文件添加thymeleaf信息

只看核心代码可以忽略此处

# ----------------项目基本配置---------------
## 端口号
#server.port=8080
## 设置项目路径.默认是“/”
#server.servlet.context-path=/qfxUploadExcelDemo

#----------------视图层thymeleaf配置---------------
## 是否开启缓存
spring.thymeleaf.cache=false
## 设置不严格的html
spring.thymeleaf.mode=HTML
## 编码格式
spring.thymeleaf.encoding=utf-8
## 前缀,也就是模板存放的路径,默认是templates,可以不用配置
#spring.thymeleaf.prefix=/view/
## 后缀
spring.thymeleaf.suffix=.html

3、Service

 核心处理就是这里了

import java.io.IOException;
import java.io.InputStream;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;

import org.apache.poi.hssf.usermodel.HSSFWorkbook;
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;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import com.qfx.modules.test.service.TestSer;

@Service
public class TestSerImpl {

/**
* 获取Excel信息
* 获取的列数信息以第一行的列数为准,比如说第一行有5列,那么所有行都是取5列的数据信息
*/
public Map<String, List<String[]>> readExcel(MultipartFile file) {
Map<String, List<String[]>> mapData = new TreeMap<String, List<String[]>>();
Workbook wb = null;
List<String[]> sheetDataList = null;
String[] cellArr = null;

try {
// 1.获取的是文件的完整名称,包括文件名称+文件拓展名
String filePath = file.getOriginalFilename();
// 2.获取输入流
InputStream stream = file.getInputStream();

// 3.根据Excel的文件格式生成对应版本的Workbook
if (filePath.endsWith(".xls")) {
wb = new HSSFWorkbook(stream);
} else if (filePath.endsWith(".xlsx")) {
wb = new XSSFWorkbook(stream);
} else {
System.out.println("未知文件格式,不是.xls和.xlsx格式[" + filePath + "]");
}
if (null == wb) {
mapData.put("没有获取到文件", null);
return mapData;
}

Iterator<Sheet> sheetIt = wb.sheetIterator();
// 4.获取工作簿中所有的工作表
while (sheetIt.hasNext()) {
sheetDataList = new LinkedList<String[]>();

// 5.获取一个Sheet页面
Sheet sheet = sheetIt.next();

// 6.指定要获取的列总数,以第一行的列数为准(表头)
int columnCount = sheet.getRow(0).getLastCellNum();

// 7.循环获取行数据
for (Row row : sheet) {
cellArr = new String[columnCount];
// 8.循环获取每个单元格数据信息
for (int i = 0; i < columnCount; i++) {
cellArr[i] = (null == row.getCell(i)) ? "" : row.getCell(i).toString();
}
// 9.添加行数据到集合中
sheetDataList.add(cellArr);
}
// 10.添加Sheet页的数据集合到map中
mapData.put(sheet.getSheetName(), sheetDataList);
}
wb.close();
stream.close();
} catch (IOException e) {
e.printStackTrace();
}

return mapData;
}

/**
* 获取Excel信息(以第一行的列数为准)
* 不限定每行的列数,只要是行中的有效数据,都可以获取到
*/
@Override
public Map<String, List<String[]>> readExcelExt(MultipartFile file) {
Map<String, List<String[]>> mapData = new TreeMap<String, List<String[]>>();
Workbook wb = null;
List<String[]> sheetDataList = null;
String[] cellArr = null;
int cellCount;

try {
// 1.获取的是文件的完整名称,包括文件名称+文件拓展名
String filePath = file.getOriginalFilename();
// 2.获取输入流
InputStream stream = file.getInputStream();

// 3.根据Excel的文件格式生成对应版本的Workbook
if (filePath.endsWith(".xls")) {
wb = new HSSFWorkbook(stream);
} else if (filePath.endsWith(".xlsx")) {
wb = new XSSFWorkbook(stream);
} else {
System.out.println("未知文件格式,不是.xls和.xlsx格式[" + filePath + "]");
}
if (null == wb) {
mapData.put("没有获取到文件", null);
return mapData;
}

Iterator<Sheet> sheetIt = wb.sheetIterator();
// 4.获取工作簿中所有的工作表
while (sheetIt.hasNext()) {
sheetDataList = new LinkedList<String[]>();

// 5.获取一个Sheet页面
Sheet sheet = sheetIt.next();
// 6.循环获取行数据
for (Row row : sheet) {
// 7.获取最后一个不为空的列是第几个(建议使用)
cellCount = row.getLastCellNum();
cellArr = new String[cellCount];

// 8.循环获取每个单元格数据信息
for (int i = 0; i < cellCount; i++) {
cellArr[i] = (null == row.getCell(i)) ? "" : row.getCell(i).toString();
}
// 9.添加行数据到集合中
sheetDataList.add(cellArr);
}
// 10.添加Sheet页的数据集合到map中
mapData.put(sheet.getSheetName(), sheetDataList);
}
wb.close();
stream.close();
} catch (IOException e) {
e.printStackTrace();
}

return mapData;
}

4、Controller

import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.ModelAndView;

import com.qfx.modules.test.service.impl.TestSerImpl;

@Controller
@RequestMapping("test")
public class TestCtl {

@Autowired
TestSerImpl testSer;

@RequestMapping("main")
public String firstView(){
return "main";
}

/**
* 获取Excel固定列数量的信息
*
* @param excelFile
* @return
*/
@RequestMapping("upload/excel")
@ResponseBody
public ModelAndView uploadExcel(MultipartFile excelFile) {
Map<String, List<String[]>> excelDataMap = testSer.readExcel(excelFile);

ModelAndView modelAndView = new ModelAndView("list");
modelAndView.addObject("remark", "根据表头获取固定列数据");
modelAndView.addObject("excelDataMap", excelDataMap);

return modelAndView;
}

/**
* 获取Excel固定所有列的信息
*
* @param excelFile
* @return
*/
@RequestMapping("upload/excelExt")
@ResponseBody
public ModelAndView uploadExcelExt(MultipartFile excelFile) {
Map<String, List<String[]>> excelDataMap = testSer.readExcelExt(excelFile);

ModelAndView modelAndView = new ModelAndView("list");
modelAndView.addObject("remark", "获取所有列数据");
modelAndView.addObject("excelDataMap", excelDataMap);

return modelAndView;
}
}

5、页面

5.1 测试页

main.html

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>main</title>
</head>
<body>
<form name="form1" action="/test/upload/excel" method="post" enctype="multipart/form-data" >
<fieldset>
<legend>Excel上传(根据表头获取固定列数据)</legend>
请选择上传文件:<input type="file" name="excelFile" /><br/><br/>
<input type="reset" name="reset" value="重置" />
<input type="submit" name="button" value="提交" />
</fieldset>
</form>

<form name="form2" action="/test/upload/excelExt" method="post" enctype="multipart/form-data" >
<fieldset>
<legend>Excel上传(获取所有列数据)</legend>
请选择上传文件:<input type="file" name="excelFile" /><br/><br/>
<input type="reset" name="reset" value="重置" />
<input type="submit" name="button" value="提交" />
</fieldset>
</form>
</body>
</html>

页面效果:

根据要获取的列数据类型选择不同模块->选择文件->提交

java在线读取Excel内容

5.2 展示页

list.html

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>list</title>
</head>
<body>
<table align="center" width="50%" border="0">
<th th:text="${remark}" />
</table>
<table align="center" width="50%" border="1" cellpadding="5" cellspacing="0" bordercolor="lime" th:each="map,state:${excelDataMap}">
<caption th:text="${map.key + '信息'}"></caption>
<tr th:each="item,state:${map.value}">
<th:block th:if="${state.count == 1}">
<td th:text="编号"></td>
</th:block>
<th:block th:unless="${state.count == 1}">
<td th:text="${(state.count -1) +'/'+ (state.size - 1)}"></td>
</th:block>
<th:block th:each="value,valueState:${item}">
<td th:text="${value}"></td>
</th:block>
</tr>
</table>
</body>
</html>
5.2.2 固定列数据展示
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>list</title>
</head>
<body>
<table align="center" width="50%" border="0">
<th th:text="${remark}" />
</table>
<table align="center" width="50%" border="1" cellpadding="5" cellspacing="0" bordercolor="lime" th:each="map,state:${excelDataMap}">
<caption th:text="${map.key + '信息'}"></caption>
<tr th:each="item,state:${map.value}">
<th:block th:if="${state.count == 1}">
<td th:text="编号"></td>
</th:block>
<th:block th:unless="${state.count == 1}">
<td th:text="${(state.count -1) +'/'+ (state.size - 1)}"></td>
</th:block>
<th:block th:each="value,valueState:${item}">
<td th:text="${value}"></td>
</th:block>
</tr>
</table>
</body>
</html>

Excel内容

java在线读取Excel内容

页面展示内容:

仅展示和表头长度相同列的数据

java在线读取Excel内容

5.2.3 所有列数据展示

Excel内容

java在线读取Excel内容

页面展示内容:

展示所有列的数据

java在线读取Excel内容