使用poi工具,下面的代码在本地环境都正常运行,new SXSSFWorkbook(new XSSFWorkbook(input)); 代码部署到linux 服务上,因为用的不是root 的用户去启动jar,在调用这段代码的时候,看到了权限不足的异常
通过log 定位到,是资源的问题:
class.getResourceAsStream(srcXlsPath);
getResourceAsStream方法的参数,如果最前面是正斜杆/,那么则从项目根目录开始查找,注意是项目根目录不是磁盘根目录。
用法为:App.class.getResourceAsStream("/com/xqxx/lncms/app.txt"),App这个类可以任意替换成其他类,对结果没有影响,因为都是从根目录开始查找。
如果不加正斜杆/,那么则从该方法的调用者class所在的目录查找。
用法为:App.class.getResourceAsStream("app.txt")//App.java和app.txt在同一个目录,App这个类不能随意替换成其他类
如果是在spring boot jar 包里面,这个路径怎么去理解:
在springboot项目中,一般会将一些配置文件放在resources文件夹下,
当java项目打成jar包,则无法以文件的形式直接获取resources中的文件,此时以流的形式获取,故此需要用getResourceAsStream这个方法
ExportUtil.class.getResourceAsStream("/exportExcelTemplate/ContractInfoWaitTemplate.xlsx")
就是获取resources 里面的 exportExcelTemplate/ContractInfoWaitTemplate.xlsx 文件
public void getSheet() {
try{
InputStream input = ExportUtil.class.getResourceAsStream(srcXlsPath);
if(input==null){
logger.info("模板文件:"+srcXlsPath+"不存在");
return;
}
if(WDWUtil.isExcel2003(srcXlsPath)){
wb = new HSSFWorkbook(input);
}
if(WDWUtil.isExcel2007(srcXlsPath)){
wb = new SXSSFWorkbook(new XSSFWorkbook(input));
}
sheet= wb.getSheet(sheetName);
}catch(Exception e){
logger.error("捕获异常",e);
}
}
回到问题的上来:
为什么会出现权限不足问题?检查了这个jar 是已经是不存在权限问题了,jar 已经是apps 777 的权限了,这样到底是那个地方的权限不够,因为模板文件是在jar 里面的,所以说不可能是模板文件的问题。
估计就是poi 内部调用了什么文件夹导致的,所以看看源代码
原因:
SXSSFWorkbook默认会在/tmp/poifiles/文件夹下创建临时文件。第一个用户创建了这个目录并运行成功了,其他用户在想往这个目录创建文件就会因为权限问题失败了。
比如我这里,是有人用root 第一次调用了这个poi 所以这个临时文件就是root 的了,
解决方案:
将/tmp/poifiles/目录权限设为777,或者是给这个临时文件修改拥有者
chown -R apps /tmp/poifiles
chmod -R 777 /tmp/poifiles
POI会通过System.getProperty(“java.io.tmpdir”)获取tmp目录的位置,可以通过修改这个改变临时文件生成的位置。