但是这些很少见。他们中的大多数看起来像这样:
=超链接(R246,“ ref to doc”)
or
= if(i257 =“#undef”,“ undefined”,超链接(u257,“ ref to doc”)) 不幸的是
XSSFHYPERLINK超链接= cell.gethyperlink();lways返回零。但是我可以从单元格中提取公式文本,并带有
Stringcellformula = cell.getCellformula();,因此我决定从公式中手动获取超链接。我为此创建了正则表达式:
Pattern pattern = Pattern.compile("HYPERLINK\\((.*?),");
Matcher matcher = pattern.matcher(cellFormula);
String val = matcher.group();
但获得异常
java.lang.illegalstateException:找不到匹配项有人可以指出我的正则是什么问题或提出一些更好的方法来获得这些超链接。
我不是建议使用正则表达式进行excel公式。即使您可以使用它,您的示例也将获得
"\"https://web.address/doc\""
或"R246"
或
"U257"
。第一个结果是可用的。 bu如何处理第二个结果和第三个结果?
完成示例:
import java.io.FileInputStream;
import org.apache.poi.ss.formula.*;
import org.apache.poi.ss.formula.ptg.*;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.*;
import org.apache.poi.ss.util.CellAddress;
public class ExcelHyperlinkDestinationFromFormula {
private static String getHyperlinkFormulaDestination(XSSFSheet sheet, String hyperlinkFormula) {
String result = "HyperlinkFormulaDestination not found";
XSSFEvaluationWorkbook workbookWrapper = XSSFEvaluationWorkbook.create((XSSFWorkbook) sheet.getWorkbook());
Ptg[] ptgs = FormulaParser.parse(hyperlinkFormula, workbookWrapper, FormulaType.CELL, sheet.getWorkbook().getSheetIndex(sheet));
for (int i = 0; i < ptgs.length; i++) {
//System.out.println(ptgs[i]);
if (ptgs[i] instanceof FuncVarPtg) {
FuncVarPtg funcVarPtg = (FuncVarPtg)ptgs[i];
//System.out.println(funcVarPtg);
if ("HYPERLINK".equals(funcVarPtg.getName())) {
int firstOperand = funcVarPtg.getNumberOfOperands();
Ptg firstOperandPtg = ptgs[i-firstOperand]; //Reverse Polish notation: first operand is number of operands before funcVarPtg
//System.out.println(firstOperandPtg);
if (firstOperandPtg instanceof StringPtg) {
result = ((StringPtg)firstOperandPtg).getValue();
} else if (firstOperandPtg instanceof RefPtg) {
Cell cell = sheet.getRow(((RefPtg)firstOperandPtg).getRow()).getCell(((RefPtg)firstOperandPtg).getColumn());
DataFormatter dataFormatter = new DataFormatter();
dataFormatter.setUseCachedValuesForFormulaCells(true);
result = dataFormatter.formatCellValue(cell);
} else if (firstOperandPtg instanceof FuncVarPtg) {
result = "HyperlinkFormulaDestination behind FuncVarPtg not parsed"; //ToDo
} else if (firstOperandPtg instanceof NamePtg) {
result = "HyperlinkFormulaDestination behind NamePtg not parsed"; //ToDo
}
}
}
}
return result;
}
public static void main(String[] args) throws Exception {
XSSFWorkbook workbook = (XSSFWorkbook)WorkbookFactory.create(new FileInputStream("./test.xlsx"));
XSSFSheet sheet = workbook.getSheetAt(0);
for (Row row : sheet) {
for (Cell cell : row) {
if (cell.getCellType() == CellType.FORMULA) {
CellAddress source = cell.getAddress();
String formula = cell.getCellFormula();
if (formula.toLowerCase().contains("hyperlink(")) {
System.out.println(source + "=" + formula);
String hyperlinkFormulaDestination = getHyperlinkFormulaDestination(sheet, formula);
System.out.println(hyperlinkFormulaDestination);
}
}
}
}
workbook.close();
}
}
代码应该能够获取示例的超链接公式目标OD。 Todos将扩展代码,以便能够解析功能和/或名称也是HYPERLINK
公式中的第一个操作数。