JXLS读Excel文件至POJO
实际应用中经常会遇到解析excel文件获取数据至java对象。有很多第三方库可以解析excel文件,这里我们使用JXLS框架,通过JXLS几乎只需几行代码就能轻松解析excel文件。JXLS提供jxls-reader模块用于读取xls文件并填充java bean,使用xml配置输入excel文件如何解析成对应数据。
1、增加依赖
compile group: 'org.jxls', name: 'jxls-reader', version: '2.0.5'
jxls依赖poi,这里无需显示声明poi。
2、JXLS三个关键部件
(1)JXLS-Reader
XLS-Reader基于org.apache.commons.digester3.Digester.RederBuilder类创建,是JXLS中的核心组件。通过Reder builder我们使用JXLS映射文件至输入流(excel数据的输入流),然后提供给相应的java 对象,所以我们必须提供JXLS映射文件和excel文件。
(2)JXLS 映射文件
解析excel文件,我们需要创建简单xml文件,用于定义excel文件和pojo直接的属性映射关系。然后JXLS框架循环excel文件行并填充pojo。本文示例中映射文件如下:
<?xml version="1.0" encoding="ISO-8859-1"?>
<workbook>
<worksheet name="Sheet1">
<section startRow="0" endRow="0" />
<loop startRow="1" endRow="1" items="players" var="player" varType="com.dataz.pojo.Player">
<section startRow="1" endRow="1">
<mapping row="1" col="0">player.name</mapping>
<mapping row="1" col="1">player.rank</mapping>
<mapping row="1" col="2">player.sports</mapping>
<mapping row="1" col="3">player.country</mapping>
</section>
<loopbreakcondition>
<rowcheck offset="0">
<cellcheck offset="0" />
</rowcheck>
</loopbreakcondition>
</loop>
</worksheet>
</workbook>
我们使用loop标记定从第一行和第一列开始,因为我们不需要读头信息,仅需要读每一行并映射对应com.dataz.pojo.Player对象。在loop中使用var属性告诉JXLS使用该pojo映射excel行数据。同时需要定义break条件用于结束循环。
注意:worksheet也可以根据索引进行映射,修改为。section和loop标记中的row和col索引值都是从0开始。
(3) 实际excel文件
提供需要解析的excel文件。示例如下:
name | rank | sports | country |
---|---|---|---|
tommy | B1 | football | india |
jack | B2 | badminton | japan |
marry | B3 | cricket | china |
3、解析过程
首先定义pojo类:
@Setter
@Getter
@ToString
public class Player {
private String name;
private String sports;
private int rank;
private String country;
}
对象解析PlayerParser类:
import com.dataz.pojo.Player;
import org.jxls.reader.ReaderBuilder;
import org.jxls.reader.XLSReader;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @author Jack
*/
public class PlayerParser {
private String mappingFile;
private String excelFile;
private PlayerParser() {
}
private static PlayerParser init() {
return new PlayerParser();
}
private void setExternalFileLocation(String mappingFile, String excelFile) {
this.mappingFile = mappingFile;
this.excelFile = excelFile;
}
public static void parseAndDisplay(String mappingFile, String excelFile) throws Exception {
PlayerParser parser = init();
parser.setExternalFileLocation(mappingFile, excelFile);
List<Player> players = parser.doConfigtask();
parser.display(players);
}
private void display(List<Player> players) {
for (Player player : players) {
System.out.println(player);
}
}
private List<Player> doConfigtask() throws Exception {
final XLSReader xlsReader = ReaderBuilder.buildFromXML(new File(mappingFile));
final List<Player> result = new ArrayList<>();
final Map<String, Object> beans = new HashMap<>(3);
beans.put("players", result);
InputStream inputStream = new BufferedInputStream(new FileInputStream(excelFile));
xlsReader.read(inputStream, beans);
return result;
}
}
xml、excel文件都可以从文件或流中加载,使解析应用更自由。
4、单元测试
import lombok.extern.log4j.Log4j2;
import org.junit.Test;
import java.net.URL;
@Log4j2
public class PlayerParserTest {
private String xmlPath = getFileFromURL("read-xml/player.xml");
private String xlsxPath = getFileFromURL("xlsx/player.xlsx");
@Test
public void parseAndDisplay() throws Exception {
PlayerParser.parseAndDisplay(xmlPath, xlsxPath);
}
private String getFileFromURL(String path) {
URL url = this.getClass().getClassLoader().getResource(path);
log.debug("url path :{}", url);
assert url != null;
return url.getPath();
}
}
xml和excel都保存在resouce目录下,索引定义getFileFromURL方法获取文件路径。
5、总结
JXLS提供jxls-reader模块实现excel文件解析,相比于使用poi更简单,无需考虑底层实现,仅需要关心业务关心。