Introduction
Welcome back again in OpenXML world, where you can create a word table with the help of C# and OpenXML.
Here the magic is, No need to install word on your machine, no Interop object required. Lets see how to drive it
Background
I have given brief explanation about 'What is Open XML' in my previous article, if you are new to OpenXML then check out this link
http://www.codeproject.com/Tips/994905/Edit-Word-Documents-using-OpenXML-and-Csharp-Witho
OpenXML table structure
According to people, OpenXML is legthy and complex but if you understand it's structure then it is really a cup of tea. So lets start with table structure first.
Things we need before going to openXML
Getting started with OpenXML Table
A table consists of rows and cells and is structured much like an HTML table. It is defined with the <w:tbl> element. Basic table structure can be defined as
<w:tbl>
<w:tblpr>.....</w:tblpr>
<w:tblgrid>....</w:tblgrid>
<w:tr>....</w:tr>
</w:tbl>
In above structure we can see, Table has three main tag.
1. w:tblpr : Specifies the table-wide properties for the table. These properties can be overridden by individual table level
2. w:tblgrid : Specifies the columns for the table
3. w:tr : Specifies a table row
Let see them one by one in detail
1. w:tblpr :
This Specifies the table-wide properties for the table, Each property is a child element of <tblPr> , and they affect all rows and cells in the table, but the style can be overridden by each individual row, column or cell.
The most commonly used properties are shown below
Property Name |
Description |
w:jc |
Represent table alignment. |
w:shd |
Represent table shading. |
w:Borders |
Represent table borders. |
w:Caption |
Represent table Caption. |
w:CellMar |
Represent table cell margins. |
w:tblCellSpacing |
Represent table spacing. |
w:tblLayout |
Represent table layout. |
w:tblLook |
Represent table conditional formatting. |
see below tag snippet
<w:tblPr>
<w:tblStyle w:val="TestTableStyle"/>
<w:jc w:val="center"/>
</w:tblPr>
2. w:tblgrid
The columns of a table are defined by the <w:tblGrid> element it contains attribute as <w:gridCol> which is the size of each columns, if the table has 4 columns then w:tblgrid has 4 w:gridCol tags
see below tag snippet
<w:tblGrid>
<w:gridCol w:w="2800"/>
<w:gridCol w:w="2600"/>
<w:gridCol w:w="2800"/>
<w:tblGrid>
3.w:tr
This is the row defination tag, this is the core element of table. it has following subset
Property Name |
Description |
w:trPr |
Represent row level properties, but can be overridden by individual cell |
w:tblPrEx |
Represent table properties for the row, These properties are typically used for legacy documents, as well as in cases where two independent tables are merged |
w:tc |
Represent individual table cell. |
see below tag snippet
<w:tr>
<w:trPr>.....</w:trPr>
<w:tblPrEx>....</w:tblPrEx>
<w:tc>....</w:tc>
</w:tr>
Now we will see w:tr properties in depth.
3.1 w:trPr
This element represent row level properties, Each property is a child element of <trPr> , and they affect all cells in the row. Mostly used properties are as below
Property Name |
Description |
w:cantSplit |
it prevents the contents of the row from breaking across multiple pages by moving the start of the row to the start of a new page, it help the row to start on next page |
w:hidden |
Help to hide the entire row |
w:jc |
Specifies the alignment of the row |
w:tblCellSpacing |
Specifies the cell spacing, it is same like HTML table attribute |
w:tblHeader |
Specifies the current row should be repeated as header of each table on new page |
w:trHeight |
Represent the height of the row, if optional then height will be adjusted automatically |
3.2 w:trPrEx
As described exceptional properties of the table, with the help of this property we can show any row with specific exception. w:trPrEx has almost same properties like <w:trPr>, some new properties are as below
Property Name |
Description |
w:shd |
Specifies the background color, it is optional property, it has different attribute like color, fill, val. |
w:tblBorders |
Specifies row borders |
w:tblCellMar |
Specifies the margin of the cell, this is basically cell properties of exceptional row (we will see this property thoroughly in cell section) |
w:tblInd |
Before leading edge of the row it adds indentation to the row, |
w:tblLayout |
Specifies the inbuilt table layout |
w:tblLook |
Specifies the inbuilt table layout specified by word application |
see below tag snippet
<w:tr>
<w:tblPrEx>
<w:tblBorders>
<w:top w:val="single" w:sz="12" w:space="0" w:color="FF0000" />
<w:start w:val="single" w:sz="24" w:space="0" w:color="00FF00" />
<w:bottom w:val="single" w:sz="12" w:space="0" w:color="0000FF" />
<w:end w:val="single" w:sz="24" w:space="0" w:color="000000" />
<w:insideH w:val="single" w:sz="24" w:space="0" w:color="FFFF00" />
<w:insideV w:val="single" w:sz="24" w:space="0" w:color="FF00FF" />
</w:tblBorders>
</w:tblPrEx>
</w:tr>
3.3 w:tc
This tag specifies data for individual table cell, these tags are nested under table row tags. The core elements of w:tc are as follows
Property Name |
Description |
w:p |
Specifies the paragraph of each cell |
w:tbl |
Specifies table as content of the cell |
w:tcPr |
Specifies the properties to be applied to the current cell. |
see below snippet
<w:tc>
<w:tcPr>
<w:tcW w:w="2600" w:type="dxa"/>
</w:tcPr>
<w:p>
<w:r>
<w:t>cell content</w:t>
</w:r>
</w:p>
</w:tc>
above markup snippet contains table cell, in which paragraph (<w:p>), Run (<w:p>), Text (<w:r>) are the child element of the cell.
3.3.1 w:p
Paragraph is the main part of the cell, The paragraph can contain rich formatting properties for the paragraph, Paragraphs may also contain bookmarks, hyperlinks, fields, comments, etc. The core element of paragraph is properties (<w:pPr>) and run (<w:r>)
Both paragraph properties and run has their own properties like paragraph frames, indentation, alignment, numbering, border, paragraph style, shading and tabs.
see below markup
<w:p>
<w:pPr>
<w:pStyle> w:val="TestWeb"/>
<w:spacing w:before="20" w:after="20"/>
</w:pPr>
<w:r>
<w:t>This is cell content</w:t>
</w:r>
</w:p>
3.3.2 w:tcPr
tcPr represent cellwise properties, this properties are used to decorate cell. Row and column wise properties can be overridden in this section
Property Name |
Description |
w:gridSpan |
Specifies the spanning cell across rows |
w:hideMark |
Specifies hide end of the table cell mark |
w:noWrap |
Specifies the prevent text from wrapping, it is boolean property |
w:tcBorders |
Specifies table cell border |
w:tcFitText |
Specifies text within the cell can be extend to the width of the cell, this is the boolean property |
w:tcMar |
Specifies table cell margins |
w:tcW |
Specifies table cell width |
w:vAlign |
Specifies table cell vertical alignments |
w:vMerge |
This property indicates if the cell is part of merged group cell, it has two possible values continue and restart |
3.3.1.1 w:r
Run defines a text properties. Most commonly run contains only text but it may have content as symbols, tabs, hyphens, carriage returns, drawings, breaks, and footnote references
see below properties of Run element
Property Name |
Description |
w:br |
Specifies a break e.g. <w:br/> |
w:cr |
Specifies a carriage return |
w:drawing |
Specifies the layout of the DrawingML object within the document |
w:noBreakHypen |
Specifies the non breaking hypen. |
w:rPr |
Specifies the properties of the run like |
w:softHypen |
Specifies the inbuilt table layout specified by word application |
w:sym |
Specifies a special character or symbol |
w:t |
Spcifies the actual text which will display in cell, This is very important and core element of Table markup, this element hold actual text contents. |
w:tab |
Specifies the TAB character |
see below markup snippet
<w:r>
<w:rPr>
<w:b/>
<w:i/>
</w:rPr>
<w:t>This is sample text</w:t>
</w:r>
3.3.1.1.1 w:rPr
This element contains different properties of the Run, which is then applies to actual text exist in <w:t> section
here are the most commonly used properties of the run
Property Name |
Description |
w:b |
Display text in bold, exist in Text element e.g. <w:b /> |
w:i |
Display text in Italics, exist in Text element e.g. <w:i /> |
w:caps |
Display text in small or upper caps depend upon 'val' attributes e.g. <w:caps w:val="true" /> |
w:color |
Display text in specified color, it accept color code for color e.g. <w:color w:val="FF1244" /> |
w:dstrike |
Display text in Strike through format e.g. <w:dstrike w:val="true"/> |
w:emboss |
Display text in emboss style e.g. <w:emboss w:val="true" /> |
w:imprint |
Display text in imprint style e.g. <w:imprint w:val="true"/> |
w:outline |
Display text in outline style e.g. <outline w:val="true"/> |
w:rStyle |
Display character style depend upon style ID (Here style is inbuilt) |
w:shadow |
Display text has shadow for each character <w:shadow w:val="true"/> |
w:smallCaps |
Display text in small capital letter, The difference between caps and smallCaps is, caps make the text size larger and convert text to capital where as smallCaps convert text to capital but does not increase the font e.g. <w:smallCaps w:val="true"/> |
w:sz |
Display the text in specified size, e.g. <w:sz w:val="14"/> . |
w:u |
Display the text in underline, e.g. <w:u w:val="double"/> |
w:vanish |
Text in this element will be hidden from display, e.g. <vanish/> |
w:vertAlign |
Display text in Super or subscript e.g. <vertAlign w:val="superscript | baseline | subscript "/> |
So here is the raw hierarchy structure of OpenXML table format
Go with Markup and code
Now with the above all markup's we can create a table in word (DOCX) file, here i have develope a small application that will put a nice table in word file
first create table properties, see below xml markup's (We have apply inbuilt table style and look as Accept4)
<w:tblPr>
<w:tblStyle w:val="LightGrid-Accent4" />
<w:tblW w:w="0" w:type="auto" />
<w:tblLook w:val="04A0" />
</w:tblPr>
then we will add columns in table, see below xml markup's (We have take 3 columns)
<w:tblGrid>
<w:gridCol w:w="2394" />
<w:gridCol w:w="2394" />
<w:gridCol w:w="2394" />
</w:tblGrid>
Now we will add rows in it with text to be display. (We have added 1 row with 3 cell here)
<w:tr w:rsidR="004D1DA5" w:rsidTr="004D1DA5">
<w:trPr>
<w:cnfStyle w:val="100000000000" />
</w:trPr>
<w:tc>
<w:tcPr>
<w:cnfStyle w:val="001000000000" />
<w:tcW w:w="2394" w:type="dxa" />
<w:hideMark />
</w:tcPr>
<w:p w:rsidR="004D1DA5" w:rsidRDefault="004D1DA5">
<w:pPr>
<w:jc w:val="center" />
</w:pPr>
<w:r>
<w:t>No</w:t>
</w:r>
</w:p>
</w:tc>
<w:tc>
<w:tcPr>
<w:tcW w:w="2394" w:type="dxa" />
<w:hideMark />
</w:tcPr>
<w:p w:rsidR="004D1DA5" w:rsidRDefault="004D1DA5">
<w:pPr>
<w:jc w:val="center" />
<w:cnfStyle w:val="100000000000" />
</w:pPr>
<w:r>
<w:t>Name</w:t>
</w:r>
</w:p>
</w:tc>
<w:tc>
<w:tcPr>
<w:tcW w:w="2394" w:type="dxa" />
<w:hideMark />
</w:tcPr>
<w:p w:rsidR="004D1DA5" w:rsidRDefault="004D1DA5">
<w:pPr>
<w:jc w:val="center" />
<w:cnfStyle w:val="100000000000" />
</w:pPr>
<w:r>
<w:t>Sex</w:t>
</w:r>
</w:p>
</w:tc>
</w:tr>
Here is code to create Markup
# Create table object and add table properties
Table table1 = new Table();
TableProperties tableProperties1 = new TableProperties();
TableStyle tableStyle1 = new TableStyle() { Val = "LightGrid-Accent4" };
TableWidth tableWidth1 = new TableWidth() { Width = "0", Type = TableWidthUnitValues.Auto };
TableLook tableLook1 = new TableLook() { Val = "04A0" };
tableProperties1.Append(tableStyle1);
tableProperties1.Append(tableWidth1);
tableProperties1.Append(tableLook1);
# define table columns and add them in table
TableGrid tableGrid1 = new TableGrid();
GridColumn gridColumn1 = new GridColumn() { Width = "2394" };
GridColumn gridColumn2 = new GridColumn() { Width = "2394" };
GridColumn gridColumn3 = new GridColumn() { Width = "2394" };
tableGrid1.Append(gridColumn1);
tableGrid1.Append(gridColumn2);
tableGrid1.Append(gridColumn3);
# Define new cell object with its associated paragraph, Run, Text object and their properties respectively.
TableRow tableRow1 = new TableRow(){RsidTableRowAddition="004D1DA5",RsidTableRowProperties="004D1DA5"};
TableRowProperties tableRowProperties1 = new TableRowProperties();
ConditionalFormatStyle conditionalFormatStyle1 = new ConditionalFormatStyle(){Val="100000000000"};
tableRowProperties1.Append(conditionalFormatStyle1);
TableCell tableCell1 = new TableCell();
TableCellProperties tableCellProperties1 = new TableCellProperties();
ConditionalFormatStyle conditionalFormatStyle2 = new ConditionalFormatStyle(){Val="001000000000"};
TableCellWidth tableCellWidth1 = new TableCellWidth(){Width="2394",Type=TableWidthUnitValues.Dxa};
HideMark hideMark1 = new HideMark();
tableCellProperties1.Append(conditionalFormatStyle2);
tableCellProperties1.Append(tableCellWidth1);
tableCellProperties1.Append(hideMark1);
Paragraph paragraph1 = new Paragraph(){RsidParagraphAddition="004D1DA5",RsidRunAdditionDefault="004D1DA5"};
ParagraphProperties paragraphProperties1 = new ParagraphProperties();
Justification justification1 = new Justification() { Val = JustificationValues.Center };
paragraphProperties1.Append(justification1);
Run run1 = new Run();
Text text1 = new Text();
text1.Text = "No";
run1.Append(text1);
paragraph1.Append(paragraphProperties1);
paragraph1.Append(run1);
tableCell1.Append(tableCellProperties1);
tableCell1.Append(paragraph1);
Yes, we are done with our code now try to test it.
Summing Up
OpenXML is is an open, international, ECMA-376, Second Edition and ISO/IEC 29500 standard, They are based on technologies like XML and ZIP. You can improve your application performance with the help of OpenXML, Developer can interact with DOCX file without opening it. With the help of openXML you can perform complex operations with just a few lines of code.
In this article we have seen how to draw a word table using OpenXML and C#
Till more to happen and learn, we will see more good samples in coming versions of this article.
Suggestions and Queries are always welcome.
Thanks
koolprasad2003