需求: 我的JDK版本是JDK17,需要用JavaFX 11和EasyExcel开发一个窗体应用。
由于IDEA限制,JavaFX 11以上版本的项目创建必须要求JDK版本高于JDK9,而JDK9引入了模块化,从而遇到了一系列问题。下面我将一步步重现我的问题,并给出解决方案。
一、POM下添加EasyExcel依赖
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
<version>3.1.5</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.24</version>
</dependency>
<dependency>
<groupId>org.apache.xmlbeans</groupId>
<artifactId>xmlbeans</artifactId>
<version>5.1.1</version>
</dependency>
</dependencies>
注意lombok需要idea额外下载插件lombok才能使用。导入依赖后,需要在"module-info.java"文件中引入模块。
二、module-info.java下添加模块
module com.example.javafx_maven {
requires javafx.controls;
requires javafx.fxml;
requires java.desktop;
requires lombok;
requires easyexcel.core;
opens com.example.javafx_maven to javafx.fxml;
exports com.example.javafx_maven;
}
三、编写测试代码读取Excel文件
package com.example.javafx_maven;
import com.alibaba.excel.annotation.ExcelProperty;
import lombok.Data;
@Data
public class Product {
@ExcelProperty("物料编码")
String material_code;
}
Excel表:
表中有6条属性,测试类使用"物料编码"属性进行测试。
读取Excel文件
String filename = "D:\\workspaces\\javafx_workspace\\gk_poms\\data\\吉曼编码文件.xlsx";
EasyExcel.read(filename, Product.class, new AnalysisEventListener() {
@Override
public void invoke(Object o, AnalysisContext analysisContext) {
System.out.println((Product) o);
}
@Override
public void doAfterAllAnalysed(AnalysisContext analysisContext) {
System.out.println("完毕");
}
}).sheet().doRead();
运行报错
Caused by: java.lang.IllegalAccessException: module
com.example.javafx_maven does not open com.example.javafx_maven to
unnamed module @7f60ea4f
按照英文翻译过来是: 我们自己的模块没有向未命名模块开放
解决办法也简单,直接在IDEA 中配置 VM OPTION 让我们包的代码对所有未命名模块开放。
--add-opens com.example.javafx_maven/com.example.javafx_maven=ALL-UNNAMED
然后再次运行,又报了个新的错误:
Caused by: java.lang.IllegalAccessError: superclass access check failed:
class com.example.javafx_maven.Product$$BeanMapByEasyExcelCGLIB$$837da033
(in module com.example.javafx_maven) cannot access class
com.alibaba.excel.support.cglib.beans.BeanMap (in unnamed module
@0x307558ca) because module com.example.javafx_maven does not read
unnamed module @0x307558ca
按照英文翻译过来是: 超类访问失败,无法访问alibaba.excel.support,因为我们自己的模块没有读取未命名模块
解决办法也简单,再添加一条 VM OPTION 让我们的模块读取所有未命名模块。
--add-reads com.example.javafx_maven=ALL-UNNAMED
两条 VM OPTION 中间用空格隔开
再次运行
成功读取数据。
折腾了一天终于把EasyExcel模块化跑起来了,但是我已经不需要了哈哈哈。时间催得紧,直接用POI手写数据解析器做完了。