Steps: 1. Open old.xls Excel file (see in attachment). 2. Create new XLSX Excel file. 2. Copy cell with colored background from old.xls to new xlsx. 3. Process new xlsx doc with poi. 4. Get cell background color: cell.getCellStyle().getFillForegroundXSSFColor().getRgb() Actual: null Expected: rgb byte array
Created attachment 26661 [details] Excel 97-2003 file
Can you unzip the file (.xlsx is a zip of xml files), and track down where your colour actually gets stored?
styles.xml <fgColor indexed="42"/> Color is stored as indexed. Possible solution: XSSFColor color = ..; short colorIndex = color.getIndexed(); HSSFColor indexedColor = HSSFColor.getIndexHash().get(colorIndex); byte[] rgb = indexedColor.getTriplet();
Thanks for the investigating, sample file and proposed fix I've added the HSSFColor lookup inside the getRGB method and added a unit test for it in r1072082.
Noticed that indexed colors hashtable is not stored in HSSFColor. So getRGBOrARGB() method calls HSSFColor.getIndexHash() whitch every time (fill color, text color, border color) builds color hashtable. It's very slowly. HSSFColor.getIndexHash() method has comment: "this function returns all colors in a hastable. Its not implemented as a static member/staticly initialized because that would be dirty in a server environment as it is intended. This means you'll eat the time it takes to create it once per request but you will not hold onto it if you have none of those requests."
(In reply to comment #5) > HSSFColor.getIndexHash() method has comment: > "this function returns all colors in a hastable. Its not implemented as a > static member/staticly initialized because that would be dirty in a > server environment as it is intended. This means you'll eat the time > it takes to create it once per request but you will not hold onto it > if you have none of those requests." I think we should probably replace this with a lazy initialized static cache on HSSFColor. That way your first call may be a little slow while it's built, but all other calls on the server will then be fast. My plan would be to have it return an immutable hash which is statically cached, but also offer a 2nd method that will return a writable hash for anyone currently doing anything odd I could swap that round with the new method name for the static cache version, and the old method name for the mutable one, if someone can think of a good reason why to do it that way!
Thanks, it's a good idea
Change committed in r1077920. Almost everyone seemed to just call getIndexedHash().get(..) so they will get the speedup with no need to change anything In the very rare case that you were relying on editing the old hashtable, getModifiableIndexedHash will provide that.
Excellent!