• 在开发过程中 常常读取excel的数据,一般excel第一行数据做为标题,而我碰到一个需求是标题不一定在第一行,而且标题还会出现竖向,横向合并等情况。又该怎么实现呢?请看下面分析

场景分析

  • 我们的需要的标题是 场景1 第一行数据:姓名,性别,年龄 等

  • 场景1 比较常见的excel第一行一般为标题:

  • 场景2 多行标题并且含有标题合并现象

  • 场景3 标题含有合并以及标题之间有几列是空格的情况

  • 场景4 (待实现)应该可以在excel指定列 如图标颜色的是需要的标题

实现分析

  • 借助工具 easyExcel
  • easyExcel 可以设置从第几行读取数据,我们只要知道标题所在的范围去解析标题
    比如:场景1 标题在第一行范围为A1:L1, 场景2 标题范围为 A10:N10

代码实现

  • 获取标题
/*** 获取excel的标题 适用于excel的标题所在行有合并单元格格式* @param file* @param headStartIndex 标题所在单元格行号(从0开始) eg:A1:B10, result:1* @param headEndIndex 标题所在单元格行号(从0开始) eg:A1:B10, result:10* @return*/
public static List<String> readExcelHead(MultipartFile file,int headStartIndex,int headEndIndex) {//表头List<String> headList = new ArrayList<>();Map<Integer,Object> headMap = new LinkedHashMap<>(16);try {EasyExcelFactory.read(file.getInputStream(), new AnalysisEventListener<Map<Integer, Object>>() {/*** 单次缓存的数据量*/public static final int BATCH_COUNT = 1000;/***临时存储*/private List<Map<Integer, Object>> cachedDataList =ListUtils.newArrayListWithExpectedSize(BATCH_COUNT);@Overridepublic void invoke(Map<Integer, Object> data, AnalysisContext context) {cachedDataList.add(data);if (cachedDataList.size() >= BATCH_COUNT) {saveData();// 存储完成清理 listcachedDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT);}}@Overridepublic void doAfterAllAnalysed(AnalysisContext context) {saveData();}private void saveData() {if (cachedDataList.size() > 0) {List<Map<Integer, Object>> subData = CollectionUtil.sub(cachedDataList, 0, headEndIndex - headStartIndex +1);for (int i = 0; i < subData.size(); i++) {Map<Integer, Object> dataMap = subData.get(i);for (int j = 0; j < dataMap.keySet().size(); j++) {if (ObjectUtil.isNotNull(dataMap.get(j))) {headMap.put(j,dataMap.get(j));}}}}}/*** 在转换异常 获取其他异常下会调用本接口。抛出异常则停止读取。如果这里不抛出异常则 继续读取下一行。** @param exception* @param context* @throws Exception*/@Overridepublic void onException(Exception exception, AnalysisContext context) {log.error("解析失败,但是继续解析下一行:{}", exception.getMessage());if (exception instanceof ExcelDataConvertException) {ExcelDataConvertException excelDataConvertException = (ExcelDataConvertException) exception;log.error("第{}行,第{}列解析异常,数据为:{}", excelDataConvertException.getRowIndex(),excelDataConvertException.getColumnIndex(), excelDataConvertException.getCellData());}}}).sheet().headRowNumber(headStartIndex).doRead();} catch (IOException e) {log.error("读取文件失败:{}", ExceptionUtil.stacktraceToString(e));}//返回数据跟excel标题顺序保持一致List<Integer> keyList = headMap.keySet().stream().sorted().collect(Collectors.toList());keyList.stream().forEach(key -> {headList.add(StrUtil.toString(headMap.get(key)));});return headList;}
  • 获取Excel内容
/*** 获取excel的内容 适用于excel的标题所在行有合并单元格格式* @param file* @param headStartIndex 标题所在单元格行号(从0开始) eg:A1:B10, result:1* @param headEndIndex 标题所在单元格行号(从0开始) eg:A1:B10, result:10* @return*/
public static List<Map<String, Object>> readExcel(MultipartFile file,int headStartIndex,int headEndIndex) {List<Map<String, Object>> mapList = CollUtil.newArrayList();//表头Map<Integer, String> importHeads = new HashMap<>();try {EasyExcelFactory.read(file.getInputStream(), new AnalysisEventListener<Map<Integer, Object>>() {/*** 单次缓存的数据量*/public static final int BATCH_COUNT = 1000;/***临时存储*/private List<Map<Integer, Object>> cachedDataList =ListUtils.newArrayListWithExpectedSize(BATCH_COUNT);@Overridepublic void invoke(Map<Integer, Object> data, AnalysisContext context) {cachedDataList.add(data);if (cachedDataList.size() > 0) {List<Map<Integer, Object>> subData = CollectionUtil.sub(cachedDataList, 0, headEndIndex -headStartIndex +1);for (int i = 0; i < subData.size(); i++) {Map<Integer, Object> dataMap = subData.get(i);for (int j = 0; j < dataMap.keySet().size(); j++) {if (ObjectUtil.isNotNull(dataMap.get(j))) {importHeads.put(j,StrUtil.toString(dataMap.get(j)));}}}}if (cachedDataList.size() >= BATCH_COUNT) {//转换表头executeMapHeader();// 存储完成清理 listcachedDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT);}}@Overridepublic void doAfterAllAnalysed(AnalysisContext context) {executeMapHeader();}/*** 在转换异常 获取其他异常下会调用本接口。抛出异常则停止读取。如果这里不抛出异常则 继续读取下一行。** @param exception* @param context* @throws Exception*/@Overridepublic void onException(Exception exception, AnalysisContext context) {log.error("解析失败,但是继续解析下一行:{}", exception.getMessage());if (exception instanceof ExcelDataConvertException) {ExcelDataConvertException excelDataConvertException = (ExcelDataConvertException) exception;log.error("第{}行,第{}列解析异常,数据为:{}", excelDataConvertException.getRowIndex(),excelDataConvertException.getColumnIndex(), excelDataConvertException.getCellData());}}private void executeMapHeader() {if (ObjectUtil.isNotNull(importHeads)) {if (CollUtil.isEmpty(mapList)) {cachedDataList = CollUtil.sub(cachedDataList,headEndIndex-headStartIndex,cachedDataList.size());}cachedDataList.forEach(data -> {LinkedHashMap<String, Object> dataMap = new LinkedHashMap<>(16);//返回的数据跟excel导入的数据顺序保持一致List<Integer> keyList = importHeads.keySet().stream().sorted().collect(Collectors.toList());keyList.stream().forEach(key -> {dataMap.put(importHeads.get(key), data.get(key));});mapList.add(dataMap);});}}}).sheet().headRowNumber(headStartIndex).doRead();} catch (IOException e) {log.error("读取文件失败:{}", ExceptionUtil.stacktraceToString(e));}mapList.remove(0);return mapList;}

展示结果

  • 读取头结果

  • 读取数据结果

获取Excel数据 (支持多标题,以及标题横向,竖向合并等情况)相关推荐

  1. 链接服务器——获取EXCEL数据

    测试目的:验证利用链接服务器.分布式查询获取EXCEL中的数据 测试环境: Microsoft SQL Server 2005 - 9.00.3080.00 (X64)   Enterprise Ed ...

  2. C# 设置Excel数据自适应行高、列宽的2种情况

    Excel表格中,由于各种数据的复杂性,可能存在单元格中的数据字号大小.数据内容长度不一而出现,列宽过宽.过窄或者行高过大.过小的问题.常见的解决方法是调整行高.列宽.在Microsoft Excel ...

  3. python获取excel数据制作有文字和图表的报告_如何用Python绘制学术报告图表?

    原标题:如何用Python绘制学术报告图表? 作者:ExcelTing 原文:http://cnblogs.com/excelting/p/6507680.html 全文约 3581 字,读完可能需要 ...

  4. python获取excel数据并移动到新表

    思路: 1.操作本地excel获取数据: 2.对数据进行操作并存储(看是否去重) 3.将处理后的数据写入新表 操作: 1.操作本地excel获取数据: 后面添加新表的时候,需要添加下面几个步骤,来保证 ...

  5. python获取excel数据进行判断输出结果到excel,如何使用python xlrd/xlwt从一个excel工作簿提取数据并输出到另一个excel工作簿?...

    我正在为xlutils.xlrd和xlwt创建一个名为excel functions的类,最终我可能会创建一个库.如果你有兴趣帮我做一个删除工作表的功能. 您可能希望转向openpyxl和/或pyex ...

  6. php获取excel数据并添加数据库,如何使用phpexcel读取数据并将其插入数据库?

    小编典典 使用PHPExcel库读取Excel文件并将数据传输到数据库中 // Include PHPExcel_IOFactory include 'PHPExcel/IOFactory.php'; ...

  7. Python获取excel数据

    方法一:可以采用pandas的read_excel功能 import pandas as pd getdata=pd.read_excel('C:/文件夹索引/文件名.xlsx',sheet_name ...

  8. BODY background=自适应大小_C# 设置Excel数据自适应行高、列宽的2种情况

    Excel表格中,由于各种数据的复杂性,可能存在单元格中的数据字号大小.数据内容长度不一而出现列宽过宽.过窄或者行高过大.过小的问题.常见的解决方法是调整行高.列宽.在Microsoft Excel中 ...

  9. pandas读取excel文档,每列标题及标题下的内容,总行数,总列数

    pandas读取excel文档,每列标题及标题下的内容,总行数,总列数 import pandas'''''' # file_path为excel的文件路径 def read_excel(file_p ...

最新文章

  1. 程序员跳槽获25K月薪,只因他给面试官看了这6000行代码
  2. spring单元测试报错:Failed to load ApplicationContext 的解决方法
  3. router-link标签学习
  4. 论OD最原始的用途------找程序BUG
  5. 2020年,.NET Core起飞在即,最强日志分析ELK还不会?
  6. follow 开源项目关于NoClassDefFoundError错误的解决方法
  7. request获取url的参数编码问题
  8. Qt可执行程序写入版本信息
  9. octotree插件 --- 将 Github 项目代码以树形格式展示
  10. abp框架(aspnetboilerplate)设置前端报错显示
  11. 工科学生考研能选择计算机专业么,考研应该如何选择学校和专业
  12. Html5 Egret游戏开发 成语大挑战(五)界面切换和数据处理
  13. javascript 经常会用到的东西
  14. sql语句中having的用法
  15. QuartusII-项目工程的时序仿真
  16. 【学习笔记】C51 keil v4 流水灯简单代码的编写
  17. 如何去掉图片上的logo
  18. stm32单片机按键消抖、长按、多击终极解决方案
  19. AIOps对监控报警架构的挑战
  20. ch340t电路_CH340电路设计 - ch340g典型应用电路

热门文章

  1. Linux02目录结构
  2. mysql nvl nvl2_nvl nvl2 case 分组函数 | 学步园
  3. Java面试题全集(1)
  4. 苹果开发者帐号 共享的方法
  5. 视频剪辑怎么做?有什么创作技巧?
  6. 小红点文化艺术中心:超有格调的教育网站
  7. uni-app学习笔记之163邮箱自动发邮件
  8. 用VSCode开发Spark应用
  9. (算法练习)蓝桥杯——饮料换购
  10. Java:HashMap实现原理