From 9a0d34dc43d87a13dbe29d5b414180bd56609901 Mon Sep 17 00:00:00 2001 From: Greg Woolsey Date: Fri, 28 Jul 2017 18:01:36 +0000 Subject: [PATCH] Deleting a sheet did not delete table parts and relations. Deleting a table needs to also delete any queryTable relations and parts. Previous behavior didn't result in documents Excel complained about, but left dead entries in the ZIP structure, which made it bigger and bugged me. This change does not attempt to delete query connection definitions, as those aren't referenced as relations, and don't have a usage counter to ensure we only delete them if there are no other references. In my samples I had query tables on multiple sheets using the same connection definition, and wanted to delete only one sheet/table but leave others. git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1803317 13f79535-47bb-0310-9956-ffa450edef68 --- .../apache/poi/xssf/usermodel/XSSFSheet.java | 32 +++++++++++++++++++ .../apache/poi/xssf/usermodel/XSSFTable.java | 13 +++++++- .../poi/xssf/usermodel/XSSFWorkbook.java | 5 +++ 3 files changed, 49 insertions(+), 1 deletion(-) diff --git a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFSheet.java b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFSheet.java index b358a93cfd..ec51fbde48 100644 --- a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFSheet.java +++ b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFSheet.java @@ -3957,6 +3957,24 @@ public class XSSFSheet extends POIXMLDocumentPart implements Sheet { return new ArrayList(tables.values()); } + /** + * Remove table references and relations + * @param t table to remove + */ + public void removeTable(XSSFTable t) { + long id = t.getCTTable().getId(); + Map.Entry toDelete = null; + + for (Map.Entry entry : tables.entrySet()) { + if (entry.getValue().getCTTable().getId() == id) toDelete = entry; + } + if (toDelete != null) { + removeRelation(getRelationById(toDelete.getKey()), true); + tables.remove(toDelete.getKey()); + toDelete.getValue().onTableDelete(); + } + } + @Override public XSSFSheetConditionalFormatting getSheetConditionalFormatting(){ return new XSSFSheetConditionalFormatting(this); @@ -4396,6 +4414,20 @@ public class XSSFSheet extends POIXMLDocumentPart implements Sheet { XSSFIgnoredErrorHelper.addIgnoredErrors(ctIgnoredError, ref, ignoredErrorTypes); } + /** + * called when a sheet is being deleted/removed from a workbook, to clean up relations and other document pieces tied to the sheet + */ + protected void onSheetDelete() { + for (RelationPart part : getRelationParts()) { + if (part.getDocumentPart() instanceof XSSFTable) { + // call table delete + removeTable((XSSFTable) part.getDocumentPart()); + continue; + } + removeRelation(part.getDocumentPart(), true); + } + } + /** * Determine the OleObject which links shapes with embedded resources * diff --git a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFTable.java b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFTable.java index f0fcd02520..7435ce6add 100644 --- a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFTable.java +++ b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFTable.java @@ -29,6 +29,7 @@ import java.util.List; import java.util.Locale; import org.apache.poi.POIXMLDocumentPart; +import org.apache.poi.POIXMLDocumentPart.RelationPart; import org.apache.poi.openxml4j.opc.PackagePart; import org.apache.poi.ss.SpreadsheetVersion; import org.apache.poi.ss.usermodel.Cell; @@ -623,4 +624,14 @@ public class XSSFTable extends POIXMLDocumentPart implements Table { return true; } return false; - }} + } + + /** + * Remove relations + */ + protected void onTableDelete() { + for (RelationPart part : getRelationParts()) { + removeRelation(part.getDocumentPart(), true); + } + } +} \ No newline at end of file diff --git a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFWorkbook.java b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFWorkbook.java index 7d6529d405..1774932a4e 100644 --- a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFWorkbook.java +++ b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFWorkbook.java @@ -1366,6 +1366,11 @@ public class XSSFWorkbook extends POIXMLDocument implements Workbook { * @param index the 0-based index of the sheet to delete */ private void onSheetDelete(int index) { + // remove all sheet relations + final XSSFSheet sheet = getSheetAt(index); + + sheet.onSheetDelete(); + //delete the CTSheet reference from workbook.xml workbook.getSheets().removeSheet(index); -- 2.39.5