为了账号安全,请及时绑定邮箱和手机立即绑定

Apache Poi 参考另一个工作簿识别公式

Apache Poi 参考另一个工作簿识别公式

跃然一笑 2023-01-05 15:34:55

我有一个工作簿,我必须清除所有对其他工作簿的引用。我目前正在尝试解析单元格公式,以检查它们是否引用了任何 excel 文件。

为此,我使用这条线

cell.getCellFormula().matches(".*\\[.*\\.xls[xm]?\\].*")

这个问题是,单元格在 XML 格式中看起来像这样:

 <c r="K64" s="2128">
    <f>[5]Segments!$AS$7/Annual!AF38</f>
    <v>0.0</v>
 </c>

如您所见,该公式实际上不包含.xls, '.xlsx' 或根本不包含.xlsm。据我所知[5],它表示一个共享字符串,它包含实际路径以及公式的实际值。

现在可以说并将正则表达式更改为.*\\[\d+\\].*,但我认为这很容易出错。此外,我认为并非每个外部引用都像这样。

所以我的问题是:

如何识别引用外部工作簿的公式?


如果你有任何问题随时问。

编辑:

我准备了一个示例 excel 文件来展示这个问题。可在workupload.com下载


查看完整描述

1 回答

?
慕的地10843

TA贡献1574条经验 获得超8个赞

动态添加外部(跨工作簿)引用中显示的方法绝对是可行的方法。遍历所有公式标记,如果其中一个具有外部工作表索引,则此公式引用外部工作表。

使用您上传的文件的示例:

import org.apache.poi.ss.usermodel.*;

import org.apache.poi.ss.formula.*;

import org.apache.poi.ss.formula.ptg.*;

import org.apache.poi.ss.formula.EvaluationWorkbook.ExternalSheet;

import org.apache.poi.hssf.usermodel.HSSFWorkbook;

import org.apache.poi.hssf.usermodel.HSSFEvaluationWorkbook;

import org.apache.poi.xssf.usermodel.XSSFWorkbook;

import org.apache.poi.xssf.usermodel.XSSFEvaluationWorkbook;


import java.io.FileInputStream;


public class ExcelReadExternalReference {

    public static void main(String[] args) throws Exception {


        String filePath = "TestExternalLinks.xlsx";

        // String filePath = "TestExternalLinks.xls";


        Workbook workbook = WorkbookFactory.create(new FileInputStream(filePath));


        EvaluationWorkbook evalWorkbook = null;

        if (workbook instanceof HSSFWorkbook) {

            evalWorkbook = HSSFEvaluationWorkbook.create((HSSFWorkbook) workbook);

        } else if (workbook instanceof XSSFWorkbook) {

            evalWorkbook = XSSFEvaluationWorkbook.create((XSSFWorkbook) workbook);

        }


        Sheet sheet = workbook.getSheetAt(0);

        EvaluationSheet evalSheet = evalWorkbook.getSheet(0);


        for (Row row : sheet) {

            for (Cell cell : row) {

                if (cell.getCellType() == CellType.FORMULA) {

                    String cellFormula = cell.getCellFormula();

                    System.out.println(cellFormula);


                    EvaluationCell evaluationCell = evalSheet.getCell(cell.getRowIndex(), cell.getColumnIndex());

                    Ptg[] formulaTokens = evalWorkbook.getFormulaTokens(evaluationCell);

                    for (Ptg formulaToken : formulaTokens) {

                        int externalSheetIndex = -1;

                        if (formulaToken instanceof Ref3DPtg) {

                            Ref3DPtg refToken = (Ref3DPtg) formulaToken;

                            externalSheetIndex = refToken.getExternSheetIndex();

                        } else if (formulaToken instanceof Area3DPtg) {

                            Area3DPtg refToken = (Area3DPtg) formulaToken;

                            externalSheetIndex = refToken.getExternSheetIndex();

                        } else if (formulaToken instanceof Ref3DPxg) {

                            Ref3DPxg refToken = (Ref3DPxg) formulaToken;

                            externalSheetIndex = refToken.getExternalWorkbookNumber();

                        } else if (formulaToken instanceof Area3DPxg) {

                            Area3DPxg refToken = (Area3DPxg) formulaToken;

                            externalSheetIndex = refToken.getExternalWorkbookNumber();

                        }


                        if (externalSheetIndex >= 0) {

                            System.out.print("We have extrenal sheet index: " + externalSheetIndex

                                    + ". So this formula refers an external sheet in workbook: ");


                            ExternalSheet externalSheet = null;

                            if (workbook instanceof HSSFWorkbook) {

                                externalSheet = evalWorkbook.getExternalSheet(externalSheetIndex);

                            } else if (workbook instanceof XSSFWorkbook) {

                                externalSheet = evalWorkbook.getExternalSheet(null, null, externalSheetIndex);

                            }

                            String linkedFileName = externalSheet.getWorkbookName();

                            System.out.println(linkedFileName);


                        }

                    }

                }

            }

        }


        workbook.close();

    }


}


查看完整回答
反对 回复 2023-01-05

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信