1

I am using Apache POI to create new XSSFWorkbook from an existing one, after updating some values. Suppose I have two worksheets (Lets say: worksheet A & B) in my existing workbook. Worksheet B has some cell reference from Worksheet A. IF i modify those cell values of worksheet A and save them as a new workbook, corresponding cell values of worksheet B should be updated too. But it doesn't. How can i update them programmatically? . Thank you.

My code:

public  void createExcel(ClientData cd) throws FileNotFoundException, IOException, InvalidFormatException{
            // create a new file
        double[] dataHolder1= cd.getFinalData1(),  param1 = cd.getRecord1Param();
        double[] dataHolder2 = cd.getFinalData2(), param2 = cd.getRecord2Param();
        double[] ncv = cd.getNcv();
        String[] pname = cd.getName();
            Workbook workbook = new XSSFWorkbook(OPCPackage.open(new FileInputStream("template/mncv.xlsx"))); // or sample.xls
            //CreationHelper createHelper = workbook.getCreationHelper();
            Sheet s=workbook.getSheetAt(0);

            int counter = dataHolder1.length + param1.length +param2.length+dataHolder2.length;//+ param1.length + param2.length;
//            r = s.getRow(0);
//            r.getCell(0).setCellValue("Param1");
//            r.getCell(1).setCellValue("Record1");
//            r.getCell(2).setCellValue("Param2");
//            r.getCell(3).setCellValue("Record2");

            int i;
            for(i=0;i<counter;i++){
                if(i<param1.length){
                    for(int j=0;j<param1.length;j++){
                        r = s.getRow(i);
                        r.getCell(0).setCellValue(param1[j]);
                        i++;
                    }
                }else if(i<dataHolder1.length+param1.length && i>=param1.length){

                    for(int j=0;j<dataHolder1.length;j++){
                        r = s.getRow(i);
                        r.getCell(0).setCellValue(dataHolder1[j]);
                        i++;
                    }

                }else if(i<dataHolder1.length+param1.length+param2.length && i>=dataHolder1.length+param1.length){
                    for(int j=0;j<param2.length;j++){
                        r = s.getRow(i);
                        r.getCell(0).setCellValue(param2[j]);
                        i++;
                    }
                }else{
                    for(int j=0;j<dataHolder2.length;j++){
                        r = s.getRow(i);
                        r.getCell(0).setCellValue(dataHolder2[j]);
                        i++;
                    }
                }

//                if(i<=param1.length){
//                    r.getCell(0).setCellValue(param1[i-1]);
//                    r.getCell(2).setCellValue(param2[i-1]);
//
//                }
                // r.getCell(0).setCellValue(param1[i]);
                 //r.getCell(3).setCellValue(dataHolder2[i-1]);
                i--;
            }
            for(int k=0;k<ncv.length;k++){
                r = s.getRow(i);
                r.getCell(0).setCellValue(ncv[k]);
                i++;
            }

            s = workbook.getSheetAt(1);

            s.getRow(2).getCell(5).setCellValue(pname[0]+" "+pname[1]+" "+pname[2]);
            s.getRow(3).getCell(5).setCellValue(cd.getAge());
            s.getRow(4).getCell(5).setCellValue(cd.getGender());


 try (FileOutputStream out = new FileOutputStream("workbook.xlsx")) { 
     //WorkbookEvaluator we = new WorkbookEvaluator(workbook); 

            workbook.write(out);     
            out.close();
          XSSFFormulaEvaluator.evaluateAllFormulaCells((XSSFWorkbook) workbook);

        }catch(Exception e){
            System.out.println(e);
        }
4

3 回答 3

2

Excel 文件格式缓存公式计算的结果,使打开文件更快。这意味着当您完成对文件的更改后,您需要评估所有公式单元格以更新其缓存值。(否则,当您在 Excel 中加载文件时,几乎在所有情况下,它仍会显示旧值,直到您进入该单元格)

幸运的是,Apache POI 提供了执行此操作的代码,有关详细信息,请参阅公式评估文档。(您可以选择仅重新计算某些公式,如果您只知道那些单元格已更改,或者执行所有操作)

于 2013-07-11T10:50:59.270 回答
0

对于任何单元格,例如“B5”,在运行时,

cell.getReference(); 

将为您提供单元格引用(例如......它将返回“B5”)

cell.getReference().toString().charAt(0); 

将为您提供列参考(如果当前单元格为 B5,将为您提供“B”)。现在

cell.getRowIndex(); 

或 cell.getReference().toString().charAt(1);

会给你行索引。现在您有了目标单元格的引用。只需将这些字符替换为您已经创建的引用即可。这将更新单元格引用。

于 2013-07-11T07:58:17.233 回答
0

以下解决方案对我有用

wb.setForceFormulaRecalculation(true);
// replace "wb" with your HSSFWorkbook/XSSFWorkbook object
于 2020-03-05T04:57:24.013 回答