I'm using ECMA-376 3rd Edition / June 2011, Office Open XML File Formats – Part 
1

Although it looks like there's a 5th edition from 2015. I'll get that one:

https://www.ecma-international.org/publications/standards/Ecma-376.htm

Cheers,

E.
--
Eliot Kimber
http://contrext.com
 

On 8/16/18, 10:55 AM, "Murphy, Mark" <[email protected]> wrote:

    Which version of the spec are you reading? We are using Version 1. Though 
we sometimes deal with later version artifacts, the CT and ST classes are all 
version 1.
    
    -----Original Message-----
    From: Eliot Kimber [mailto:[email protected]] 
    Sent: Thursday, August 16, 2018 11:00 AM
    To: POI Users List <[email protected]>
    Subject: Re: General Support for Percentage Values?
    
    I'm reading section 17.4.88 Table Measurement (CT_TblWidth), which shows 
this example:
    
    <… w:type="pct" w:w="100%"/>
    
    And which refers to 17.18.107 ST_MeasurementOrPercent (Measurement or 
Percentage Value) as the definition of the @w:w attribute.
    
    It says it's a union of two types: ST_DecimalNumberOrPercent and 
ST_UniversalMeasure.  ST_DecimalNumberOrPercent then says it's a union of 
ST_Percentage, 22.9.2.9 ST_Percentage (Percentage Value with Sign), which has 
this example:
    
    <w:tcW w:type="pct" w:w="33.3%" />
    
    I tried some experiements and if I modify the XML for my table to e.g.:
    
    <w:tblW w:type="pct" w:w="50%"/>
    
    And open it, Word correctly reflects the 50% width BUT when I save from 
Word the @w:w value is set to 2500 (50 * 50).
    
    So clearly Word prefers to store things as integers, which makes sense, but 
it will read the % string value as defined in the spec.
    
    I'm curious--what part of the spec are you reading that indicates that 
value is always an integer? I'm not doubting that it says that, but I didn't 
get to that part of the spec starting from the definitions for table width.
    
    But this does suggest that my code that lets you set and get the table 
width (and the table cell widths, as you indicate, which I also need) is 
appropriate, in that it conforms to the spec, works with Word, and provides the 
convenience of allowing direct specific of the literal decimal percentage 
strings to .setWidth().
    
    At the same time, there's no reason not to have the POI code do the 
percentage-to-integer conversion when it sets the @w:w value.
    
    Cheers,
    
    Eliot
    
    --
    Eliot Kimber
    http://contrext.com
     
    
    On 8/16/18, 8:42 AM, "Murphy, Mark" <[email protected]> wrote:
    
        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:[email protected]] 
        Sent: Wednesday, August 15, 2018 7:02 PM
        To: POI Users List <[email protected]>
        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" <[email protected]> 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" <[email protected]> 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: [email protected]
                For additional commands, e-mail: [email protected]
                
                
                
            
            
            
            
---------------------------------------------------------------------
            To unsubscribe, e-mail: [email protected]
            For additional commands, e-mail: [email protected]
            
            
            
        
        
        
        ---------------------------------------------------------------------
        To unsubscribe, e-mail: [email protected] For additional 
commands, e-mail: [email protected]
        
        
        ---------------------------------------------------------------------
        To unsubscribe, e-mail: [email protected]
        For additional commands, e-mail: [email protected]
        
    
    
    
    ---------------------------------------------------------------------
    To unsubscribe, e-mail: [email protected] For additional 
commands, e-mail: [email protected]
    
    
    ---------------------------------------------------------------------
    To unsubscribe, e-mail: [email protected]
    For additional commands, e-mail: [email protected]
    



---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to