According to the spec, w:val is always an integer value. What that integer 
represents depends on the w:type value. If w:type="auto" then it appears that 
w:val=0, or may even be ignored, but that will depend on the table width 
algorithm. I didn't look at that just now, it is very complex.

If w:type="dxa" then w:val is an integer that represents 20ths of a point. In 
that case I would take the value you specify in setCellWidth and multiply by 20 
to get the integer for val (don't make the user provide val in 20ths of a 
point).

If w:type="pct" then w:val is an integer that represents 50ths of a point. In 
that case I would take the value specified in setCellWidth and multiply by 50 
to get the integer for w:val (again don't make the user provide val in 50ths of 
a percent).

getCellWidth will have to honor these conventions as well. To retrieve cell 
width in points, you will have to divide w:val by 20, and to retrieve cell 
widths in percents, you will have to divide by 50. Note, there is no real way 
to convert between points and percent.

-----Original Message-----
From: Eliot Kimber [mailto:ekim...@contrext.com] 
Sent: Wednesday, August 15, 2018 7:02 PM
To: POI Users List <user@poi.apache.org>
Subject: Re: General Support for Percentage Values?

If I manually set the @w:w value to the percentage string then I can get back 
the percentage and convert it to a double when the width type is set to 
percentage.

But I think there really needs to be a method on CTTblWidth that can return an 
STPercentage, parallel to xgetWidth(), which returns a BigDecimal.

Cheers,

E.

--
Eliot Kimber
http://contrext.com
 

On 8/15/18, 5:39 PM, "Eliot Kimber" <ekim...@contrext.com> wrote:

    (This is in the context of setting the width on XWPFTable.)
    
    I decided that the best (and simplest) approach would be to use strings to 
set the width value for "auto" and percentages, rather than creating a separate 
class that would just end up creating a percentage string anyway. This also 
matches the way the API is likely to be used, e.g., getting percentage value 
strings from some incoming source.
    
    So I added a new setWidth(String widthValue) method to XWPFTable() which 
validates that it's a good value ("auto", an integer, or a percentage) and then 
if it's good, sets the value appropriately.
    
    I also created a new method, getWidthDecimal(), to return the width value 
as a decimal (because percentages can be decimal values).
    
    Using this test case:
    
            XWPFDocument doc = new XWPFDocument();
    
            XWPFTable xtab = doc.createTable();
    
            assertEquals(0, xtab.getWidth());
            assertEquals(STTblWidth.AUTO, xtab.getWidthType());
            
            xtab.setWidth(1000);
            assertEquals(STTblWidth.DXA, xtab.getWidthType());
            assertEquals(1000, xtab.getWidth());
            
            xtab.setWidth("auto");
            assertEquals(STTblWidth.AUTO, xtab.getWidthType());
            assertEquals(0, xtab.getWidth());
            assertEquals(0.0, xtab.getWidthDecimal(), 0.01);
            
            xtab.setWidth("999");
            assertEquals(STTblWidth.DXA, xtab.getWidthType());                
            assertEquals(999, xtab.getWidth());
            
            xtab.setWidth("50.5%");
            assertEquals(STTblWidth.PCT, xtab.getWidthType());        
            assertEquals(50.5, xtab.getWidthDecimal(), 0.01);
            assertEquals(50.5, 
xtab.getCTTbl().getTblPr().getTblW().xgetW().getBigDecimalValue().doubleValue(),
 0.01);
    
    Everything passes until the last test, where the value returned by 
getWidthDecimal() is 50.0, not 50.5.
    
    It looks like the underlying CT class methods always set the value as an 
integer, even when using CTTblWidth.setBigDecimalValue():
    
            } else if (widthValue.matches("[0-9]+(\\.[0-9]+)?%")) {
                String numericPart = widthValue.substring(0, 
widthValue.length() - 1);
                STDecimalNumber number = STDecimalNumber.Factory.newInstance();
                number.setBigDecimalValue(new BigDecimal(numericPart));
                ctWidth.xsetW(number);
                ctWidth.setType(STTblWidth.PCT);
    
    Debugging through this code I see that the @w:val attribute is "50" rather 
than "50.5" after the xsetW() method call.
    
    This appears to be happening at a very low level.
    
    Is there a way to fix this so that percentages can be decimals or have I 
misunderstood the specs and percentages should actually always be integers 
(although I'm pretty sure the spec allows fractional percentages).
    
    Thanks,
    
    Eliot
    --
    Eliot Kimber
    http://contrext.com
     
    
    On 8/15/18, 3:40 PM, "Eliot Kimber" <ekim...@contrext.com> wrote:
    
        I need to extend the options for setting table widths.
        
        Per the spec, a table's width can be an absolute measurement, a 
percentage value, or the keyword "auto".
        
        Right now XWPFTable.setWidth() only takes an integer.
        
        I'd like to extend it to take in addition a percentage value or the 
value "auto" (which I suppose conceptually is an enumeration with one possible 
value).
        
        There doesn't seem to be a class that represents a percentage value (at 
least I couldn't find any declarations with the string "perc" in them.
        
        Am I missing something for working with percentage values in the XWPF 
API?
        
        Thanks,
        
        E.
        
        --
        Eliot Kimber
        http://contrext.com
         
        
        
        
        ---------------------------------------------------------------------
        To unsubscribe, e-mail: user-unsubscr...@poi.apache.org
        For additional commands, e-mail: user-h...@poi.apache.org
        
        
        
    
    
    
    ---------------------------------------------------------------------
    To unsubscribe, e-mail: user-unsubscr...@poi.apache.org
    For additional commands, e-mail: user-h...@poi.apache.org
    
    
    



---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscr...@poi.apache.org For additional 
commands, e-mail: user-h...@poi.apache.org

Reply via email to