如何从Excel文件中提取外部引用的列表
我正在为(不断增长的)非结构化的excel文档集合build立一个自动化处理系统。 该集合包含old-school .xls
文件和新的.xlsx
文件。 在我的基于Java的解决scheme中,我已经使用Apache POI工具包来分析文档。
目前尚未解决的一个挑战是如何识别文档之间的链接以便绘制依赖关系。 我还没有弄清楚如何方便地提取外部引用列表。 对于.xlsx
文件,我有一个解决方法,将文件解压缩,并打开包含引用的xml文件。 这可以工作,但对于大型文档集合来说是低效的,也不能为.xls
文件提供解决scheme。
我更喜欢有一个不依赖Microsoft Office或相关库的解决scheme,因为解决scheme需要在Linux环境中运行。
POI能够以某种方式做到这一点? 如果没有,我会进一步调查哪些图书馆/工具/区域?
最终,我通过POI源代码工作,并使用reflection来获取引用的外部工作簿的列表。 以下代码已经过testing,可以在POI版本3.11testing版上使用。
注意那些想在这里使用这个方法的人的代码:因为它处理的是非公开的方法和类,它可能会改变,并可能在未来破坏。
private LinkedList<String> getWorkbookReferences(HSSFWorkbook wb) { LinkedList<String> references = new LinkedList<>(); try { // 1. Get InternalWorkbook Field internalWorkbookField = HSSFWorkbook.class.getDeclaredField("workbook"); internalWorkbookField.setAccessible(true); InternalWorkbook internalWorkbook = (InternalWorkbook) internalWorkbookField.get(wb); // 2. Get LinkTable (hidden class) Method getLinkTableMethod; getLinkTableMethod = InternalWorkbook.class.getDeclaredMethod("getOrCreateLinkTable", null); getLinkTableMethod.setAccessible(true); Object linkTable = getLinkTableMethod.invoke(internalWorkbook, null); // 3. Get external books method Method externalBooksMethod = linkTable.getClass().getDeclaredMethod("getExternalBookAndSheetName", int.class); externalBooksMethod.setAccessible(true); // 4. Loop over all possible workbooks int i = 0; String[] names; try { while( true) { names = (String[]) externalBooksMethod.invoke(linkTable, i++) ; if (names != null ) { references.add(names[0]); } } } catch ( java.lang.reflect.InvocationTargetException e) { if ( !(e.getCause() instanceof java.lang.IndexOutOfBoundsException) ) { throw e; } } } catch (NoSuchFieldException | NoSuchMethodException | SecurityException | InvocationTargetException | IllegalAccessException e) { e.printStackTrace(); } return references; }