When i create Drawing from sheet.createDrawingPatriarch() I got Exception: org.apache.poi.openxml4j.exceptions.PartAlreadyExistsException: A part with the name '/xl/drawings/drawing7.xml' already exists : Packages shall not contain equivalent part names and package implementers shall neither create nor recognize packages with equivalent part names. [M1.12] I tested with 3.14 and 3.15. Problem i found maybe: in org.apache.poi.xssf.usermodel.XSSFSheet.createDrawingPatriarch, we get new drawing index by code line int drawingNumber = getPackagePart().getPackage().getPartsByContentType(XSSFRelation.DRAWINGS.getContentType()).size() + 1; The index is count of exist drawings + 1. And correct if exist indexes are consecutive. My Excel file containing multiple drawings, getPackagePart().getPackage().getPartsByContentType(XSSFRelation.DRAWINGS.getContentType()) return indexes are nonconsecutive. Then I got Exception /xl/drawings/drawing1.xml /xl/drawings/drawing2.xml /xl/drawings/drawing3.xml /xl/drawings/drawing5.xml /xl/drawings/drawing7.xml /xl/drawings/drawing10.xml There is another way for me to re-index exist drawing by poi library or How can I override this method to get new index = get lastest index + 1 Thank you very much for reading and support
POI should probably look through all defined drawing IDs and either pick the lowest available ID greater than 0 (fill in the gaps) or 1 greater than the largest drawing ID. Will there be any issues with the first approach, such as drawing z-order or breaking references (hopefully no detached xml element exceptions)? Zero, can you upload a workbook with non-consecutive drawing numbers that we could use for a unit test?
Created attachment 34372 [details] excel file after clear content, now duplicate at /xl/drawings/drawing13.xml Thank Javen O'Neal, I upload the file
I think I found the bug, the method getPackagePart().getPackage().getPartsByContentType(XSSFRelation.DRAWINGS.getContentType()) not load all /xl/drawings/drawing#.xml I debug with getPackagePart().getPackage(), then I found hidden drawing, in partList, registerPartNameStr include /xl/drawings/drawing1.xml, /xl/drawings/drawing2.xml, /xl/drawings/drawing3.xml, /xl/drawings/drawing4.xml, /xl/drawings/drawing5.xml, /xl/drawings/drawing6.xml, /xl/drawings/drawing7.xml, /xl/drawings/drawing8.xml, /xl/drawings/drawing9.xml, /xl/drawings/drawing10.xml, /xl/drawings/drawing11.xml, /xl/drawings/drawing12.xml, /xl/drawings/drawing13.xml, /xl/drawings/drawing14.xml, /xl/drawings/drawing15.xml, /xl/drawings/drawing16.xml, /xl/drawings/drawing17.xml, /xl/drawings/drawing18.xml, /xl/drawings/drawing19.xml, /xl/drawings/drawing20.xml, /xl/drawings/drawing21.xml, /xl/drawings/drawing22.xml, /xl/drawings/drawing23.xml, /xl/drawings/drawing24.xml, /xl/drawings/drawing25.xml, /xl/drawings/drawing26.xml, /xl/drawings/drawing27.xml, /xl/drawings/drawing28.xml but getPackagePart().getPackage().getPartsByContentType(XSSFRelation.DRAWINGS.getContentType()) just return 1,4,7,8,12,13,16,19,20,21,24,28
I found reason why drawing2,3 not in list of getPackagePart().getPackage().getPartsByContentType(XSSFRelation.DRAWINGS.getContentType()) In function org.apache.poi.openxml4j.opc.OPCPackage.getPartsByContentType /xl/drawings/drawing2.xml - Content Type: application/vnd.openxmlformats-officedocument.drawingml.chartshapes+xml /xl/drawings/drawing3.xml - Content Type: application/vnd.openxmlformats-officedocument.drawingml.chartshapes+xml not equals XSSFRelation.DRAWINGS.getContentType() = application/vnd.openxmlformats-officedocument.drawing+xml then retArr added Thanks for reading
edit: then part not added to retArr sorry
Normally parts of type application/vnd.openxmlformats-officedocument.drawingml.chart+xml use the /xl/charts/chart#.xml naming scheme, but I guess this proves it doesn't always!
Fixed in r1764863 - util method added to find the next available part number even with other parts claiming the "wrong" one, and used from the drawing creation
Thank you very much, Nick Burch
(In reply to Nick Burch from comment #7) > r1764863 Is there anything special about the special 9999 and 1000? Could a workbook have more drawings than this (and then POI artificially limits drawing creation to 1000)? I was thinking of something along the lines of NavigableSet<Integer> takenIDs = new TreeSet<Integer>(); for (PackagePart part : packages) { takenIDs.add(part.getRefID()); } int previous = 0; for (int id : takenIDs.tailSet(1)) { if (id != previous+1) { // a gap was found or the taken IDs did not start at 1 return previous+1; } } // there were no gaps in takenIDs. Assign the max taken ID + 1. return takenIDs.last() + 1;
The most I've seen were part numberss in the double digits, so I added an order of magnitude and rounded up! If you have a cleaner solution, please feel free to replace the logic :) Unit tests should hopefully help with that too!
*** Bug 55516 has been marked as a duplicate of this bug. ***
(In reply to Nick Burch from comment #10) > The most I've seen were part numberss in the double digits, so I added an > order of magnitude and rounded up! If you have a cleaner solution, please > feel free to replace the logic :) Replaced 1000 part limit by querying the OOXML package for the number of package parts in r1765546.