最近專案裡,我都開始改用NPOI來處理Excel檔案的讀寫輸出,感覺上比Excel DOM、OLE DB for JET、甚至CSV法來得穩定輕巧,而NPOI功能的齊全程度更是讓我驚喜連連。

今天寫了個簡單套版程式要實現類似以下的概念:

Template.xls中有寫好的公式計算兩個欄位的相加值,A3 = SUM(A1:A2)

我的程式會開啟Template.xls,將A1改成3、A2改成4,另存為Result.xls。(關於NPOI的基本介紹,可以參考MSDN上的中文教學)

using (FileStream fsIn = new FileStream("Template.xls", FileMode.Open))
{
    //開啟Excel
    HSSFWorkbook workbook = new HSSFWorkbook(fsIn);
    fsIn.Close();
    //取得第一個工作表
    Sheet sheet = workbook.GetSheetAt(0);
    //將第一列第一欄(A1)設成3
    sheet.GetRow(0).GetCell(0).SetCellValue(3);
    //將第二列第一欄(A2)設成3
    sheet.GetRow(1).GetCell(0).SetCellValue(4);
    //另存為Result.xls                
    using (FileStream fsOut = new FileStream("Result.xls", FileMode.Create))
    {
        workbook.Write(fsOut);
        fsOut.Close();
    }
}

預期在Result.xls,A3 應該 = SUM(A1:A2) = 3 + 4 = 7才對,結果...

我發現NPOI產出的文件,SUM(A1:A2)仍是停留舊值3,要重新指定一次A3公式,才會更新為7。

花了一陣子,我才找出NPOI控制自動重算公式結果的屬性: Sheet.ForceFormulaRecalculation。

    //將第一列第一欄(A1)設成3
    sheet.GetRow(0).GetCell(0).SetCellValue(3);
    //將第二列第一欄(A2)設成3
    sheet.GetRow(1).GetCell(0).SetCellValue(4);
    //要求公式重算結果
    sheet.ForceFormulaRecalculation = true;
    //另存為Result.xls                
    using (FileStream fsOut = new FileStream("Result.xls", FileMode.Create))
    {
        workbook.Write(fsOut);
        fsOut.Close();
    }

既然花了時間才找到,就留個記錄幫助有類似需求的朋友吧!


Comments

# by lijinan

太感謝你了。這個問題困擾了我一天!NPOI官方支持的力度不夠呀。找了一天才解決

# by 李政忠

小弟的需求是必須資料異動之後,在不開啟Excel的情形下,就得取得公式重新計算的值,使用版主大人的方式行不通,後來爬文得到下述方法,供作參考。 Dim eva As HSSFFormulaEvaluator = New HSSFFormulaEvaluator(workbook) Dim cell_F17 As NPOI.SS.UserModel.ICell = eva.EvaluateInCell(sheet.GetRow(16).GetCell(5)) Response.Write(String.Format("F17={0}!!", cell_F17.NumericCellValue))

# by 小米

太感謝了~~~~~~~~~~~~~~~

# by 月夜微醺

简直了,感激不尽!!!

# by hybirx

太感谢了,找了好久都想完全写入了,十分感谢

# by 猫出没

太感谢了!我一开始找的是用的: //HSSFFormulaEvaluator e = new HSSFFormulaEvaluator(workbook); //ICell cell02 = sheet.GetRow(0).GetCell(2); //cell02 = e.EvaluateInCell(cell02); 但是觉得挺奇葩的,看完楼主,瞬间大亮啊!!!

Post a comment


45 + 27 =