POI可以說是目前Java裏面操作Excel唯一的選擇。好用,但也有問題,比如操作大數據量的.xlsx
,那速度令人崩潰,雖然有有SXSSFSheet,效率很高,但對寫入並不很有好,很多操作都無法實現。
以上並不是本文重點:),本文主要記錄本人在使用POI來操作Excel,並進行公式計算時遇到的一點問題。首先POI並不支持所有的Excel函數(如:DATEDIF),並且有些函數即便支持,但和Excel中函數的表現可能並不一致(如:FV)。
看到這兩個函數有人可能大概能猜到我要做的是個什麼功能了,有一個公式超級複雜的銀行投資收益試算表,我保證90%的人看了都會頭疼。
表中公式是寫好的(不知道哪個大神寫的),我要做的是首先填上一些基礎的參數,然後根據公式計算結果,導出一個新的Excel,聽起來好像不復雜,但是有些計算公式POI並不支持(我也不可能搞清楚所有公式,然後用代碼算),所以就有了這篇短文。
POI支持的函數
FunctionEval.getSupportedFunctionNames().forEach(name->System.out.println(name));
POI不支持的函數
FunctionEval.getNotSupportedFunctionNames().forEach(name->System.out.println(name));
函數註冊
FunctionEval.registerFunction("name", func);
POI允許用戶自己實現函數,但是隻能是一個真實的函數(如DATEDIF),這也很好理解,因爲我們不能隨便製造一個函數,這樣Excel也不認識。但,凡事就怕但是,POI不允許覆蓋一個POI已經實現的函數。這就有點悲催了,因爲我發現有一個函數,POI的實現並不能滿足我當前的需求,又不能覆蓋,這可怎麼辦,只能簡單粗暴的複製源碼來改了。
我說的這個函數就是OFFSET
,可能是爲了兼容.xls
,POI裏面最大允許的偏移列不能超過0xFF
,也就是255
,但是.xlsx
最大允許列是16384
。這就很尷尬了,目前我只有改源碼的方法,不知道看到這篇文章的大神,有沒有其它更好的辦法,請不吝賜教。
Offset類:
private static final int LAST_VALID_ROW_INDEX = 0xFFFF; private static final int LAST_VALID_COLUMN_INDEX = 0xFF;