Bug 51955 - unable to get themes table from getStylesTable() call using the XSSFReader event model
unable to get themes table from getStylesTable() call using the XSSFReader ev...
Status: RESOLVED FIXED
Product: POI
Classification: Unclassified
Component: XSSF
3.8-dev
All Windows XP
: P2 critical (vote)
: ---
Assigned To: POI Developers List
:
Depends on:
Blocks:
  Show dependency tree
 
Reported: 2011-10-04 20:41 UTC by jxz164
Modified: 2011-10-05 21:05 UTC (History)
0 users



Attachments
Sample xlsx file to demonstrate the bug (9.35 KB, application/octet-stream)
2011-10-04 20:41 UTC, jxz164
Details

Note You need to log in before you can comment on or make changes to this bug.
Description jxz164 2011-10-04 20:41:49 UTC
Created attachment 27690 [details]
Sample xlsx file to demonstrate the bug

I am trying to get the themes table for XLSX files using the XSSFReader event model API (3.8-beta4). Unfortunately the getStylesTable() call of the XSSFReader class always returns a StylesTable with a null theme. Please see the following code and the attached xlsx file that demonstrate this problem. 

On the other hand, using the user model XSSFWorkbook API I am able to get the themes table and the RGB values correctly. So I suspect this is a bug of the getStylesTable() method.


package org.apache.poi.ss.examples;

import java.io.FileInputStream;

import org.apache.poi.xssf.eventusermodel.XSSFReader;
import org.apache.poi.xssf.model.StylesTable;
import org.apache.poi.xssf.model.ThemesTable;
import org.apache.poi.xssf.usermodel.XSSFCellStyle;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.apache.poi.openxml4j.opc.OPCPackage;

public class TestTheme {
	
    public void processEventModel(String filename) throws Exception {
    	OPCPackage pkg = OPCPackage.open(filename);
    	XSSFReader r = new XSSFReader( pkg );
    	StylesTable st = r.getStylesTable();
    	ThemesTable ttable = st.getTheme();
    	System.out.println(ttable);
	
    	XSSFCellStyle cs = st.getStyleAt(1);
    	System.out.println(cs.getFillForegroundColorColor().getARGBHex());
    }

    public void processUserModel(String filename) throws Exception {
       	OPCPackage pkg = OPCPackage.open(filename);
        XSSFWorkbook wb = new XSSFWorkbook(pkg);
        StylesTable st = wb.getStylesSource(); 
    	ThemesTable ttable = st.getTheme();

    	System.out.println(ttable);
    	XSSFCellStyle cs = st.getStyleAt(1);
    	System.out.println(cs.getFillForegroundColorColor().getARGBHex());
    }
    
    public static void main(String[] args) throws Exception {
    	TestTheme tt = new TestTheme();
    	System.out.println("Getting ThemesTable using Event Model");
    	tt.processEventModel(args[0]);
    	System.out.println("Getting ThemesTable using User Model");
    	tt.processUserModel(args[0]);
    }
}
Comment 1 Nick Burch 2011-10-04 21:03:20 UTC
Themes live in a different package part to the styles, but they're linked. I suspect that the xssf reader isn't doing the setup that xssf usermodel does to wire the two together

If you have a minute, take a look at how usermodel does the themes bit, then work up a patch to have the reader do the same. That'll be much quicker than waiting for someone to have time to look at it!

Also, any chance you could turn your sample program into a (currently failing) unit test, so when fixed we can ensure it stays fixed?
Comment 2 jxz164 2011-10-05 20:05:06 UTC
Thanks, Nick. Now I know how to fix my problem. It looks like we need to add a getThemesTable method to the XSSFReader class. The method returns a ThemesTable type. Then I can call setTheme() for the styles table. 

The getThemesTable() method can be copied from getStylesTable() with a slight change. I will see if I can create a patch later.

    public ThemesTable getThemesTable() throws IOException, InvalidFormatException {
        ArrayList<PackagePart> parts = pkg.getPartsByContentType( XSSFRelation.THEME.getContentType());
        return parts.size() == 0 ? null : new ThemesTable(parts.get(0), null);
    }
Comment 3 Nick Burch 2011-10-05 21:05:25 UTC
Ah, it really is that simple, isn't it

Should be fixed in r1179440 - I've got the getStylesTable method to find the themes part and supply it if available