一、运行环境
- windows10
- IDEA 2022
- JDK 8
- Maven 3.8.6
- Apache POI 5
- fastjson2
二、需求描述
写一个功能,任意json生成excel,每个数组都单独生成一个sheet。
三、实现思路
参考资料:Apache POI 使用教程
主要实现思路: 使用支持Java对象与JSON对象、字符串互相转换的fastjson,以及支持Java将JSON转化Excel的库 apache-poi
Excel表格关键结构:
- Workbook 工作台,相当于一个 excel文件
- sheet,一个excel文件中的表格页面,可能有多个
- row,所在sheet中的行
- cel,所在sheet中所在行的列
- value,所在单元格的值
- cel,所在sheet中所在行的列
- row,所在sheet中的行
JSON转换的几种情形与实现思路:
情形一:普通的单层结构,多个JSON对象
{
"班级A" : [{
"文章":"课文1",
"作者":"李白"
},
{
"文章":"课文2",
"作者":"小李"
},
{
"文章":"课文2",
"作者": "小明"
}]
}
导出结果:
当我们使用fastjson遍历JSONObject时,每次读取到的都是单个{ } 所包含的对象,比如:
{
"文章":"课文1",
"作者":"李白"
}
这种情况下,我们在Excel的Sheet中的行是确定的,比如这里就是第二行(第一行是列名),行根据遍历的顺序确定,而列则是不确定的,在这里有 “文章”,“作者” 这两个列,但是一开始这两个列是不存在的。这里则确定文章在第一列,作者按第二列(默认升序排序)。
当遍历下一个对象时,我们可能遇到旧的列,也可能遇到新的列,比如:
{
"文章":"课文2",
"作者":"李白",
"出版日期": "2022年7月6日"
}
这时,我们需要知道"文章" 和 “作者” 在第几列,同时也要知道 “出版日期” 应该在第几列,否则就不能确定唯一的单元格,将 JSON的value存储进去。
这里可以使用 Map<String, Integer> map
来记录列名以及下标。
在遍历对象时,key是列名,value则是单元格该填的值,如果 map.get(key) 的结果是空的,说明该列不存在,则需要创建,如果存在,那么可以创建单元格的对象,将值填入即可。
情形二:嵌套结构,JSON数组的嵌套
{
"班级A":[
{
"学号":"A01",
"语文":[
{
"文章":"课文1",
"作者":"李白"
},
{
"文章":"课文2",
"作者":"小李"
},
{
"文章":"课文2",
"作者": "小明"
}
],
"数学":"130"
},
{
"学号":"A02",
"语文":"130",
"数学":"135"
}
],
}
实现效果:
这里相比之前的情况复杂了一些,主要的就是需要再次创建一个新的 sheet,这意味着需要使用递归完成创建,于是我们可以将之前那种情形的代码实现封装成一个方法,比如createSubSheet(),在遍历JSON对象时,如果value值是一个JSONAarray,那么就再次调用createSubSheet()这个方法,只要使用同一个Workbook对象,表示同一个excel文件,就能满足这个需求了。
四、实现代码
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>groupId</groupId>
<artifactId>poi_demo</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>5.2.2</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.9</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>2.0.7</version>
</dependency>
</dependencies>
</project>
JSONToExcelUtil.java
package cn.uni;
import com.alibaba.fastjson2.JSON