POI刷新數據後的函數(公式)更新問題

使用POI將Excel模板中的數據進行更新,這應該是很常見的操做java

下面就貼上個人一小段代碼數據庫

public class ModifyExcel {
	
	/**
	 * @param fileName	Excel報表路徑
	 * @param sheetName Excel中須要修改的sheet名
	 * @param modify_from	從哪個座標點開始刷新數據
	 * @param crs	從Oracle中讀取出來的緩存數據集
	 * @throws Exception
	 */
	public void doModify(String fileName,String sheetName,int[] modify_from,CachedRowSet crs) throws Exception{
		Workbook	wb=WorkbookFactory.create(new FileInputStream(fileName));
		Sheet sheet=wb.getSheet(sheetName);
		
		int i=0;
		while(crs.next()){	
			if(sheet.getRow(i+modify_from[0])==null)
				sheet.createRow(i+modify_from[0]);
			for(int j=0;j<crs.getMetaData().getColumnCount();j++){
				Cell cell=sheet.getRow(i+modify_from[0]).getCell(j+modify_from[1]);
				if(cell==null)
					cell=sheet.getRow(i+modify_from[0]).createCell(j+modify_from[1]);
				
				String content=crs.getString(j+1);
				try{
					cell.setCellValue(Double.parseDouble(content));
				}catch(Exception e){
					cell.setCellValue(content);
				}
				
			}
			i++;
		}
		
		FileOutputStream fout = new FileOutputStream(fileName);
		wb.write(fout);
		fout.flush();
		fout.close();
		
		wb.close();	
	}
}

這一段代碼是使用POI將從數據庫中取到的結果集更新到報表中的一個隱藏sheet中去緩存

然而遇到一個問題函數

隱藏的sheet做爲數據源,爲多個非隱藏的報表sheet提供基礎數據,也就是說Excel中還有不少sheet是要調用這個隱藏sheet中的數據的測試

使用POI將數據源的sheet更新後,你的Excel模板並無觸發任何的數據修改事件,由於你自己並無打開WPS或者Officelua

因此報表sheet中那些代入,那些引用,那些函數和公式,所有都不會有更新orm

除非你在  wb.write(fout);  以前加上一句blog

wb.setForceFormulaRecalculation(true);事件

強制整個Excel在你打開WPS或者Office的一瞬間,從新計算更新一下函數公式get

接着又會碰到另外一個問題

若是我不打開WPS或者Office,一直不打開,那在單純的Excel文件裏,那些報表的函數公式會更新嗎?

答案是否認的

想作個這個測試很簡單,先在隱藏sheet中修改數據源,而後不打開WPS或者Office

再一次使用POI去讀這個文件,將讀到的公式數據輸出,你會發現他們仍是原來的值,並無由於數據源的變化而從新計算

通過博主的不斷研究,終於發現若是要在不打開WPS或者Office的狀況下,更新完數據源後強制全部sheet中的公式從新計算

須要對指定的Cell進行以下操做:

wb.getCreationHelper().createFormulaEvaluator().evaluateFormulaCell(cell);

博主最終將這行代碼添加在讀取公式單元格的操做中,在讀的時候強制計算新值

實現代碼以下:

                   // 設置文本
				String strCell = "";
				switch (cells[i][j].getCell().getCellType()) {
				case HSSFCell.CELL_TYPE_NUMERIC:										
					strCell = String.valueOf(cells[i][j].getCell().getNumericCellValue());
					break;
				case HSSFCell.CELL_TYPE_STRING:
					strCell = cells[i][j].getCell().getStringCellValue();
					break;
				case HSSFCell.CELL_TYPE_BOOLEAN:
					strCell = String.valueOf(cells[i][j].getCell().getBooleanCellValue());
					break;
				case HSSFCell.CELL_TYPE_FORMULA:
					//剛寫入的數據沒法及時更新,須要人爲打開WPS或者Office才能更新
					//使用evaluateFormulaCell對函數單元格進行強行更新計算
					wb.getCreationHelper().createFormulaEvaluator().evaluateFormulaCell(cells[i][j].getCell());
					
					try {
						strCell = String.valueOf(cells[i][j].getCell().getNumericCellValue());
					} catch (IllegalStateException e) {
						strCell = String.valueOf(cells[i][j].getCell().getRichStringCellValue());
					}
					break;
				default:
					strCell = "";
				}
相關文章
相關標籤/搜索