• 一、前言
  • 二、技术准备
  • 三、实现思路
    • 3.1、如何表示每个单元格数据?
    • 3.2、如果处理单元格之间的关系?
    • 3.3、如何包装“卫龙”辣条?
  • 四、实现代码的核心部分
  • 五、注意

一、前言

先看效果:左图的excel表中的五级目录的数据,转成了右边的JSON格式。 表格总共有739行,转成JSON后,足足有3461行,之前采用人工逐个录入,花了整整一天时间,眼睛都看花了,准确率也需要多次核对才放心。 表格中数据这次有了较大改动,想到之前手工录入的痛苦,搜了几个转换工具也未能满足需求,只能自己撸代码实现了。

二、技术准备

2.1、操作表格的API,用的是apche的 POI

2.2、数据类型 JSONArray和JSONObject,需导入相应的jar包。

三、实现思路

3.1、如何表示每个单元格数据?

{"text": "二级目录","children": [{"text": "三级目录"}]}

由JSON数据的格式可以看出,每读取一个目录数据,都可以看成一个JSONObject,JSONObject有两个键值对,text代表目录的名字、children代表子目录。 一个父目录可以有多个子目录,所以children用的JSONArray去表示。

3.2、如果处理单元格之间的关系?

在我们的场景中,合并单元格,是一个父目录,代表还有子目录。而POI读取表格的顺序是:先读行、再读每行中的每一列。 所以遇到合并单元格,要判断出来,并且计算出合并单元格的起始行、结束行的行号,这样,只要在起始行、结束行之间的读出的数据都是从属于该父目录的子目录,并且这些数据要缓存起来。

3.3、如何包装“卫龙”辣条?

就好比流水线上包装的卫龙辣条,如何规定一个包装袋只装一根辣条,那么流水上的机器工作起来就很简单,只要读取一根辣条,将这根辣条加入包装袋里封口进行了。这就是对应没有合并单元格的情况。依次读取就行了。 如果规定一个包装袋里要装4根辣条,那么包装袋读取了一根辣条时不会封口,会停在流水线上等待并且计数,等到第4跟读取完成(即读到第4行),才封口完成包装(完成JSONArray的组装)。

四、实现代码的核心部分

4.1、处理一级目录的代码示例:

// 第1列 -- 一级目录
HSSFCell cell1 = row.getCell(0);
if (cell1 != null && !"".equals(cell1)) {
String cellValue1 = row.getCell(0).getStringCellValue();
Result mergedRegion1 = isMergedRegion(sheet, i, 0);
if (mergedRegion1.merged == false) {// 不是合并的if (!"".equals(cellValue1)) {rowobj1.put("text", cellValue1);if (jsonArray2.size() > 0) {rowobj1.put("children", jsonArray2);}jsonArray.add(rowobj1);rowobj2.clear();jsonArray2.clear();rowobj1.clear();}} else {if (i == mergedRegion1.startRow - 1) {rowobj1.put("text", cellValue1);}if (i == mergedRegion1.endRow - 1) {rowobj1.put("children", jsonArray2);jsonArray.add(rowobj1);rowobj2.clear();jsonArray2.clear();rowobj1.clear();}
}
}

4.2、判断是否是合并单元格:

// 判断是否是合并单元格
private static Result isMergedRegion(HSSFSheet sheet, int row, int column) {
int sheetMergeCount = ((org.apache.poi.ss.usermodel.Sheet) sheet).getNumMergedRegions();
for (int i = 0; i < sheetMergeCount; i++) {CellRangeAddress range = ((org.apache.poi.ss.usermodel.Sheet) sheet).getMergedRegion(i);int firstColumn = range.getFirstColumn();int lastColumn = range.getLastColumn();int firstRow = range.getFirstRow();int lastRow = range.getLastRow();if (row >= firstRow && row <= lastRow) {if (column >= firstColumn && column <= lastColumn) {return new Result(true, firstRow + 1, lastRow + 1, firstColumn + 1, lastColumn + 1);}}
}
return new Result(false, 0, 0, 0, 0);
}

详细代码见github: https://github.com/pluscai/excelToJson

五、注意

5.1、本意是直接转成json文件,实际情况时在控制台打印出来了,黏贴到json文件里,格式化下就行了。

5.2、如果excel文件是xlsx后缀的,可以打开后另存为xls格式,再转换。

json转excel_手写JAVA实现个性化业务的Excel转JSON,效率提高99.99%相关推荐

  1. 【XML和Java】手写Java程序引用xsd验证xml

    一.首先要有一个xml文件和xsd文件 (1) database.conf.xml <?xml version="1.0" encoding="UTF-8" ...

  2. 安全系列之——手写JAVA加密、解密

    其他文章: 安全系列之--手写JAVA加密.解密 安全系列之--数据传输的完整性.私密性.源认证.不可否认性 安全系列之--主流Hash散列算法介绍和使用 安全系列之--RSA的公钥私钥有多少人能分的 ...

  3. 视频教程-手写Java框架系列教程之一反射(含配套资料)-Java

    手写Java框架系列教程之一反射(含配套资料) 张长志技术全才.擅长领域:区块链.大数据.Java等.10余年软件研发及企业培训经验,曾为多家大型企业提供企业内训如中石化,中国联通,中国移动等知名企业 ...

  4. java linkedlist底层_手写Java LinkedList核心源码

    上一章我们手写了ArrayList的核心源码,ArrayList底层是用了一个数组来保存数据,数组保存数据的优点就是查找效率高,但是删除效率特别低,最坏的情况下需要移动所有的元素.在查找需求比较重要的 ...

  5. 手写java_手写java锁

    手写非公平可重入锁 公平锁:多个线程按照申请锁的顺序去获得锁,线程会直接进入队列去排队,永远都是队列的第一位才能得到锁. 优点:所有的线程都能得到资源,不会饿死在队列中. 缺点:吞吐量会下降很多,队列 ...

  6. 【JVM】手写Java虚拟机-02 搜索class文件

    目录 环境 可能遇到的问题 开始 执行 参考 环境 操作系统:Windows 10 IDE:IntelliJ IDEA 2019.1 x64 JDK:Java 11.0.8 项目管理工具:apache ...

  7. 1000题!!阿里P8架构师手写“Java面试宝典”带你横扫全网

    序言 很多同学学习Java并发一头扎进源码,最后头破血流,无功而返.横看成岭侧成峰,远近高低各不同.学习要始终从不同的视角来看待问题.学习并发亦是如此,需要通过理论远看轮廓,然后通过源码近看明细. 今 ...

  8. java中map转为json数据_Java技术-将java中Map类型数据转化为json数据并以Ajax形式返回...

    Java技术-将java中Map类型数据转化为json数据并以Ajax形式返回html 1.自定义工具类(简单易用)-下面是我写的一个简单的工具类前端 package com.test.util; i ...

  9. Java中普通字符串转json,老司机帮您java中如何将字符串转成json

    电脑现已成为我们工作.生活和娱乐必不可少的工具了,在使用电脑的过程中,可能会遇到java中如何将字符串转成json的问题,如果我们遇到了java中如何将字符串转成json的情况,该怎么处理怎么才能解决 ...

最新文章

  1. Synergy 共享键盘和鼠标
  2. Spark2.x 与 Spark1.x 关系
  3. 从零单排之玩转Python安全编程(II)
  4. tomcat如何查找请求资源的?
  5. WebStrom 使用淘宝镜像
  6. 安徽二本大学计算机排名,2018安徽大学排名 安徽有哪些大学
  7. vs2013 MFC入门
  8. 不想做外包,当不了药神,AI公司如何才能走通制药这条路?
  9. element-ui table列表自定义表头,修改列标题样式、添加tooltip
  10. hd630 linux内核,Sandy Bridge集成显卡总算支持Linux 开源性能实测
  11. Windows XP的图标结构
  12. 查询某个网址的服务器IP
  13. 联接(CROSS JOIN、JOIN、OUTER JOIN)
  14. c++中多个线程使用同一个函数
  15. HBase的TTL介绍
  16. 散——TIPS(C语言)
  17. 2020年鼠年正月十五 祝贺元宵节快乐
  18. 来说一说毕达哥拉斯定理
  19. windows系统中环境系统变量和用户变量的区别
  20. 汽车几种变速器的结构特点

热门文章

  1. app能不能跳转外部h5_轻羽微信小程序和H5的区别在哪里?主要有三点
  2. 【连载】如何掌握openGauss数据库核心技术?秘诀二:拿捏执行器技术(1)
  3. 文档丨Oracle 20c 概念手册
  4. MongoDB DBA常用的NoSQL语句(全)
  5. 7个连环问揭开java多线程背后的弯弯绕
  6. LiteOS内核源码分析:静态内存Static Memory
  7. 基础知识 | 对目标检测认识及理解
  8. 大数据下单集群如何做到2万+规模?
  9. 【华为云技术分享】云图说 | ContainerOps推出灰度发布模式,助力企业落地容器DevOps最佳实践
  10. 【华为云技术分享】从零搭建一个灰度发布环境