• java excel 刷新公式_POI刷新数据后的函数(公式)更新问题


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

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

    public class ModifyExcel {
    /**

    * @param fileNameExcel报表路径

    * @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{
    Workbookwb=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

    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 = "";

    }


    ————————————————
    版权声明:本文为CSDN博主「日本留学秋武老师」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    原文链接:https://blog.csdn.net/weixin_42512933/article/details/114308990

  • 相关阅读:
    <input type='date'>传到后台怎么接收
    @Conditionnal注解和拦截器
    docker安装nginx
    vue npm run build报错 npm ERR! missing script: build
    阳哥讲面试题(七)Redis五种基本类型,分布式锁
    阳哥讲面试题(六)AOP,循环依赖
    mysql建表报错(this is incompatible with sql_mode=only_full_group_by)
    阳哥讲面试题(五)各种锁,LockSupport,AQS
    SSM_CRUD新手练习(2)配置文件
    Mysql逻辑分层、存储引擎
  • 原文地址:https://www.cnblogs.com/javalinux/p/14788714.html
Copyright © 2020-2023  润新知