zoukankan      html  css  js  c++  java
  • POI刷新数据后的函数(公式)更新问题

    使用POI将Excel模板中的数据进行更新,这应该是很常见的操作

    下面就贴上我的一小段代码

    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或者Office

    所以报表sheet中那些代入,那些引用,那些函数和公式,全部都不会有更新

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

    wb.setForceFormulaRecalculation(true);

    强制整个Excel在你打开WPS或者Office的一瞬间,重新计算更新一下函数公式

    接着又会碰到另一个问题

    如果我不打开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 = "";
    				}
    

      

  • 相关阅读:
    添加或删除项并动态记录项的值
    练习题。对DOM中document的深刻理解巩固
    document--文档中的操作,操作属性、操作样式、操作元素
    10.13DOM中document--文档1找到元素的方法,还有元素内容属性
    函数的定义,语法,二维数组,几个练习题
    10.11讲的内容总结
    js基础巩固练习
    10.9做的一个静态页面(巩固前面的内容)
    9.29学习的js基础
    9.28做的作业(企业名称静态网页)
  • 原文地址:https://www.cnblogs.com/newflydd/p/4926417.html
Copyright © 2011-2022 走看看