Java使用Spire.XLS导出Excel报IllegalAccessError问题咨询
异常根因
触发的java.lang.IllegalAccessError是Java 9及以上版本引入的模块化系统(JPMS)访问限制导致。你使用的Free Spire XLS组件依赖了JDK内部非公开API sun.security.action.GetPropertyAction,该类属于java.base模块的内部实现,高版本JDK默认不向第三方模块开放该类的访问权限,因此抛出访问错误。
当前Spire方案的解决方法
- 添加JVM启动参数开放访问权限
启动程序时追加以下VM参数,手动将受限的内部包导出给Spire模块:
IDEA运行时可在Run/Debug配置的VM options栏填入该参数;命令行启动JAR包时,将参数拼接在--add-exports java.base/sun.security.action=spire.xls.freejava命令后即可。 - 切换运行环境到JDK 1.8
Java 8未引入模块化系统,不存在内部API访问拦截规则,使用JDK8运行项目可直接规避该错误。 - 升级Free Spire XLS到最新发布版本
新版本组件一般会完成高版本JDK适配,替换掉对已封禁内部API的依赖,从根源解决兼容性问题。
Java导出数组到Excel的其他实现方案
1. Apache POI
Apache POI是Java生态操作Excel的主流开源方案,完全免费无商业使用限制,支持xls、xlsx全格式,可实现样式、公式、图表等所有Excel特性,适合需要复杂格式处理的场景。
示例代码:
import org.apache.poi.ss.usermodel.Row; import org.apache.poi.ss.usermodel.Sheet; import org.apache.poi.ss.usermodel.Workbook; import org.apache.poi.xssf.usermodel.XSSFWorkbook; import java.io.FileOutputStream; import java.io.IOException; public void exportArrayToExcel(String[] col1Data, String[] col2Data) throws IOException { try (Workbook workbook = new XSSFWorkbook(); FileOutputStream outputStream = new FileOutputStream("dictionary.xlsx")) { Sheet sheet = workbook.createSheet("Sheet1"); int maxRow = Math.max(col1Data.length, col2Data.length); for (int i = 0; i < maxRow; i++) { Row row = sheet.createRow(i); if (i < col1Data.length) { row.createCell(0).setCellValue(col1Data[i]); } if (i < col2Data.length) { row.createCell(1).setCellValue(col2Data[i]); } } workbook.write(outputStream); } }
2. EasyExcel
EasyExcel是基于POI优化的开源Excel处理工具,重写了大文件处理的内存逻辑,万行级数据导出内存占用仅几MB,不会出现OOM问题,API封装简单,适合业务系统中常规数据导出场景。
示例代码:
import com.alibaba.excel.EasyExcel; import com.alibaba.excel.annotation.ExcelProperty; import lombok.Data; import java.util.ArrayList; import java.util.List; @Data public class ExcelRowData { @ExcelProperty("第一列") private String firstCol; @ExcelProperty("第二列") private String secondCol; } public void exportArrayToExcel(String[] col1Data, String[] col2Data) { List<ExcelRowData> dataList = new ArrayList<>(); int maxRow = Math.max(col1Data.length, col2Data.length); for (int i = 0; i < maxRow; i++) { ExcelRowData row = new ExcelRowData(); if (i < col1Data.length) { row.setFirstCol(col1Data[i]); } if (i < col2Data.length) { row.setSecondCol(col2Data[i]); } dataList.add(row); } EasyExcel.write("dictionary.xlsx", ExcelRowData.class) .sheet("Sheet1") .doWrite(dataList); }
3. CSV纯文本导出
如果只需要导出纯数据、不需要样式/多Sheet等复杂特性,可以直接生成CSV格式文件,该格式可被Excel直接打开,不需要引入任何第三方依赖,性能最高。注意导出时处理好内容中的逗号、换行符转义即可。
示例代码:
import java.io.FileWriter; import java.io.IOException; public void exportArrayToCsv(String[] col1Data, String[] col2Data) throws IOException { try (FileWriter writer = new FileWriter("dictionary.csv")) { int maxRow = Math.max(col1Data.length, col2Data.length); for (int i = 0; i < maxRow; i++) { String c1 = i < col1Data.length ? col1Data[i].replace(",", ",").replace("\n", " ") : ""; String c2 = i < col2Data.length ? col2Data[i].replace(",", ",").replace("\n", " ") : ""; writer.write(c1 + "," + c2 + "\r\n"); } } }
内容的提问来源于stack exchange,提问作者Mutastak
相关产品推荐
相关产品推荐

