Page 1 of 1

How to format a table

PostPosted: Fri Nov 19, 2010 1:53 pm
by ashario
Hi all

I'm creating a table, adding a header row and then multiple data rows. I've managed to work out how to create the table, but I have no idea where to look to find out how to format my table.

3 things I'd like to be able to do are

1. Have a solid thin border for all cells in the table (the same border you see when you create a default table in Word)
2. Centre align the text in the header row
3. Bold text in the header row

Below is the code so far. If someone can point me in the right direction, it would be very much appreciated.

Code: Select all
Tbl tblCredProg = factory.createTbl();

Tr thead = factory.createTr();
addTc(thead, "Centre");
addTc(thead, "Facility Questionnaire");
addTc(thead, "Benchmarking");
addTc(thead, "Site Visit");
addTc(thead, "Overall Result");
tblCredProg.getEGContentRowContent().add(thead);


protected void addTc(Tr tr, String text) {
   Tc tc = factory.createTc();
   tc.getEGBlockLevelElts().add( wordMLPackage.getMainDocumentPart().createParagraphOfText(text) );
   tr.getEGContentCellContent().add( tc );
}


Re: How to format a table

PostPosted: Fri Nov 19, 2010 4:14 pm
by jason
Have you tried formatting a table as you would like it in Word, and then looking at the resulting XML? Note that its appearance may be affected by the styles and themes parts.

If you are wondering what the corresponding docx4j objects in the MDP are, you can run it through the OpenMainDocumentAndTraverse sample.

If you don't feel like creating all those JAXB objects using the ObjectFactory, you can unmarshall from string (see Getting Started for details).

So, if you'd like further help on this topic, pls start your post with the XML you are wishing to replicate and/or discuss.

thanks .. Jason

Re: How to format a table

PostPosted: Fri Nov 19, 2010 6:37 pm
by ashario
Thanks

The xml for a simple example of my doc is below. It represents a table containing 3 rows, with each row containing 3 columns.

All columns in the first row are bold and centre aligned.
All cells have a solid thin border.

I'm interested in learning the 'best practice' techniques you might use to, for example
- get a table cell and make its contents bold
- get a table cell and make its contents centre aligned.

Even better would be if we could
- get a table row and make its contents bold
- get a table row and make its contents centre aligned.

Code: Select all
      <w:tbl>
         <w:tblPr>
            <w:tblStyle w:val="TableGrid" />
            <w:tblW w:w="0" w:type="auto" />
            <w:tblLook w:val="04A0" />
         </w:tblPr>
         <w:tblGrid>
            <w:gridCol w:w="3080" />
            <w:gridCol w:w="3081" />
            <w:gridCol w:w="3081" />
         </w:tblGrid>
         <w:tr>
            <w:tc>
               <w:tcPr>
                  <w:tcW w:w="3080" w:type="dxa" />
               </w:tcPr>
               <w:p>
                  <w:pPr>
                     <w:jc w:val="center" />
                     <w:rPr>
                        <w:b />
                     </w:rPr>
                  </w:pPr>
                  <w:r w:rsidRPr="000E7E43">
                     <w:rPr>
                        <w:b />
                     </w:rPr>
                     <w:t>Header1</w:t>
                  </w:r>
               </w:p>
            </w:tc>
            :
         </w:tr>
            :
      </w:tbl>


Re: How to format a table

PostPosted: Fri Nov 19, 2010 7:48 pm
by jason
So you can see the table look (solid thin border) comes from:

Code: Select all
<w:tblPr>
            <w:tblStyle w:val="TableGrid" />
            <w:tblLook w:val="04A0" />
         </w:tblPr>


Each paragraph in a tc is centred by:

Code: Select all
                  <w:pPr>
                     <w:jc w:val="center" />


and each run in each p made bold by

Code: Select all
                  <w:r>
                     <w:rPr>
                        <w:b />
                     </w:rPr>
                     <w:t>Header1</w:t>
                  </w:r>


I believe you have to set these properties at the p level; you can't do it at the tc or tr level.

Given your code snippet, you'd change the line:

Code: Select all
tc.getEGBlockLevelElts().add( wordMLPackage.getMainDocumentPart().createParagraphOfText(text) );


and instead create the P yourself, add pPr, and add a run containing the rPr and your text. You'd then tc.getEGBlockLevelElts().add(p).

If instead you were adding the formatting to an existing table, you want to get the relevant tr from the list of table rows we discussed in the other thread:
Code: Select all
      List<Object> rows = tbl.getEGContentRowContent();


and then iterate over its cells,
Code: Select all
      List<Object> cells = tr.getEGContentCellContent();


and then access its contents list, to add the properties:

Code: Select all
tc.getEGBlockLevelElts()

Re: How to format a table

PostPosted: Sat Nov 20, 2010 12:55 am
by myjupiler
I may give some precisions. I've used POI before docx4j and played with cell borders.

POI propose border/alignement options at paragraph level but the result is not looking good in Word.
Alignement is OK but borders appears INSIDE the cell, like underlining, and not as cell borders. So you get a discontinued border, not pretty.

It is like formatting a line of text with borders outside a table.

Therefore I believe they must be cell borders properties but I didn't look further the topic. What I actually still have to do !

Re: How to format a table

PostPosted: Sat Nov 20, 2010 1:33 am
by myjupiler
Seems to be different ways to do it.

###When you create a table with default values, you have borders everywhere and no reference to any border tag.
<w:tblPr>
<w:tblStyle w:val="Grilledutableau"/>
<w:tblW w:w="0" w:type="auto"/>
<w:tblLook w:val="04A0"/>
</w:tblPr>



###The same table but I removed all the borders. It added a tblBorders tag
<w:tblBorders>
<w:top w:val="none" w:sz="0" w:space="0" w:color="auto"/>
<w:left w:val="none" w:sz="0" w:space="0" w:color="auto"/>
<w:bottom w:val="none" w:sz="0" w:space="0" w:color="auto"/>
<w:right w:val="none" w:sz="0" w:space="0" w:color="auto"/>
<w:insideH w:val="none" w:sz="0" w:space="0" w:color="auto"/>
<w:insideV w:val="none" w:sz="0" w:space="0" w:color="auto"/>
</w:tblBorders>


###Last change. I keep only bottom and right border to the whole table and bottom and right to the center cell (it is a 3*3 table).

TblBorders tag becomes
<w:tblBorders>
<w:top w:val="none" w:sz="0" w:space="0" w:color="auto"/>
<w:left w:val="none" w:sz="0" w:space="0" w:color="auto"/>
<w:insideH w:val="none" w:sz="0" w:space="0" w:color="auto"/>
<w:insideV w:val="none" w:sz="0" w:space="0" w:color="auto"/>
</w:tblBorders>

and the cells that still have some borders do now have tcBorders tags :
<w:tcBorders>
<w:bottom w:val="single" w:sz="4" w:space="0" w:color="auto"/>
<w:right w:val="single" w:sz="4" w:space="0" w:color="auto"/>
</w:tcBorders>

###Last version : the table created with docx4j, no borders so far
no tblPr tag, to tcPr tag. very basic.


There must be one of the table property (tblStyle, tblW, tblLook) defining an overall style that is overwritten by table borders tag or cell borders tags.

Re: How to format a table

PostPosted: Sat Nov 20, 2010 2:01 am
by myjupiler
Taken from the Office Open XML spec :


These cell borders are specified using the following WordprocessingML:
<w:tcPr>
<w:tcBorders>
<w:top w:val="double" w:sz="24" w:space="0" w:color="FF0000"/>
<w:left w:val="double" w:sz="24" w:space="0" w:color="FF0000"/>
<w:bottom w:val="double" w:sz="24" w:space="0" w:color="FF0000"/>
<w:right w:val="double" w:sz="24" w:space="0" w:color="FF0000"/>
</w:tcBorders>
</w:tcPr>

bottom (Table Cell Bottom Border)
insideH (Table Cell Inside Horizontal Edges Border)
insideV (Table Cell Inside Vertical Edges Border)
left (Table Cell Left Border)
right (Table Cell Right Border)
tl2br (Table Cell Top Left to Bottom Right Diagonal Border)
top (Table Cell Top Border)
tr2bl (Table Cell Top Right to Bottom Left Diagonal Border)


You have to be careful with border conflicts (the right border of A is left border of B if A and B are side by side)
The doc says :

If the cell spacing is zero, then there may be a conflict between two adjacent cell borders [Example: Between the left border of all cells in the second column and the right border of all cells in the first column of the table. end example], which shall be resolved as follows:
1. If either conflicting table cell border is nil or none (no border), then the opposing border shall be displayed.
2. If a cell border conflicts with a table border, the cell border always wins.
3. Each border shall then be assigned a weight using the following formula, and the border value using this calculation shall be displayed over the alternative border:
W_border=# of lines in border*border number
The border number shall be determined by this list:
single 1
thick 2
double 3
dotted 4
dashed 5



the list is bigger but you have the basics