Is it feasible to remove workbook links (external references) using Apache POI in Java? I understand that Excel provides a way to break links to external workbooks manually, but is there a way to programmatically identify and remove external links (formulas or named ranges referencing other workbooks) using Apache POI?
public static void breakExternalLinks(String inputFilePath, String outputFilePath) throws IOException {
// Load the Excel workbook
FileInputStream fis = new FileInputStream(inputFilePath);
XSSFWorkbook workbook = new XSSFWorkbook(fis);
// Break external links in formulas by replacing them with their current values
breakFormulaLinks(workbook);
// Remove external references in named ranges
removeExternalNamedRanges(workbook);
// Save the updated workbook
FileOutputStream fos = new FileOutputStream(outputFilePath);
workbook.write(fos);
// Close resources
fos.close();
fis.close();
workbook.close();
}
private static void breakFormulaLinks(XSSFWorkbook workbook) {
FormulaEvaluator evaluator = workbook.getCreationHelper().createFormulaEvaluator();
evaluator.setIgnoreMissingWorkbooks(true); // Ignore missing external workbooks
for (Sheet sheet : workbook) {
for (Row row : sheet) {
for (Cell cell : row) {
if (cell.getCellType() == CellType.FORMULA) {
try {
// Evaluate the formula and replace it with the calculated value
CellValue cellValue = evaluator.evaluate(cell);
switch (cellValue.getCellType()) {
case BOOLEAN:
cell.setCellValue(cellValue.getBooleanValue());
break;
case NUMERIC:
cell.setCellValue(cellValue.getNumberValue());
break;
case STRING:
cell.setCellValue(cellValue.getStringValue());
break;
case ERROR:
cell.setCellErrorValue(cellValue.getErrorValue());
break;
case BLANK:
cell.setBlank();
break;
}
} catch (Exception e) {
System.out.println("Error evaluating formula in cell " + cell.getAddress() + ": " + e.getMessage());
}
}
}
}
}
}
private static void removeExternalNamedRanges(XSSFWorkbook workbook) {
// Collect all named ranges with external references
List<XSSFName> namesToRemove = new ArrayList<>();
// Iterate over all named ranges in the workbook
for (XSSFName name : workbook.getAllNames()) {
// Check if the name refers to an external workbook (contains a [ symbol)
if (name.getRefersToFormula() != null && name.getRefersToFormula().contains("[")) {
namesToRemove.add(name);
}
}
// Remove all external references from named ranges
for (XSSFName name : namesToRemove) {
workbook.removeName(name);
}
}
Here the images attached for facing issue
5