简体   繁体   English

使用 Apache POI 编辑和现有 Excel 文件后,使用的公式会消失

[英]After using Apache POI to edit and existing Excel file, the formulas that use does cells disappear

I am using Apache POI to edit an existing file.我正在使用 Apache POI 来编辑现有文件。 This file contains multiple formulas that use the numbers that will be inputted through Apache.该文件包含多个公式,这些公式使用将通过 Apache 输入的数字。 And this is where I run into problems, when a number is inputted and that cell is being used in a formula, the file gets corrupted and the formula disappears.这就是我遇到问题的地方,当输入一个数字并且在公式中使用该单元格时,文件被损坏并且公式消失了。 Here the formulas for the 0 are C7+D7, C8+D8, etc. Here the formulas for the 0 became normal 0, the formulas got lost.这里 0 的公式是 C7+D7、C8+D8 等。这里 0 的公式变成了正常的 0,公式丢失了。

Here is the code I used to write to the excel file:这是我用来写入 excel 文件的代码:

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

import org.apache.poi.EncryptedDocumentException;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.usermodel.WorkbookFactory;


public class write {
    public static void main(String[] args) {
        String excelFilePath = "C:\\Users\\jose_\\IdeaProjects\\writeExcel\\src\\JavaBooks.xlsx";

        try {
            FileInputStream inputStream = new FileInputStream(new File(excelFilePath));
            Workbook workbook = WorkbookFactory.create(inputStream);

            Sheet sheet = workbook.getSheetAt(0);
            /*Cell cell2Update = sheet.getRow(1).getCell(3); // This updates a specific cell: row 0 cell 3
            cell2Update.setCellValue(49);*/

            Object[][] bookData = {
                    {2, 17},
                    {3, 27},
                    {4, 33},
                    {5, 44},
            };

            // int rowCount = sheet.getLastRowNum(); // Gets the last entry
            int rowCount = 5;

            for (Object[] aBook : bookData) {
                Row row = sheet.createRow(++rowCount);

                int columnCount = 1;
                int lote = 1;

                Cell cell = row.createCell(columnCount);
                //cell.setCellValue(rowCount); // This sets the index for each entry
                cell.setCellValue(lote);

                for (Object field : aBook) {
                    cell = row.createCell(++columnCount);
                    if (field instanceof String) {
                        cell.setCellValue((String) field);
                    } else if (field instanceof Integer) {
                        cell.setCellValue((Integer) field);
                    }
                }

            }

            inputStream.close();

            FileOutputStream outputStream = new FileOutputStream("C:\\Users\\jose_\\IdeaProjects\\writeExcel\\src\\JavaBooks.xlsx");
            workbook.write(outputStream);
            workbook.close();
            outputStream.close();

        } catch (IOException | EncryptedDocumentException ex) {
            ex.printStackTrace();
        }

    }
}

Is there a way to work around this or do I need to set all the formulas again through Apache POI?有没有办法解决这个问题,还是我需要通过 Apache POI 再次设置所有公式?

You get the error because using code line Row row = sheet.createRow(++rowCount);您收到错误是因为使用代码行Row row = sheet.createRow(++rowCount); you always create new empty rows and so you remove all cells in those rows.您总是创建新的空行,因此您删除了这些行中的所有单元格。 So you are also removing the cells containing the formulas.因此,您还删除了包含公式的单元格。 Doing so you are damaging the calculation chain.这样做会破坏计算链。 That's what the Excel GUI tells you with the messages.这就是Excel GUI通过消息告诉您的内容。

You should not do this.你不应该这样做。 Instead you always should try to get the rows first using Sheet.getRow .相反,您应该始终尝试首先使用Sheet.getRow获取行。 Only if that returns null then you need to create the row.仅当返回null时,您才需要创建该行。

...
//Row row = sheet.createRow(++rowCount);
Row row = sheet.getRow(rowCount); if (row == null) row = sheet.createRow(rowCount); rowCount++;
...

Additional please read Recalculation of Formulas .另外请阅读公式的重新计算 So after changing cells referenced in formulas, do always either workbook.getCreationHelper().createFormulaEvaluator().evaluateAll();因此,在更改公式中引用的单元格后,请始终执行workbook.getCreationHelper().createFormulaEvaluator().evaluateAll(); or delegate re-calculation to Excel using workbook.setForceFormulaRecalculation(true);或使用workbook.setForceFormulaRecalculation(true);将重新计算委托给Excel . .

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM