/************************************************************************************* DocX – DocX is the community edition of Xceed Words for .NET Copyright (C) 2009-2016 Xceed Software Inc. This program is provided to you under the terms of the Microsoft Public License (Ms-PL) as published at http://wpftoolkit.codeplex.com/license For more features and fast professional support, pick up Xceed Words for .NET at https://xceed.com/xceed-words-for-net/ ***********************************************************************************/ using System; using System.Collections.Generic; using System.Linq; using System.Xml.Linq; using System.IO.Packaging; using System.IO; using System.Drawing; using System.Globalization; using System.Collections.ObjectModel; namespace Xceed.Words.NET { /// /// Represents a Table in a document. /// public class Table : InsertBeforeOrAfter { #region Private Members private Alignment _alignment; private AutoFit _autofit; private float[] _columnWidths; private TableDesign _design; /// /// The custom design\style to apply to this table. /// /// private string _customTableDesignName; private int _cachedColumnCount = -1; #endregion #region Public Properties /// /// Returns a list of all Paragraphs inside this container. /// /// public virtual List Paragraphs { get { var paragraphs = new List(); foreach( Row r in Rows ) paragraphs.AddRange( r.Paragraphs ); return paragraphs; } } /// /// Returns a list of all Pictures in a Table. /// /// /// Returns a list of all Pictures in a Table. /// /// pictures = t.Pictures; /// /// // Save this document. /// document.Save(); /// } /// ]]> /// /// public List Pictures { get { var pictures = new List(); foreach( Row r in Rows ) { pictures.AddRange( r.Pictures ); } return pictures; } } /// /// Get all of the Hyperlinks in this Table. /// /// /// Get all of the Hyperlinks in this Table. /// /// // Create a document. /// using (DocX document = DocX.Load(@"Test.docx")) /// { /// // Get the first Table in this document. /// Table t = document.Tables[0]; /// /// // Get a list of all Hyperlinks in this Table. /// List<Hyperlink> hyperlinks = t.Hyperlinks; /// /// // Save this document. /// document.Save(); /// } /// /// public List Hyperlinks { get { var hyperlinks = new List(); foreach( Row r in Rows ) { hyperlinks.AddRange( r.Hyperlinks ); } return hyperlinks; } } /// /// Returns the number of rows in this table. /// public Int32 RowCount { get { return this.Xml.Elements( XName.Get( "tr", DocX.w.NamespaceName ) ).Count(); } } /// /// Returns the number of columns in this table. /// public Int32 ColumnCount { get { if( this.RowCount == 0 ) return 0; if( _cachedColumnCount == -1 ) { foreach( var r in this.Rows ) { _cachedColumnCount = Math.Max( _cachedColumnCount, r.ColumnCount ); } } return _cachedColumnCount; } } /// /// Returns a list of rows in this table. /// public List Rows { get { var rows = ( from r in Xml.Elements( XName.Get( "tr", DocX.w.NamespaceName ) ) select new Row( this, Document, r ) ).ToList(); return rows; } } public Alignment Alignment { get { return _alignment; } set { string alignmentString = string.Empty; switch( value ) { case Alignment.left: { alignmentString = "left"; break; } case Alignment.both: { alignmentString = "both"; break; } case Alignment.right: { alignmentString = "right"; break; } case Alignment.center: { alignmentString = "center"; break; } } XElement tblPr = Xml.Descendants( XName.Get( "tblPr", DocX.w.NamespaceName ) ).First(); XElement jc = tblPr.Descendants( XName.Get( "jc", DocX.w.NamespaceName ) ).FirstOrDefault(); jc?.Remove(); jc = new XElement( XName.Get( "jc", DocX.w.NamespaceName ), new XAttribute( XName.Get( "val", DocX.w.NamespaceName ), alignmentString ) ); tblPr.Add( jc ); _alignment = value; } } /// /// Auto size this table according to some rule. /// public AutoFit AutoFit { get { return _autofit; } set { string tableAttributeValue = string.Empty; string columnAttributeValue = string.Empty; switch( value ) { case AutoFit.ColumnWidth: { tableAttributeValue = "auto"; columnAttributeValue = "dxa"; // Disable "Automatically resize to fit contents" option var tblPr = Xml.Element( XName.Get( "tblPr", DocX.w.NamespaceName ) ); if( tblPr != null ) { var layout = tblPr.Element( XName.Get( "tblLayout", DocX.w.NamespaceName ) ); if( layout == null ) { tblPr.Add( new XElement( XName.Get( "tblLayout", DocX.w.NamespaceName ) ) ); layout = tblPr.Element( XName.Get( "tblLayout", DocX.w.NamespaceName ) ); } var type = layout.Attribute( XName.Get( "type", DocX.w.NamespaceName ) ); if( type == null ) { layout.Add( new XAttribute( XName.Get( "type", DocX.w.NamespaceName ), String.Empty ) ); type = layout.Attribute( XName.Get( "type", DocX.w.NamespaceName ) ); } type.Value = "fixed"; } break; } case AutoFit.Contents: { tableAttributeValue = columnAttributeValue = "auto"; break; } case AutoFit.Window: { tableAttributeValue = columnAttributeValue = "pct"; break; } case AutoFit.Fixed: { tableAttributeValue = columnAttributeValue = "dxa"; var tblPr = Xml.Element( XName.Get( "tblPr", DocX.w.NamespaceName ) ); var tblLayout = tblPr.Element( XName.Get( "tblLayout", DocX.w.NamespaceName ) ); if( tblLayout == null ) { var tmp = tblPr.Element( XName.Get( "tblInd", DocX.w.NamespaceName ) ) ?? tblPr.Element( XName.Get( "tblW", DocX.w.NamespaceName ) ); tmp.AddAfterSelf( new XElement( XName.Get( "tblLayout", DocX.w.NamespaceName ) ) ); tmp = tblPr.Element( XName.Get( "tblLayout", DocX.w.NamespaceName ) ); tmp.SetAttributeValue( XName.Get( "type", DocX.w.NamespaceName ), "fixed" ); tmp = tblPr.Element( XName.Get( "tblW", DocX.w.NamespaceName ) ); Double totalWidth = 0; foreach( Double columnWidth in ColumnWidths ) { totalWidth += columnWidth; } tmp.SetAttributeValue( XName.Get( "w", DocX.w.NamespaceName ), totalWidth.ToString() ); break; } else { var types = from d in Xml.Descendants() let type = d.Attribute( XName.Get( "type", DocX.w.NamespaceName ) ) where ( d.Name.LocalName == "tblLayout" ) && type != null select type; foreach( XAttribute type in types ) { type.Value = "fixed"; } var tmp = tblPr.Element( XName.Get( "tblW", DocX.w.NamespaceName ) ); Double totalWidth = 0; foreach( Double columnWidth in ColumnWidths ) { totalWidth += columnWidth; } tmp.SetAttributeValue( XName.Get( "w", DocX.w.NamespaceName ), totalWidth.ToString() ); break; } } } // Set table attributes var query = from d in Xml.Descendants() let type = d.Attribute( XName.Get( "type", DocX.w.NamespaceName ) ) where ( d.Name.LocalName == "tblW" ) && type != null select type; foreach( XAttribute type in query ) { type.Value = tableAttributeValue; } // Set column attributes query = from d in Xml.Descendants() let type = d.Attribute( XName.Get( "type", DocX.w.NamespaceName ) ) where ( d.Name.LocalName == "tcW" ) && type != null select type; foreach( XAttribute type in query ) { type.Value = columnAttributeValue; } _autofit = value; } } /// /// The design\style to apply to this table. /// public TableDesign Design { get { return _design; } set { XElement tblPr = Xml.Element( XName.Get( "tblPr", DocX.w.NamespaceName ) ); XElement style = tblPr.Element( XName.Get( "tblStyle", DocX.w.NamespaceName ) ); if( style == null ) { tblPr.Add( new XElement( XName.Get( "tblStyle", DocX.w.NamespaceName ) ) ); style = tblPr.Element( XName.Get( "tblStyle", DocX.w.NamespaceName ) ); } XAttribute val = style.Attribute( XName.Get( "val", DocX.w.NamespaceName ) ); if( val == null ) { style.Add( new XAttribute( XName.Get( "val", DocX.w.NamespaceName ), "" ) ); val = style.Attribute( XName.Get( "val", DocX.w.NamespaceName ) ); } _design = value; if( _design == TableDesign.None ) { if( style != null ) style.Remove(); } if( _design == TableDesign.Custom ) { if( string.IsNullOrEmpty( _customTableDesignName ) ) { _design = TableDesign.None; if( style != null ) style.Remove(); } else { val.Value = _customTableDesignName; } } else { switch( _design ) { case TableDesign.TableNormal: val.Value = "TableNormal"; break; case TableDesign.TableGrid: val.Value = "TableGrid"; break; case TableDesign.LightShading: val.Value = "LightShading"; break; case TableDesign.LightShadingAccent1: val.Value = "LightShading-Accent1"; break; case TableDesign.LightShadingAccent2: val.Value = "LightShading-Accent2"; break; case TableDesign.LightShadingAccent3: val.Value = "LightShading-Accent3"; break; case TableDesign.LightShadingAccent4: val.Value = "LightShading-Accent4"; break; case TableDesign.LightShadingAccent5: val.Value = "LightShading-Accent5"; break; case TableDesign.LightShadingAccent6: val.Value = "LightShading-Accent6"; break; case TableDesign.LightList: val.Value = "LightList"; break; case TableDesign.LightListAccent1: val.Value = "LightList-Accent1"; break; case TableDesign.LightListAccent2: val.Value = "LightList-Accent2"; break; case TableDesign.LightListAccent3: val.Value = "LightList-Accent3"; break; case TableDesign.LightListAccent4: val.Value = "LightList-Accent4"; break; case TableDesign.LightListAccent5: val.Value = "LightList-Accent5"; break; case TableDesign.LightListAccent6: val.Value = "LightList-Accent6"; break; case TableDesign.LightGrid: val.Value = "LightGrid"; break; case TableDesign.LightGridAccent1: val.Value = "LightGrid-Accent1"; break; case TableDesign.LightGridAccent2: val.Value = "LightGrid-Accent2"; break; case TableDesign.LightGridAccent3: val.Value = "LightGrid-Accent3"; break; case TableDesign.LightGridAccent4: val.Value = "LightGrid-Accent4"; break; case TableDesign.LightGridAccent5: val.Value = "LightGrid-Accent5"; break; case TableDesign.LightGridAccent6: val.Value = "LightGrid-Accent6"; break; case TableDesign.MediumShading1: val.Value = "MediumShading1"; break; case TableDesign.MediumShading1Accent1: val.Value = "MediumShading1-Accent1"; break; case TableDesign.MediumShading1Accent2: val.Value = "MediumShading1-Accent2"; break; case TableDesign.MediumShading1Accent3: val.Value = "MediumShading1-Accent3"; break; case TableDesign.MediumShading1Accent4: val.Value = "MediumShading1-Accent4"; break; case TableDesign.MediumShading1Accent5: val.Value = "MediumShading1-Accent5"; break; case TableDesign.MediumShading1Accent6: val.Value = "MediumShading1-Accent6"; break; case TableDesign.MediumShading2: val.Value = "MediumShading2"; break; case TableDesign.MediumShading2Accent1: val.Value = "MediumShading2-Accent1"; break; case TableDesign.MediumShading2Accent2: val.Value = "MediumShading2-Accent2"; break; case TableDesign.MediumShading2Accent3: val.Value = "MediumShading2-Accent3"; break; case TableDesign.MediumShading2Accent4: val.Value = "MediumShading2-Accent4"; break; case TableDesign.MediumShading2Accent5: val.Value = "MediumShading2-Accent5"; break; case TableDesign.MediumShading2Accent6: val.Value = "MediumShading2-Accent6"; break; case TableDesign.MediumList1: val.Value = "MediumList1"; break; case TableDesign.MediumList1Accent1: val.Value = "MediumList1-Accent1"; break; case TableDesign.MediumList1Accent2: val.Value = "MediumList1-Accent2"; break; case TableDesign.MediumList1Accent3: val.Value = "MediumList1-Accent3"; break; case TableDesign.MediumList1Accent4: val.Value = "MediumList1-Accent4"; break; case TableDesign.MediumList1Accent5: val.Value = "MediumList1-Accent5"; break; case TableDesign.MediumList1Accent6: val.Value = "MediumList1-Accent6"; break; case TableDesign.MediumList2: val.Value = "MediumList2"; break; case TableDesign.MediumList2Accent1: val.Value = "MediumList2-Accent1"; break; case TableDesign.MediumList2Accent2: val.Value = "MediumList2-Accent2"; break; case TableDesign.MediumList2Accent3: val.Value = "MediumList2-Accent3"; break; case TableDesign.MediumList2Accent4: val.Value = "MediumList2-Accent4"; break; case TableDesign.MediumList2Accent5: val.Value = "MediumList2-Accent5"; break; case TableDesign.MediumList2Accent6: val.Value = "MediumList2-Accent6"; break; case TableDesign.MediumGrid1: val.Value = "MediumGrid1"; break; case TableDesign.MediumGrid1Accent1: val.Value = "MediumGrid1-Accent1"; break; case TableDesign.MediumGrid1Accent2: val.Value = "MediumGrid1-Accent2"; break; case TableDesign.MediumGrid1Accent3: val.Value = "MediumGrid1-Accent3"; break; case TableDesign.MediumGrid1Accent4: val.Value = "MediumGrid1-Accent4"; break; case TableDesign.MediumGrid1Accent5: val.Value = "MediumGrid1-Accent5"; break; case TableDesign.MediumGrid1Accent6: val.Value = "MediumGrid1-Accent6"; break; case TableDesign.MediumGrid2: val.Value = "MediumGrid2"; break; case TableDesign.MediumGrid2Accent1: val.Value = "MediumGrid2-Accent1"; break; case TableDesign.MediumGrid2Accent2: val.Value = "MediumGrid2-Accent2"; break; case TableDesign.MediumGrid2Accent3: val.Value = "MediumGrid2-Accent3"; break; case TableDesign.MediumGrid2Accent4: val.Value = "MediumGrid2-Accent4"; break; case TableDesign.MediumGrid2Accent5: val.Value = "MediumGrid2-Accent5"; break; case TableDesign.MediumGrid2Accent6: val.Value = "MediumGrid2-Accent6"; break; case TableDesign.MediumGrid3: val.Value = "MediumGrid3"; break; case TableDesign.MediumGrid3Accent1: val.Value = "MediumGrid3-Accent1"; break; case TableDesign.MediumGrid3Accent2: val.Value = "MediumGrid3-Accent2"; break; case TableDesign.MediumGrid3Accent3: val.Value = "MediumGrid3-Accent3"; break; case TableDesign.MediumGrid3Accent4: val.Value = "MediumGrid3-Accent4"; break; case TableDesign.MediumGrid3Accent5: val.Value = "MediumGrid3-Accent5"; break; case TableDesign.MediumGrid3Accent6: val.Value = "MediumGrid3-Accent6"; break; case TableDesign.DarkList: val.Value = "DarkList"; break; case TableDesign.DarkListAccent1: val.Value = "DarkList-Accent1"; break; case TableDesign.DarkListAccent2: val.Value = "DarkList-Accent2"; break; case TableDesign.DarkListAccent3: val.Value = "DarkList-Accent3"; break; case TableDesign.DarkListAccent4: val.Value = "DarkList-Accent4"; break; case TableDesign.DarkListAccent5: val.Value = "DarkList-Accent5"; break; case TableDesign.DarkListAccent6: val.Value = "DarkList-Accent6"; break; case TableDesign.ColorfulShading: val.Value = "ColorfulShading"; break; case TableDesign.ColorfulShadingAccent1: val.Value = "ColorfulShading-Accent1"; break; case TableDesign.ColorfulShadingAccent2: val.Value = "ColorfulShading-Accent2"; break; case TableDesign.ColorfulShadingAccent3: val.Value = "ColorfulShading-Accent3"; break; case TableDesign.ColorfulShadingAccent4: val.Value = "ColorfulShading-Accent4"; break; case TableDesign.ColorfulShadingAccent5: val.Value = "ColorfulShading-Accent5"; break; case TableDesign.ColorfulShadingAccent6: val.Value = "ColorfulShading-Accent6"; break; case TableDesign.ColorfulList: val.Value = "ColorfulList"; break; case TableDesign.ColorfulListAccent1: val.Value = "ColorfulList-Accent1"; break; case TableDesign.ColorfulListAccent2: val.Value = "ColorfulList-Accent2"; break; case TableDesign.ColorfulListAccent3: val.Value = "ColorfulList-Accent3"; break; case TableDesign.ColorfulListAccent4: val.Value = "ColorfulList-Accent4"; break; case TableDesign.ColorfulListAccent5: val.Value = "ColorfulList-Accent5"; break; case TableDesign.ColorfulListAccent6: val.Value = "ColorfulList-Accent6"; break; case TableDesign.ColorfulGrid: val.Value = "ColorfulGrid"; break; case TableDesign.ColorfulGridAccent1: val.Value = "ColorfulGrid-Accent1"; break; case TableDesign.ColorfulGridAccent2: val.Value = "ColorfulGrid-Accent2"; break; case TableDesign.ColorfulGridAccent3: val.Value = "ColorfulGrid-Accent3"; break; case TableDesign.ColorfulGridAccent4: val.Value = "ColorfulGrid-Accent4"; break; case TableDesign.ColorfulGridAccent5: val.Value = "ColorfulGrid-Accent5"; break; case TableDesign.ColorfulGridAccent6: val.Value = "ColorfulGrid-Accent6"; break; default: break; } } if( Document._styles == null ) { PackagePart word_styles = Document._package.GetPart( new Uri( "/word/styles.xml", UriKind.Relative ) ); using( TextReader tr = new StreamReader( word_styles.GetStream() ) ) Document._styles = XDocument.Load( tr ); } var tableStyle = ( from e in Document._styles.Descendants() let styleId = e.Attribute( XName.Get( "styleId", DocX.w.NamespaceName ) ) where ( styleId != null && styleId.Value == val.Value ) select e ).FirstOrDefault(); if( tableStyle == null ) { XDocument external_style_doc = HelperFunctions.DecompressXMLResource( "Xceed.Words.NET.Resources.styles.xml.gz" ); var styleElement = ( from e in external_style_doc.Descendants() let styleId = e.Attribute( XName.Get( "styleId", DocX.w.NamespaceName ) ) where ( styleId != null && styleId.Value == val.Value ) select e ).First(); Document._styles.Element( XName.Get( "styles", DocX.w.NamespaceName ) ).Add( styleElement ); } } } /// /// Returns the index of this Table. /// /// /// Replace the first table in this document with a new Table. /// /// // Load a document into memory. /// using (DocX document = DocX.Load(@"Test.docx")) /// { /// // Get the first Table in this document. /// Table t = document.Tables[0]; /// /// // Get the character index of Table t in this document. /// int index = t.Index; /// /// // Remove Table t. /// t.Remove(); /// /// // Insert a new Table at the original index of Table t. /// Table newTable = document.InsertTable(index, 4, 4); /// /// // Set the design of this new Table, so that we can see it. /// newTable.Design = TableDesign.LightShadingAccent1; /// /// // Save all changes made to the document. /// document.Save(); /// } // Release this document from memory. /// /// public int Index { get { int index = 0; IEnumerable previous = Xml.ElementsBeforeSelf(); foreach( XElement e in previous ) index += Paragraph.GetElementTextLength( e ); return index; } } /// /// The custom design/style to apply to this table. /// public string CustomTableDesignName { get { return _customTableDesignName; } set { _customTableDesignName = value; this.Design = TableDesign.Custom; } } /// /// Gets or sets the value of the Table Caption (Alternate Text Title) of this table. /// public string TableCaption { get { var tblPr = Xml.Element( XName.Get( "tblPr", DocX.w.NamespaceName ) ); var caption = tblPr?.Element( XName.Get( "tblCaption", DocX.w.NamespaceName ) ); if( caption != null ) return caption.GetAttribute( XName.Get( "val", DocX.w.NamespaceName ) ); return null; } set { var tblPr = Xml.Element( XName.Get( "tblPr", DocX.w.NamespaceName ) ); if( tblPr != null ) { var caption = tblPr.Descendants( XName.Get( "tblCaption", DocX.w.NamespaceName ) ).FirstOrDefault(); if( caption != null ) { caption.Remove(); } caption = new XElement( XName.Get( "tblCaption", DocX.w.NamespaceName ), new XAttribute( XName.Get( "val", DocX.w.NamespaceName ), value ) ); tblPr.Add( caption ); } } } /// /// Gets or sets the value of the Table Description (Alternate Text Description) of this table. /// public string TableDescription { get { var tblPr = Xml.Element( XName.Get( "tblPr", DocX.w.NamespaceName ) ); var description = tblPr?.Element( XName.Get( "tblDescription", DocX.w.NamespaceName ) ); if( description != null ) return description.GetAttribute( XName.Get( "val", DocX.w.NamespaceName ) ); return null; } set { var tblPr = Xml.Element( XName.Get( "tblPr", DocX.w.NamespaceName ) ); if( tblPr != null ) { var description = tblPr.Descendants( XName.Get( "tblDescription", DocX.w.NamespaceName ) ).FirstOrDefault(); description?.Remove(); description = new XElement( XName.Get( "tblDescription", DocX.w.NamespaceName ), new XAttribute( XName.Get( "val", DocX.w.NamespaceName ), value ) ); tblPr.Add( description ); } } } public TableLook TableLook { get; set; } #endregion #region Constructors internal Table( DocX document, XElement xml ) : base( document, xml ) { _autofit = AutoFit.ColumnWidth; this.Xml = xml; this.PackagePart = document.PackagePart; var properties = xml.Element( XName.Get( "tblPr", DocX.w.NamespaceName ) ); var alignment = properties.Element( XName.Get( "jc", DocX.w.NamespaceName ) ); if( alignment != null ) { var val = alignment.Attribute( XName.Get( "val", DocX.w.NamespaceName ) ); if( val != null ) { _alignment = (Alignment)Enum.Parse( typeof( Alignment ), val.Value ); } } var style = properties?.Element( XName.Get( "tblStyle", DocX.w.NamespaceName ) ); if( style != null ) { var val = style.Attribute( XName.Get( "val", DocX.w.NamespaceName ) ); if( val != null ) { String cleanValue = val.Value.Replace( "-", string.Empty ); if( Enum.IsDefined( typeof( TableDesign ), cleanValue ) ) { _design = ( TableDesign )Enum.Parse( typeof( TableDesign ), cleanValue ); } else { _design = TableDesign.Custom; } } else { _design = TableDesign.None; } } else { _design = TableDesign.None; } var tableLook = properties?.Element( XName.Get( "tblLook", DocX.w.NamespaceName ) ); if( tableLook != null ) { this.TableLook = new TableLook( tableLook.GetAttribute( XName.Get( "firstRow", DocX.w.NamespaceName ) ) == "1", tableLook.GetAttribute( XName.Get( "lastRow", DocX.w.NamespaceName ) ) == "1", tableLook.GetAttribute( XName.Get( "firstColumn", DocX.w.NamespaceName ) ) == "1", tableLook.GetAttribute( XName.Get( "lastColumn", DocX.w.NamespaceName ) ) == "1", tableLook.GetAttribute( XName.Get( "noHBand", DocX.w.NamespaceName ) ) == "1", tableLook.GetAttribute( XName.Get( "noVBand", DocX.w.NamespaceName ) ) == "1" ); } } #endregion #region Public Methods /// /// Merge cells in given column starting with startRow and ending with endRow. /// public void MergeCellsInColumn( int columnIndex, int startRow, int endRow ) { // Check for valid start and end indexes. if( columnIndex < 0 || columnIndex >= ColumnCount ) throw new IndexOutOfRangeException(); if( startRow < 0 || endRow <= startRow || endRow >= Rows.Count ) throw new IndexOutOfRangeException(); // Foreach each Cell between startIndex and endIndex inclusive. foreach( Row row in Rows.Where( ( z, i ) => i > startRow && i <= endRow ) ) { var c = row.Cells[ columnIndex ]; var tcPr = c.Xml.Element( XName.Get( "tcPr", DocX.w.NamespaceName ) ); if( tcPr == null ) { c.Xml.SetElementValue( XName.Get( "tcPr", DocX.w.NamespaceName ), string.Empty ); tcPr = c.Xml.Element( XName.Get( "tcPr", DocX.w.NamespaceName ) ); } var vMerge = tcPr.Element( XName.Get( "vMerge", DocX.w.NamespaceName ) ); if( vMerge == null ) { tcPr.SetElementValue( XName.Get( "vMerge", DocX.w.NamespaceName ), string.Empty ); vMerge = tcPr.Element( XName.Get( "vMerge", DocX.w.NamespaceName ) ); } } /* * Get the tcPr (table cell properties) element for the first cell in this merge, * null will be returned if no such element exists. */ var startRowCellsCount = this.Rows[ startRow ].Cells.Count; var start_tcPr = ( columnIndex > startRowCellsCount ) ? this.Rows[ startRow ].Cells[ startRowCellsCount - 1 ].Xml.Element( XName.Get( "tcPr", DocX.w.NamespaceName ) ) : this.Rows[ startRow ].Cells[ columnIndex ].Xml.Element( XName.Get( "tcPr", DocX.w.NamespaceName ) ); if( start_tcPr == null ) { this.Rows[ startRow ].Cells[ columnIndex ].Xml.SetElementValue( XName.Get( "tcPr", DocX.w.NamespaceName ), string.Empty ); start_tcPr = this.Rows[ startRow ].Cells[ columnIndex ].Xml.Element( XName.Get( "tcPr", DocX.w.NamespaceName ) ); } /* * Get the gridSpan element of this row, * null will be returned if no such element exists. */ var start_vMerge = start_tcPr.Element( XName.Get( "vMerge", DocX.w.NamespaceName ) ); if( start_vMerge == null ) { start_tcPr.SetElementValue( XName.Get( "vMerge", DocX.w.NamespaceName ), string.Empty ); start_vMerge = start_tcPr.Element( XName.Get( "vMerge", DocX.w.NamespaceName ) ); } start_vMerge.SetAttributeValue( XName.Get( "val", DocX.w.NamespaceName ), "restart" ); } /// /// Set the direction of all content in this Table. /// /// (Left to Right) or (Right to Left) /// /// Set the content direction for all content in a table to RightToLeft. /// /// // Load a document. /// using (DocX document = DocX.Load(@"Test.docx")) /// { /// // Get the first table in a document. /// Table table = document.Tables[0]; /// /// // Set the content direction for all content in this table to RightToLeft. /// table.SetDirection(Direction.RightToLeft); /// /// // Save all changes made to this document. /// document.Save(); /// } /// /// public void SetDirection( Direction direction ) { var tblPr = GetOrCreate_tblPr(); tblPr.Add( new XElement( DocX.w + "bidiVisual" ) ); foreach( Row r in Rows ) { r.SetDirection( direction ); } } /// /// Remove this Table from this document. /// /// /// Remove the first Table from this document. /// /// // Load a document into memory. /// using (DocX document = DocX.Load(@"Test.docx")) /// { /// // Get the first Table in this document. /// Table t = d.Tables[0]; /// /// // Remove this Table. /// t.Remove(); /// /// // Save all changes made to the document. /// document.Save(); /// } // Release this document from memory. /// /// public void Remove() { this.Xml.Remove(); } /// /// Insert a row at the end of this table. /// /// /// /// // Load a document. /// using (DocX document = DocX.Load(@"C:\Example\Test.docx")) /// { /// // Get the first table in this document. /// Table table = document.Tables[0]; /// /// // Insert a new row at the end of this table. /// Row row = table.InsertRow(); /// /// // Loop through each cell in this new row. /// foreach (Cell c in row.Cells) /// { /// // Set the text of each new cell to "Hello". /// c.Paragraphs[0].InsertText("Hello", false); /// } /// /// // Save the document to a new file. /// document.SaveAs(@"C:\Example\Test2.docx"); /// }// Release this document from memory. /// /// /// A new row. public Row InsertRow() { return this.InsertRow( this.RowCount ); } /// /// Insert a copy of a row at the end of this table. /// /// A new row. public Row InsertRow( Row row ) { return this.InsertRow( row, this.RowCount ); } /// /// Insert a column to the right of a Table. /// /// /// /// // Load a document. /// using (DocX document = DocX.Load(@"C:\Example\Test.docx")) /// { /// // Get the first Table in this document. /// Table table = document.Tables[0]; /// /// // Insert a new column to this right of this table. /// table.InsertColumn(); /// /// // Set the new columns text to "Row no." /// table.Rows[0].Cells[table.ColumnCount - 1].Paragraph.InsertText("Row no.", false); /// /// // Loop through each row in the table. /// for (int i = 1; i < table.Rows.Count; i++) /// { /// // The current row. /// Row row = table.Rows[i]; /// /// // The cell in this row that belongs to the new column. /// Cell cell = row.Cells[table.ColumnCount - 1]; /// /// // The first Paragraph that this cell houses. /// Paragraph p = cell.Paragraphs[0]; /// /// // Insert this rows index. /// p.InsertText(i.ToString(), false); /// } /// /// document.Save(); /// }// Release this document from memory. /// /// public void InsertColumn() { this.InsertColumn( this.ColumnCount, true ); } /// /// Remove the last row from this Table. /// /// /// Remove the last row from a Table. /// /// // Load a document. /// using (DocX document = DocX.Load(@"C:\Example\Test.docx")) /// { /// // Get the first table in this document. /// Table table = document.Tables[0]; /// /// // Remove the last row from this table. /// table.RemoveRow(); /// /// // Save the document. /// document.Save(); /// }// Release this document from memory. /// /// public void RemoveRow() { this.RemoveRow( RowCount - 1 ); } /// /// Remove a row from this Table. /// /// The row to remove. /// /// Remove the first row from a Table. /// /// // Load a document. /// using (DocX document = DocX.Load(@"C:\Example\Test.docx")) /// { /// // Get the first table in this document. /// Table table = document.Tables[0]; /// /// // Remove the first row from this table. /// table.RemoveRow(0); /// /// // Save the document. /// document.Save(); /// }// Release this document from memory. /// /// public void RemoveRow( int index ) { if( index < 0 || index > RowCount - 1 ) throw new IndexOutOfRangeException(); this.Rows[ index ].Xml.Remove(); if( this.Rows.Count == 0 ) { this.Remove(); } } /// /// Remove the last column for this Table. /// /// /// Remove the last column from a Table. /// /// // Load a document. /// using (DocX document = DocX.Load(@"C:\Example\Test.docx")) /// { /// // Get the first table in this document. /// Table table = document.Tables[0]; /// /// // Remove the last column from this table. /// table.RemoveColumn(); /// /// // Save the document. /// document.Save(); /// }// Release this document from memory. /// /// public void RemoveColumn() { this.RemoveColumn( this.ColumnCount - 1 ); } /// /// Remove a column from this Table. /// /// The column to remove. /// /// Remove the first column from a Table. /// /// // Load a document. /// using (DocX document = DocX.Load(@"C:\Example\Test.docx")) /// { /// // Get the first table in this document. /// Table table = document.Tables[0]; /// /// // Remove the first column from this table. /// table.RemoveColumn(0); /// /// // Save the document. /// document.Save(); /// }// Release this document from memory. /// /// public void RemoveColumn( int index ) { if( ( index < 0 ) || ( index > this.ColumnCount - 1 ) ) throw new IndexOutOfRangeException(); foreach( Row r in Rows ) { if( r.Cells.Count < this.ColumnCount ) { int gridAfterValue = r.GridAfter; int posIndex = 0; int currentPos = 0; for( int i = 0; i < r.Cells.Count; ++i ) { var rowCell = r.Cells[ i ]; int gridSpanValue = ( rowCell.GridSpan != 0 ) ? rowCell.GridSpan - 1 : 0; // checks to see if index is between the lowest and highest cell value. if( ( ( index - gridAfterValue ) >= currentPos ) && ( ( index - gridAfterValue ) <= ( currentPos + gridSpanValue ) ) ) { r.Cells[ posIndex ].Xml.Remove(); break; } ++posIndex; currentPos += ( gridSpanValue + 1 ); } } else { r.Cells[ index ].Xml.Remove(); } } _cachedColumnCount = -1; } /// /// Insert a row into this table. /// /// /// /// // Load a document. /// using (DocX document = DocX.Load(@"C:\Example\Test.docx")) /// { /// // Get the first table in this document. /// Table table = document.Tables[0]; /// /// // Insert a new row at index 1 in this table. /// Row row = table.InsertRow(1); /// /// // Loop through each cell in this new row. /// foreach (Cell c in row.Cells) /// { /// // Set the text of each new cell to "Hello". /// c.Paragraphs[0].InsertText("Hello", false); /// } /// /// // Save the document to a new file. /// document.SaveAs(@"C:\Example\Test2.docx"); /// }// Release this document from memory. /// /// /// Index to insert row at. /// A new Row public Row InsertRow( int index ) { if( ( index < 0 ) || ( index > this.RowCount ) ) throw new IndexOutOfRangeException(); var content = new List(); for( int i = 0; i < ColumnCount; i++ ) { var cell = ( ( _columnWidths != null ) && ( _columnWidths.Length > i ) ) ? HelperFunctions.CreateTableCell( _columnWidths[ i ] * 20 ) : HelperFunctions.CreateTableCell(); content.Add( cell ); } return this.InsertRow( content, index ); } /// /// Insert a copy of a row into this table. /// /// Row to copy and insert. /// Index to insert row at. /// A new Row public Row InsertRow( Row row, int index ) { if( row == null ) throw new ArgumentNullException( "row" ); if( index < 0 || index > RowCount ) throw new IndexOutOfRangeException(); var content = row.Xml.Elements( XName.Get( "tc", DocX.w.NamespaceName ) ).Select( element => HelperFunctions.CloneElement( element ) ).ToList(); return this.InsertRow( content, index ); } /// /// Insert a column into a table. /// /// The index to insert the column at. /// The side in which you wish to place the colum : True for right, false for left. /// /// Insert a column to the left of a table. /// /// // Load a document. /// using (DocX document = DocX.Load(@"C:\Example\Test.docx")) /// { /// // Get the first Table in this document. /// Table table = document.Tables[0]; /// /// // Insert a new column to this left of this table. /// table.InsertColumn(0, false); /// /// // Set the new columns text to "Row no." /// table.Rows[0].Cells[table.ColumnCount - 1].Paragraph.InsertText("Row no.", false); /// /// // Loop through each row in the table. /// for (int i = 1; i < table.Rows.Count; i++) /// { /// // The current row. /// Row row = table.Rows[i]; /// /// // The cell in this row that belongs to the new column. /// Cell cell = row.Cells[table.ColumnCount - 1]; /// /// // The first Paragraph that this cell houses. /// Paragraph p = cell.Paragraphs[0]; /// /// // Insert this rows index. /// p.InsertText(i.ToString(), false); /// } /// /// document.Save(); /// }// Release this document from memory. /// /// public void InsertColumn( int index, bool direction ) { var colCount = this.ColumnCount; if( (index <= 0) && (index > colCount ) ) throw new NullReferenceException( "index should be greater than 0 and smaller or equals to this.ColumnCount." ); if( this.RowCount > 0 ) { _cachedColumnCount = -1; foreach( Row r in this.Rows ) { // create cell var cell = HelperFunctions.CreateTableCell(); // insert cell if( r.Cells.Count < colCount ) { if( index >= colCount ) { this.AddCellToRow( r, cell, r.Cells.Count - 1, direction ); } else { int gridAfterValue = r.GridAfter; int currentPosition = 1; int posIndex = 1; foreach( var rowCell in r.Cells ) { int gridSpanValue = ( rowCell.GridSpan != 0 ) ? rowCell.GridSpan - 1 : 0; var tcPr = rowCell.Xml.Element( XName.Get( "tcPr", DocX.w.NamespaceName ) ); // Check if the cell have a gridSpan and if the index is between the lowest and highest cell value if( ( ( index - gridAfterValue ) >= currentPosition ) && ( ( index - gridAfterValue ) <= ( currentPosition + gridSpanValue ) ) ) { var dir = ( direction && ( index == ( currentPosition + gridSpanValue ) ) ); this.AddCellToRow( r, cell, posIndex - 1, dir ); break; } ++posIndex; currentPosition += (gridSpanValue + 1); } } } else { this.AddCellToRow( r, cell, index - 1, direction ); } } } } /// /// Insert a page break before a Table. /// /// /// Insert a Table and a Paragraph into a document with a page break between them. /// /// // Create a new document. /// using (DocX document = DocX.Create(@"Test.docx")) /// { /// // Insert a new Paragraph. /// Paragraph p1 = document.InsertParagraph("Paragraph", false); /// /// // Insert a new Table. /// Table t1 = document.InsertTable(2, 2); /// t1.Design = TableDesign.LightShadingAccent1; /// /// // Insert a page break before this Table. /// t1.InsertPageBreakBeforeSelf(); /// /// // Save this document. /// document.Save(); /// }// Release this document from memory. /// /// public override void InsertPageBreakBeforeSelf() { base.InsertPageBreakBeforeSelf(); } public void SetWidths( float[] widths ) { _columnWidths = widths; for( int i = 0; i < this.Rows.Count; ++i ) { var row = this.Rows[ i ]; for( int j = 0; j < widths.Length; ++j ) { if( row.Cells.Count > j ) { row.Cells[ j ].Width = widths[ j ]; } } } } public void SetWidthsPercentage( float[] widthsPercentage, float? totalWidth ) { if( totalWidth == null ) totalWidth = this.Document.PageWidth - this.Document.MarginLeft - this.Document.MarginRight; List widths = new List( widthsPercentage.Length ); widthsPercentage.ToList().ForEach( pWidth => { widths.Add( ( pWidth * totalWidth.Value / 100 ) * ( 96 / 72 ) ); } ); SetWidths( widths.ToArray() ); } /// /// Insert a page break after a Table. /// /// /// Insert a Table and a Paragraph into a document with a page break between them. /// /// // Create a new document. /// using (DocX document = DocX.Create(@"Test.docx")) /// { /// // Insert a new Table. /// Table t1 = document.InsertTable(2, 2); /// t1.Design = TableDesign.LightShadingAccent1; /// /// // Insert a page break after this Table. /// t1.InsertPageBreakAfterSelf(); /// /// // Insert a new Paragraph. /// Paragraph p1 = document.InsertParagraph("Paragraph", false); /// /// // Save this document. /// document.Save(); /// }// Release this document from memory. /// /// public override void InsertPageBreakAfterSelf() { base.InsertPageBreakAfterSelf(); } /// /// Insert a new Table before this Table, this Table can be from this document or another document. /// /// The Table t to be inserted /// A new Table inserted before this Table. /// /// Insert a new Table before this Table. /// /// // Place holder for a Table. /// Table t; /// /// // Load document a. /// using (DocX documentA = DocX.Load(@"a.docx")) /// { /// // Get the first Table from this document. /// t = documentA.Tables[0]; /// } /// /// // Load document b. /// using (DocX documentB = DocX.Load(@"b.docx")) /// { /// // Get the first Table in document b. /// Table t2 = documentB.Tables[0]; /// /// // Insert the Table from document a before this Table. /// Table newTable = t2.InsertTableBeforeSelf(t); /// /// // Save all changes made to document b. /// documentB.Save(); /// }// Release this document from memory. /// /// public override Table InsertTableBeforeSelf( Table t ) { return base.InsertTableBeforeSelf( t ); } /// /// Insert a new Table into this document before this Table. /// /// The number of rows this Table should have. /// The number of columns this Table should have. /// A new Table inserted before this Table. /// /// /// // Create a new document. /// using (DocX document = DocX.Create(@"Test.docx")) /// { /// //Insert a Table into this document. /// Table t = document.InsertTable(2, 2); /// t.Design = TableDesign.LightShadingAccent1; /// t.Alignment = Alignment.center; /// /// // Insert a new Table before this Table. /// Table newTable = t.InsertTableBeforeSelf(2, 2); /// newTable.Design = TableDesign.LightShadingAccent2; /// newTable.Alignment = Alignment.center; /// /// // Save all changes made to this document. /// document.Save(); /// }// Release this document from memory. /// /// public override Table InsertTableBeforeSelf( int rowCount, int columnCount ) { return base.InsertTableBeforeSelf( rowCount, columnCount ); } /// /// Insert a new Table after this Table, this Table can be from this document or another document. /// /// The Table t to be inserted /// A new Table inserted after this Table. /// /// Insert a new Table after this Table. /// /// // Place holder for a Table. /// Table t; /// /// // Load document a. /// using (DocX documentA = DocX.Load(@"a.docx")) /// { /// // Get the first Table from this document. /// t = documentA.Tables[0]; /// } /// /// // Load document b. /// using (DocX documentB = DocX.Load(@"b.docx")) /// { /// // Get the first Table in document b. /// Table t2 = documentB.Tables[0]; /// /// // Insert the Table from document a after this Table. /// Table newTable = t2.InsertTableAfterSelf(t); /// /// // Save all changes made to document b. /// documentB.Save(); /// }// Release this document from memory. /// /// public override Table InsertTableAfterSelf( Table t ) { return base.InsertTableAfterSelf( t ); } /// /// Insert a new Table into this document after this Table. /// /// The number of rows this Table should have. /// The number of columns this Table should have. /// A new Table inserted before this Table. /// /// /// // Create a new document. /// using (DocX document = DocX.Create(@"Test.docx")) /// { /// //Insert a Table into this document. /// Table t = document.InsertTable(2, 2); /// t.Design = TableDesign.LightShadingAccent1; /// t.Alignment = Alignment.center; /// /// // Insert a new Table after this Table. /// Table newTable = t.InsertTableAfterSelf(2, 2); /// newTable.Design = TableDesign.LightShadingAccent2; /// newTable.Alignment = Alignment.center; /// /// // Save all changes made to this document. /// document.Save(); /// }// Release this document from memory. /// /// public override Table InsertTableAfterSelf( int rowCount, int columnCount ) { return base.InsertTableAfterSelf( rowCount, columnCount ); } /// /// Insert a Paragraph before this Table, this Paragraph may have come from the same or another document. /// /// The Paragraph to insert. /// The Paragraph now associated with this document. /// /// Take a Paragraph from document a, and insert it into document b before this Table. /// /// // Place holder for a Paragraph. /// Paragraph p; /// /// // Load document a. /// using (DocX documentA = DocX.Load(@"a.docx")) /// { /// // Get the first paragraph from this document. /// p = documentA.Paragraphs[0]; /// } /// /// // Load document b. /// using (DocX documentB = DocX.Load(@"b.docx")) /// { /// // Get the first Table in document b. /// Table t = documentB.Tables[0]; /// /// // Insert the Paragraph from document a before this Table. /// Paragraph newParagraph = t.InsertParagraphBeforeSelf(p); /// /// // Save all changes made to document b. /// documentB.Save(); /// }// Release this document from memory. /// /// public override Paragraph InsertParagraphBeforeSelf( Paragraph p ) { return base.InsertParagraphBeforeSelf( p ); } /// /// Insert a new Paragraph before this Table. /// /// The initial text for this new Paragraph. /// A new Paragraph inserted before this Table. /// /// Insert a new Paragraph before the first Table in this document. /// /// // Create a new document. /// using (DocX document = DocX.Create(@"Test.docx")) /// { /// // Insert a Table into this document. /// Table t = document.InsertTable(2, 2); /// /// t.InsertParagraphBeforeSelf("I was inserted before the next Table."); /// /// // Save all changes made to this new document. /// document.Save(); /// }// Release this new document form memory. /// /// public override Paragraph InsertParagraphBeforeSelf( string text ) { return base.InsertParagraphBeforeSelf( text ); } /// /// Insert a new Paragraph before this Table. /// /// The initial text for this new Paragraph. /// Should this insertion be tracked as a change? /// A new Paragraph inserted before this Table. /// /// Insert a new paragraph before the first Table in this document. /// /// // Create a new document. /// using (DocX document = DocX.Create(@"Test.docx")) /// { /// // Insert a Table into this document. /// Table t = document.InsertTable(2, 2); /// /// t.InsertParagraphBeforeSelf("I was inserted before the next Table.", false); /// /// // Save all changes made to this new document. /// document.Save(); /// }// Release this new document form memory. /// /// public override Paragraph InsertParagraphBeforeSelf( string text, bool trackChanges ) { return base.InsertParagraphBeforeSelf( text, trackChanges ); } /// /// Insert a new Paragraph before this Table. /// /// The initial text for this new Paragraph. /// Should this insertion be tracked as a change? /// The formatting to apply to this insertion. /// A new Paragraph inserted before this Table. /// /// Insert a new paragraph before the first Table in this document. /// /// // Create a new document. /// using (DocX document = DocX.Create(@"Test.docx")) /// { /// // Insert a Table into this document. /// Table t = document.InsertTable(2, 2); /// /// Formatting boldFormatting = new Formatting(); /// boldFormatting.Bold = true; /// /// t.InsertParagraphBeforeSelf("I was inserted before the next Table.", false, boldFormatting); /// /// // Save all changes made to this new document. /// document.Save(); /// }// Release this new document form memory. /// /// public override Paragraph InsertParagraphBeforeSelf( string text, bool trackChanges, Formatting formatting ) { return base.InsertParagraphBeforeSelf( text, trackChanges, formatting ); } /// /// Insert a Paragraph after this Table, this Paragraph may have come from the same or another document. /// /// The Paragraph to insert. /// The Paragraph now associated with this document. /// /// Take a Paragraph from document a, and insert it into document b after this Table. /// /// // Place holder for a Paragraph. /// Paragraph p; /// /// // Load document a. /// using (DocX documentA = DocX.Load(@"a.docx")) /// { /// // Get the first paragraph from this document. /// p = documentA.Paragraphs[0]; /// } /// /// // Load document b. /// using (DocX documentB = DocX.Load(@"b.docx")) /// { /// // Get the first Table in document b. /// Table t = documentB.Tables[0]; /// /// // Insert the Paragraph from document a after this Table. /// Paragraph newParagraph = t.InsertParagraphAfterSelf(p); /// /// // Save all changes made to document b. /// documentB.Save(); /// }// Release this document from memory. /// /// public override Paragraph InsertParagraphAfterSelf( Paragraph p ) { return base.InsertParagraphAfterSelf( p ); } /// /// Insert a new Paragraph after this Table. /// /// The initial text for this new Paragraph. /// Should this insertion be tracked as a change? /// The formatting to apply to this insertion. /// A new Paragraph inserted after this Table. /// /// Insert a new paragraph after the first Table in this document. /// /// // Create a new document. /// using (DocX document = DocX.Create(@"Test.docx")) /// { /// // Insert a Table into this document. /// Table t = document.InsertTable(2, 2); /// /// Formatting boldFormatting = new Formatting(); /// boldFormatting.Bold = true; /// /// t.InsertParagraphAfterSelf("I was inserted after the previous Table.", false, boldFormatting); /// /// // Save all changes made to this new document. /// document.Save(); /// }// Release this new document form memory. /// /// public override Paragraph InsertParagraphAfterSelf( string text, bool trackChanges, Formatting formatting ) { return base.InsertParagraphAfterSelf( text, trackChanges, formatting ); } /// /// Insert a new Paragraph after this Table. /// /// The initial text for this new Paragraph. /// Should this insertion be tracked as a change? /// A new Paragraph inserted after this Table. /// /// Insert a new paragraph after the first Table in this document. /// /// // Create a new document. /// using (DocX document = DocX.Create(@"Test.docx")) /// { /// // Insert a Table into this document. /// Table t = document.InsertTable(2, 2); /// /// t.InsertParagraphAfterSelf("I was inserted after the previous Table.", false); /// /// // Save all changes made to this new document. /// document.Save(); /// }// Release this new document form memory. /// /// public override Paragraph InsertParagraphAfterSelf( string text, bool trackChanges ) { return base.InsertParagraphAfterSelf( text, trackChanges ); } /// /// Insert a new Paragraph after this Table. /// /// The initial text for this new Paragraph. /// A new Paragraph inserted after this Table. /// /// Insert a new Paragraph after the first Table in this document. /// /// // Create a new document. /// using (DocX document = DocX.Create(@"Test.docx")) /// { /// // Insert a Table into this document. /// Table t = document.InsertTable(2, 2); /// /// t.InsertParagraphAfterSelf("I was inserted after the previous Table."); /// /// // Save all changes made to this new document. /// document.Save(); /// }// Release this new document form memory. /// /// public override Paragraph InsertParagraphAfterSelf( string text ) { return base.InsertParagraphAfterSelf( text ); } /// /// Set a table border /// /// /// /// // Create a new document. ///using (DocX document = DocX.Create("Test.docx")) ///{ /// // Insert a table into this document. /// Table t = document.InsertTable(3, 3); /// /// // Create a large blue border. /// Border b = new Border(BorderStyle.Tcbs_single, BorderSize.seven, 0, Color.Blue); /// /// // Set the tables Top, Bottom, Left and Right Borders to b. /// t.SetBorder(TableBorderType.Top, b); /// t.SetBorder(TableBorderType.Bottom, b); /// t.SetBorder(TableBorderType.Left, b); /// t.SetBorder(TableBorderType.Right, b); /// /// // Save the document. /// document.Save(); ///} /// /// /// The table border to set /// Border object to set the table border public void SetBorder( TableBorderType borderType, Border border ) { /* * Get the tblPr (table properties) element for this Table, * null will be return if no such element exists. */ var tblPr = Xml.Element( XName.Get( "tblPr", DocX.w.NamespaceName ) ); if( tblPr == null ) { this.Xml.SetElementValue( XName.Get( "tblPr", DocX.w.NamespaceName ), string.Empty ); tblPr = Xml.Element( XName.Get( "tblPr", DocX.w.NamespaceName ) ); } /* * Get the tblBorders (table borders) element for this Table, * null will be return if no such element exists. */ var tblBorders = tblPr.Element( XName.Get( "tblBorders", DocX.w.NamespaceName ) ); if( tblBorders == null ) { tblPr.SetElementValue( XName.Get( "tblBorders", DocX.w.NamespaceName ), string.Empty ); tblBorders = tblPr.Element( XName.Get( "tblBorders", DocX.w.NamespaceName ) ); } /* * Get the 'borderType' (table border) element for this Table, * null will be return if no such element exists. */ string tbordertype; tbordertype = borderType.ToString(); // only lower the first char of string (because of insideH and insideV) tbordertype = tbordertype.Substring( 0, 1 ).ToLower() + tbordertype.Substring( 1 ); var tblBorderType = tblBorders.Element( XName.Get( borderType.ToString(), DocX.w.NamespaceName ) ); if( tblBorderType == null ) { tblBorders.SetElementValue( XName.Get( tbordertype, DocX.w.NamespaceName ), string.Empty ); tblBorderType = tblBorders.Element( XName.Get( tbordertype, DocX.w.NamespaceName ) ); } // get string value of border style var borderstyle = border.Tcbs.ToString().Substring( 5 ); borderstyle = borderstyle.Substring( 0, 1 ).ToLower() + borderstyle.Substring( 1 ); // The val attribute is used for the border style tblBorderType.SetAttributeValue( XName.Get( "val", DocX.w.NamespaceName ), borderstyle ); if( border.Tcbs != BorderStyle.Tcbs_nil ) { int size; switch( border.Size ) { case BorderSize.one: size = 2; break; case BorderSize.two: size = 4; break; case BorderSize.three: size = 6; break; case BorderSize.four: size = 8; break; case BorderSize.five: size = 12; break; case BorderSize.six: size = 18; break; case BorderSize.seven: size = 24; break; case BorderSize.eight: size = 36; break; case BorderSize.nine: size = 48; break; default: size = 2; break; } // The sz attribute is used for the border size tblBorderType.SetAttributeValue( XName.Get( "sz", DocX.w.NamespaceName ), ( size ).ToString() ); // The space attribute is used for the cell spacing (probably '0') tblBorderType.SetAttributeValue( XName.Get( "space", DocX.w.NamespaceName ), ( border.Space ).ToString() ); // The color attribute is used for the border color tblBorderType.SetAttributeValue( XName.Get( "color", DocX.w.NamespaceName ), border.Color.ToHex() ); } } /// /// Get a table border /// /// The table border to get public Border GetBorder( TableBorderType borderType ) { // instance with default border values var b = new Border(); /* * Get the tblPr (table properties) element for this Table, * null will be return if no such element exists. */ var tblPr = Xml.Element( XName.Get( "tblPr", DocX.w.NamespaceName ) ); if( tblPr == null ) { // uses default border style } /* * Get the tblBorders (table borders) element for this Table, * null will be return if no such element exists. */ var tblBorders = tblPr.Element( XName.Get( "tblBorders", DocX.w.NamespaceName ) ); if( tblBorders == null ) { // uses default border style } /* * Get the 'borderType' (table border) element for this Table, * null will be return if no such element exists. */ string tbordertype = borderType.ToString(); // only lower the first char of string (because of insideH and insideV) tbordertype = tbordertype.Substring( 0, 1 ).ToLower() + tbordertype.Substring( 1 ); var tblBorderType = tblBorders.Element( XName.Get( tbordertype, DocX.w.NamespaceName ) ); if( tblBorderType == null ) { // uses default border style } // The val attribute is used for the border style var val = tblBorderType.Attribute( XName.Get( "val", DocX.w.NamespaceName ) ); // If val is null, this table contains no border information. if( val == null ) { // uses default border style } else { try { var bordertype = "Tcbs_" + val.Value; b.Tcbs = ( BorderStyle )Enum.Parse( typeof( BorderStyle ), bordertype ); } catch { val.Remove(); // uses default border style } } // The sz attribute is used for the border size var sz = tblBorderType.Attribute( XName.Get( "sz", DocX.w.NamespaceName ) ); // If sz is null, this border contains no size information. if( sz == null ) { // uses default border style } else { // If sz is not an int, something is wrong with this attributes value, so remove it int numerical_size; if( !int.TryParse( sz.Value, out numerical_size ) ) { sz.Remove(); } else { switch( numerical_size ) { case 2: b.Size = BorderSize.one; break; case 4: b.Size = BorderSize.two; break; case 6: b.Size = BorderSize.three; break; case 8: b.Size = BorderSize.four; break; case 12: b.Size = BorderSize.five; break; case 18: b.Size = BorderSize.six; break; case 24: b.Size = BorderSize.seven; break; case 36: b.Size = BorderSize.eight; break; case 48: b.Size = BorderSize.nine; break; default: b.Size = BorderSize.one; break; } } } // The space attribute is used for the border spacing (probably '0') var space = tblBorderType.Attribute( XName.Get( "space", DocX.w.NamespaceName ) ); // If space is null, this border contains no space information. if( space == null ) { // uses default border style } else { // If space is not an int, something is wrong with this attributes value, so remove it int borderspace; if( !int.TryParse( space.Value, out borderspace ) ) { space.Remove(); // uses default border style } else { b.Space = borderspace; } } // The color attribute is used for the border color var color = tblBorderType.Attribute( XName.Get( "color", DocX.w.NamespaceName ) ); if( color == null ) { // uses default border style } else { // If color is not a Color, something is wrong with this attributes value, so remove it try { b.Color = ColorTranslator.FromHtml( string.Format( "#{0}", color.Value ) ); } catch { color.Remove(); // uses default border style } } return b; } public Double GetColumnWidth( Int32 columnIndex ) { List columnWidths = ColumnWidths; if( columnWidths == null || columnIndex > columnWidths.Count - 1 ) return Double.NaN; return columnWidths[ columnIndex ]; } public void SetColumnWidth( int columnIndex, double width ) { var columnWidths = this.ColumnWidths; if( columnWidths == null || ( columnIndex > columnWidths.Count - 1 ) ) { if( this.Rows.Count == 0 ) throw new Exception( "There is at least one row required to detect the existing columns." ); columnWidths = new List(); foreach( Cell c in Rows[ Rows.Count - 1 ].Cells ) { columnWidths.Add( c.Width ); } } // check if the columnIndex is valid if( columnIndex > (columnWidths.Count - 1) ) throw new Exception( "The index is greather than the available table columns." ); // append a new grid if null var grid = Xml.Element( XName.Get( "tblGrid", DocX.w.NamespaceName ) ); if( grid == null ) { var tblPr = GetOrCreate_tblPr(); tblPr.AddAfterSelf( new XElement( XName.Get( "tblGrid", DocX.w.NamespaceName ) ) ); grid = Xml.Element( XName.Get( "tblGrid", DocX.w.NamespaceName ) ); } // remove all existing values grid?.RemoveAll(); // append new column widths int index = 0; foreach( var columnWidth in columnWidths ) { double newWidth = columnWidth; if( index == columnIndex ) { newWidth = width; } var newColumn = new XElement( XName.Get( "gridCol", DocX.w.NamespaceName ), new XAttribute( XName.Get( "w", DocX.w.NamespaceName ), newWidth ) ); grid?.Add( newColumn ); index += 1; } // remove cell widths foreach( Row row in this.Rows ) { foreach( Cell cell in row.Cells ) { cell.Width = -1; } } // set AutoFit to Fixed this.AutoFit = AutoFit.Fixed; } public List ColumnWidths { get { var columnWidths = new List(); // get the table grid property XElement grid = Xml.Element( XName.Get( "tblGrid", DocX.w.NamespaceName ) ); // get the columns properties var columns = grid?.Elements( XName.Get( "gridCol", DocX.w.NamespaceName ) ); if( columns == null ) return null; foreach( var column in columns ) { string value = column.GetAttribute( XName.Get( "w", DocX.w.NamespaceName ) ); columnWidths.Add( Convert.ToDouble( value, new CultureInfo("en-US" ) ) ); } return columnWidths; } } public void SetTableCellMargin( TableCellMarginType type, double margin ) { var tblPr = this.GetOrCreate_tblPr(); var tblCellMarXName = XName.Get( "tblCellMar", DocX.w.NamespaceName ); var typeXName = XName.Get( type.ToString(), DocX.w.NamespaceName ); var tblCellMar = tblPr.Element( tblCellMarXName ); if( tblCellMar == null ) { tblPr.AddFirst( new XElement( tblCellMarXName ) ); tblCellMar = tblPr.Element( tblCellMarXName ); } var side = tblCellMar.Element( typeXName ); if( side == null ) { tblCellMar.AddFirst( new XElement( typeXName ) ); side = tblCellMar.Element( typeXName ); } side.RemoveAttributes(); // Set value and side for cell Margin side.Add( new XAttribute( XName.Get( "w", DocX.w.NamespaceName ), margin ) ); side.Add( new XAttribute( XName.Get( "type", DocX.w.NamespaceName ), "dxa" ) ); } /// /// Deletes a cell in a row and shift the others to the left. /// /// index of the row where a cell will be removed. /// index of the cell to remove in the row. public void DeleteAndShiftCellsLeft( int rowIndex, int celIndex ) { var trPr = this.Rows[ rowIndex ].Xml.Element( XName.Get( "trPr", DocX.w.NamespaceName ) ); if( trPr != null ) { var gridAfter = trPr.Element( XName.Get( "gridAfter", DocX.w.NamespaceName ) ); if( gridAfter != null ) { var gridAfterValAttr = gridAfter.Attribute( XName.Get( "val", DocX.w.NamespaceName ) ); gridAfterValAttr.Value = ( gridAfterValAttr != null ) ? int.Parse( gridAfterValAttr.Value ).ToString() : "1"; } else { gridAfter.SetAttributeValue( "val", 1 ); } } else { var gridAfterXElement = new XElement( XName.Get( "gridAfter", DocX.w.NamespaceName ) ); var valXAttribute = new XAttribute( XName.Get( "val", DocX.w.NamespaceName ), 1 ); gridAfterXElement.Add( valXAttribute ); var trPrXElement = new XElement( XName.Get( "trPr", DocX.w.NamespaceName ) ); trPrXElement.Add( gridAfterXElement ); this.Rows[ rowIndex ].Xml.AddFirst( trPrXElement ); } if( ( celIndex <= this.ColumnCount ) && ( this.Rows[ rowIndex ].ColumnCount <= this.ColumnCount ) ) { this.Rows[ rowIndex ].Cells[ celIndex ].Xml.Remove(); } } #endregion #region Internal Methods /// /// If the tblPr element doesent exist it is created, either way it is returned by this function. /// /// The tblPr element for this Table. internal XElement GetOrCreate_tblPr() { // Get the element. var tblPr = Xml.Element( XName.Get( "tblPr", DocX.w.NamespaceName ) ); // If it dosen't exist, create it. if( tblPr == null ) { this.Xml.AddFirst( new XElement( XName.Get( "tblPr", DocX.w.NamespaceName ) ) ); tblPr = Xml.Element( XName.Get( "tblPr", DocX.w.NamespaceName ) ); } // Return the pPr element for this Paragraph. return tblPr; } #endregion #region Private Methods private Row InsertRow( List content, Int32 index ) { Row newRow = new Row( this, Document, new XElement( XName.Get( "tr", DocX.w.NamespaceName ), content ) ); XElement rowXml; if( index == Rows.Count ) { rowXml = Rows.Last().Xml; rowXml.AddAfterSelf( newRow.Xml ); } else { rowXml = Rows[ index ].Xml; rowXml.AddBeforeSelf( newRow.Xml ); } return newRow; } private void AddCellToRow( Row row, XElement cell, int index, bool direction ) { if( index >= row.Cells.Count ) throw new IndexOutOfRangeException( "index is greater or equals to row.Cells.Count." ); if( direction ) { row.Cells[ index ].Xml.AddAfterSelf( cell ); } else { row.Cells[ index ].Xml.AddBeforeSelf( cell ); } } #endregion } /// /// Represents a single row in a Table. /// public class Row : Container { #region Internal Members internal Table _table; #endregion #region Public Properties /// /// Calculates columns count in the row, taking spanned cells into account /// public Int32 ColumnCount { get { int gridSpanSum = this.GridAfter; // Foreach each Cell between startIndex and endIndex inclusive. foreach( Cell c in Cells ) { if( c.GridSpan != 0 ) { gridSpanSum += (c.GridSpan - 1); } } // return cells count + count of spanned cells return Cells.Count + gridSpanSum; } } /// /// Returns the row.GridAfter => The number of deleted cells in a row. /// public int GridAfter { get { var trPr = this.Xml.Element( XName.Get( "trPr", DocX.w.NamespaceName ) ); if( trPr != null ) { var gridAfter = trPr.Element( XName.Get( "gridAfter", DocX.w.NamespaceName ) ); var gridAfterAttrVal = gridAfter?.Attribute( XName.Get( "val", DocX.w.NamespaceName ) ); if( gridAfterAttrVal != null ) { return int.Parse( gridAfterAttrVal.Value ); } } return 0; } } /// /// A list of Cells in this Row. /// public List Cells { get { List cells = ( from c in Xml.Elements( XName.Get( "tc", DocX.w.NamespaceName ) ) select new Cell( this, Document, c ) ).ToList(); return cells; } } public override ReadOnlyCollection Paragraphs { get { var paragraphs = ( from p in Xml.Descendants( DocX.w + "p" ) select new Paragraph( Document, p, 0 ) ).ToList(); foreach( Paragraph p in paragraphs ) { p.PackagePart = _table.PackagePart; } return paragraphs.AsReadOnly(); } } /// /// Height in pixels. /// public double Height { get { /* * Get the trPr (table row properties) element for this Row, * null will be return if no such element exists. */ XElement trPr = Xml.Element( XName.Get( "trPr", DocX.w.NamespaceName ) ); // If trPr is null, this row contains no height information. // Get the trHeight element for this Row, // null will be return if no such element exists. XElement trHeight = trPr?.Element( XName.Get( "trHeight", DocX.w.NamespaceName ) ); // If trHeight is null, this row contains no height information. // Get the val attribute for this trHeight element. XAttribute val = trHeight?.Attribute( XName.Get( "val", DocX.w.NamespaceName ) ); // If w is null, this cell contains no width information. if( val == null ) return double.NaN; // If val is not a double, something is wrong with this attributes value, so remove it and return double.NaN; double heightInWordUnits; if( !double.TryParse( val.Value, out heightInWordUnits ) ) { val.Remove(); return double.NaN; } // Using 20 to match DocX._pageSizeMultiplier. return ( heightInWordUnits / 20 ); } set { SetHeight( value, true ); } } /// /// Minimum Height in pixels. /// public double MinHeight { get { return Height; } set { SetHeight( value, false ); } } public bool TableHeader { get { XElement trPr = Xml.Element( XName.Get( "trPr", DocX.w.NamespaceName ) ); XElement tblHeader = trPr?.Element( XName.Get( "tblHeader", DocX.w.NamespaceName ) ); return tblHeader != null; } set { XElement trPr = Xml.Element( XName.Get( "trPr", DocX.w.NamespaceName ) ); if( trPr == null ) { Xml.SetElementValue( XName.Get( "trPr", DocX.w.NamespaceName ), string.Empty ); trPr = Xml.Element( XName.Get( "trPr", DocX.w.NamespaceName ) ); } XElement tblHeader = trPr.Element( XName.Get( "tblHeader", DocX.w.NamespaceName ) ); if( tblHeader == null && value ) trPr.SetElementValue( XName.Get( "tblHeader", DocX.w.NamespaceName ), string.Empty ); if( tblHeader != null && !value ) tblHeader.Remove(); } } /// /// Allow row to break across pages. /// Default value is True : Word will break the contents of the row across the pages. /// When False, the contents of the row will not be split across the pages; it will be entirely moved to the next page. /// public bool BreakAcrossPages { get { var trPr = Xml.Element( XName.Get( "trPr", DocX.w.NamespaceName ) ); var cantSplit = trPr?.Element( XName.Get( "cantSplit", DocX.w.NamespaceName ) ); return cantSplit == null; } set { var trPrXName = XName.Get( "trPr", DocX.w.NamespaceName ); var cantSplitXName = XName.Get( "cantSplit", DocX.w.NamespaceName ); if( value ) { var trPr = Xml.Element( trPrXName ); var cantSplit = trPr?.Element( cantSplitXName ); if( cantSplit != null ) cantSplit.Remove(); } else { var trPr = Xml.Element( trPrXName ); if( trPr == null ) { Xml.SetElementValue( trPrXName, string.Empty ); trPr = Xml.Element( trPrXName ); } var cantSplit = trPr.Element( cantSplitXName ); if( cantSplit == null ) { trPr.SetElementValue( cantSplitXName, string.Empty ); } } } } #endregion #region Constructors internal Row( Table table, DocX document, XElement xml ) : base( document, xml ) { _table = table; this.PackagePart = table.PackagePart; } #endregion #region Private Methods private void SetHeight( double height, bool isHeightExact ) { XElement trPr = Xml.Element( XName.Get( "trPr", DocX.w.NamespaceName ) ); if( trPr == null ) { Xml.SetElementValue( XName.Get( "trPr", DocX.w.NamespaceName ), string.Empty ); trPr = Xml.Element( XName.Get( "trPr", DocX.w.NamespaceName ) ); } XElement trHeight = trPr.Element( XName.Get( "trHeight", DocX.w.NamespaceName ) ); if( trHeight == null ) { trPr.SetElementValue( XName.Get( "trHeight", DocX.w.NamespaceName ), string.Empty ); trHeight = trPr.Element( XName.Get( "trHeight", DocX.w.NamespaceName ) ); } // The hRule attribute needs to be set. trHeight.SetAttributeValue( XName.Get( "hRule", DocX.w.NamespaceName ), isHeightExact ? "exact" : "atLeast" ); // Using 20 to match DocX._pageSizeMultiplier. trHeight.SetAttributeValue( XName.Get( "val", DocX.w.NamespaceName ), ( height * 20 ).ToString() ); } #endregion #region Public Methods public void Remove() { XElement table = Xml.Parent; Xml.Remove(); if( !table.Elements( XName.Get( "tr", DocX.w.NamespaceName ) ).Any() ) table.Remove(); } /// /// Merge cells starting with startIndex and ending with endIndex. /// public void MergeCells( int startIndex, int endIndex ) { // Check for valid start and end indexes. if( startIndex < 0 || endIndex <= startIndex || endIndex > Cells.Count + 1 ) throw new IndexOutOfRangeException(); // The sum of all merged gridSpans. int gridSpanSum = 0; // Foreach each Cell between startIndex and endIndex inclusive. foreach( Cell c in Cells.Where( ( z, i ) => i > startIndex && i <= endIndex ) ) { XElement tcPr = c.Xml.Element( XName.Get( "tcPr", DocX.w.NamespaceName ) ); XElement gridSpan = tcPr?.Element( XName.Get( "gridSpan", DocX.w.NamespaceName ) ); if( gridSpan != null ) { XAttribute val = gridSpan.Attribute( XName.Get( "val", DocX.w.NamespaceName ) ); int value; if( val != null && int.TryParse( val.Value, out value ) ) gridSpanSum += value - 1; } // Add this cells Pragraph to the merge start Cell. Cells[ startIndex ].Xml.Add( c.Xml.Elements( XName.Get( "p", DocX.w.NamespaceName ) ) ); // Remove this Cell. c.Xml.Remove(); } // Trim cell's paragraphs to remove extra blank lines, if any int index = 0; do { // If the cell doesn't have multiple paragraphs, leave the loop if ( Cells[ startIndex ].Paragraphs.Count < 2 ) break; // Remove the last paragraph if it's a blank line, otherwise trimming is done index = Cells[ startIndex ].Paragraphs.Count - 1; if ( Cells[ startIndex ].Paragraphs[ index ].Text.Trim() == "" ) Cells[ startIndex ].Paragraphs[ index ].Remove( false ); else break; } while( true ); /* * Get the tcPr (table cell properties) element for the first cell in this merge, * null will be returned if no such element exists. */ XElement start_tcPr = Cells[ startIndex ].Xml.Element( XName.Get( "tcPr", DocX.w.NamespaceName ) ); if( start_tcPr == null ) { Cells[ startIndex ].Xml.SetElementValue( XName.Get( "tcPr", DocX.w.NamespaceName ), string.Empty ); start_tcPr = Cells[ startIndex ].Xml.Element( XName.Get( "tcPr", DocX.w.NamespaceName ) ); } /* * Get the gridSpan element of this row, * null will be returned if no such element exists. */ XElement start_gridSpan = start_tcPr.Element( XName.Get( "gridSpan", DocX.w.NamespaceName ) ); if( start_gridSpan == null ) { start_tcPr.SetElementValue( XName.Get( "gridSpan", DocX.w.NamespaceName ), string.Empty ); start_gridSpan = start_tcPr.Element( XName.Get( "gridSpan", DocX.w.NamespaceName ) ); } /* * Get the val attribute of this row, * null will be returned if no such element exists. */ XAttribute start_val = start_gridSpan.Attribute( XName.Get( "val", DocX.w.NamespaceName ) ); int start_value = 0; if( start_val != null ) if( int.TryParse( start_val.Value, out start_value ) ) gridSpanSum += start_value - 1; // Set the val attribute to the number of merged cells. start_gridSpan.SetAttributeValue( XName.Get( "val", DocX.w.NamespaceName ), ( gridSpanSum + ( endIndex - startIndex + 1 ) ).ToString() ); } #endregion } public class Cell : Container { #region Internal Members internal Row _row; #endregion #region Public Properties public override ReadOnlyCollection Paragraphs { get { var paragraphs = base.Paragraphs; foreach( Paragraph p in paragraphs ) { p.PackagePart = _row._table.PackagePart; } return paragraphs; } } /// /// Gets or Sets this Cells vertical alignment. /// /// /// Creates a table with 3 cells and sets the vertical alignment of each to 1 of the 3 available options. /// ///// Create a new document. ///using(DocX document = DocX.Create("Test.docx")) ///{ /// // Insert a Table into this document. /// Table t = document.InsertTable(3, 1); /// /// // Set the design of the Table such that we can easily identify cell boundaries. /// t.Design = TableDesign.TableGrid; /// /// // Set the height of the row bigger than default. /// // We need to be able to see the difference in vertical cell alignment options. /// t.Rows[0].Height = 100; /// /// // Set the vertical alignment of cell0 to top. /// Cell c0 = t.Rows[0].Cells[0]; /// c0.InsertParagraph("VerticalAlignment.Top"); /// c0.VerticalAlignment = VerticalAlignment.Top; /// /// // Set the vertical alignment of cell1 to center. /// Cell c1 = t.Rows[0].Cells[1]; /// c1.InsertParagraph("VerticalAlignment.Center"); /// c1.VerticalAlignment = VerticalAlignment.Center; /// /// // Set the vertical alignment of cell2 to bottom. /// Cell c2 = t.Rows[0].Cells[2]; /// c2.InsertParagraph("VerticalAlignment.Bottom"); /// c2.VerticalAlignment = VerticalAlignment.Bottom; /// /// // Save the document. /// document.Save(); ///} /// /// public VerticalAlignment VerticalAlignment { get { /* * Get the tcPr (table cell properties) element for this Cell, * null will be return if no such element exists. */ XElement tcPr = Xml.Element( XName.Get( "tcPr", DocX.w.NamespaceName ) ); // If tcPr is null, this cell contains no width information. // Get the vAlign (table cell vertical alignment) element for this Cell, // null will be return if no such element exists. XElement vAlign = tcPr?.Element( XName.Get( "vAlign", DocX.w.NamespaceName ) ); // If vAlign is null, this cell contains no vertical alignment information. // Get the val attribute of the vAlign element. XAttribute val = vAlign?.Attribute( XName.Get( "val", DocX.w.NamespaceName ) ); // If val is null, this cell contains no vAlign information. if( val == null ) return VerticalAlignment.Center; // If val is not a VerticalAlign enum, something is wrong with this attributes value, so remove it and return VerticalAlignment.Center; try { return ( VerticalAlignment )Enum.Parse( typeof( VerticalAlignment ), val.Value, true ); } catch { val.Remove(); return VerticalAlignment.Center; } } set { /* * Get the tcPr (table cell properties) element for this Cell, * null will be return if no such element exists. */ XElement tcPr = Xml.Element( XName.Get( "tcPr", DocX.w.NamespaceName ) ); if( tcPr == null ) { Xml.SetElementValue( XName.Get( "tcPr", DocX.w.NamespaceName ), string.Empty ); tcPr = Xml.Element( XName.Get( "tcPr", DocX.w.NamespaceName ) ); } /* * Get the vAlign (table cell vertical alignment) element for this Cell, * null will be return if no such element exists. */ XElement vAlign = tcPr.Element( XName.Get( "vAlign", DocX.w.NamespaceName ) ); if( vAlign == null ) { tcPr.SetElementValue( XName.Get( "vAlign", DocX.w.NamespaceName ), string.Empty ); vAlign = tcPr.Element( XName.Get( "vAlign", DocX.w.NamespaceName ) ); } // Set the VerticalAlignment in 'val' vAlign.SetAttributeValue( XName.Get( "val", DocX.w.NamespaceName ), value.ToString().ToLower() ); } } public Color Shading { get { /* * Get the tcPr (table cell properties) element for this Cell, * null will be return if no such element exists. */ XElement tcPr = Xml.Element( XName.Get( "tcPr", DocX.w.NamespaceName ) ); // If tcPr is null, this cell contains no Color information. // Get the shd (table shade) element for this Cell, // null will be return if no such element exists. XElement shd = tcPr?.Element( XName.Get( "shd", DocX.w.NamespaceName ) ); // If shd is null, this cell contains no Color information. // Get the w attribute of the tcW element. XAttribute fill = shd?.Attribute( XName.Get( "fill", DocX.w.NamespaceName ) ); // If fill is null, this cell contains no Color information. if( fill == null ) return Color.White; return ColorTranslator.FromHtml( string.Format( "#{0}", fill.Value ) ); } set { /* * Get the tcPr (table cell properties) element for this Cell, * null will be return if no such element exists. */ XElement tcPr = Xml.Element( XName.Get( "tcPr", DocX.w.NamespaceName ) ); if( tcPr == null ) { Xml.SetElementValue( XName.Get( "tcPr", DocX.w.NamespaceName ), string.Empty ); tcPr = Xml.Element( XName.Get( "tcPr", DocX.w.NamespaceName ) ); } /* * Get the shd (table shade) element for this Cell, * null will be return if no such element exists. */ XElement shd = tcPr.Element( XName.Get( "shd", DocX.w.NamespaceName ) ); if( shd == null ) { tcPr.SetElementValue( XName.Get( "shd", DocX.w.NamespaceName ), string.Empty ); shd = tcPr.Element( XName.Get( "shd", DocX.w.NamespaceName ) ); } // The val attribute needs to be set to clear shd.SetAttributeValue( XName.Get( "val", DocX.w.NamespaceName ), "clear" ); // The color attribute needs to be set to auto shd.SetAttributeValue( XName.Get( "color", DocX.w.NamespaceName ), "auto" ); // The fill attribute needs to be set to the hex for this Color. shd.SetAttributeValue( XName.Get( "fill", DocX.w.NamespaceName ), value.ToHex() ); } } /// /// Width in pixels. /// public double Width { get { /* * Get the tcPr (table cell properties) element for this Cell, * null will be return if no such element exists. */ XElement tcPr = Xml.Element( XName.Get( "tcPr", DocX.w.NamespaceName ) ); // If tcPr is null, this cell contains no width information. // Get the tcW (table cell width) element for this Cell, // null will be return if no such element exists. XElement tcW = tcPr?.Element( XName.Get( "tcW", DocX.w.NamespaceName ) ); // If tcW is null, this cell contains no width information. // Get the w attribute of the tcW element. XAttribute w = tcW?.Attribute( XName.Get( "w", DocX.w.NamespaceName ) ); // If w is null, this cell contains no width information. if( w == null ) return double.NaN; // If w is not a double, something is wrong with this attributes value, so remove it and return double.NaN; double widthInWordUnits; if( !double.TryParse( w.Value, out widthInWordUnits ) ) { w.Remove(); return double.NaN; } // Using 20 to match DocX._pageSizeMultiplier. return ( widthInWordUnits / 20 ); } set { /* * Get the tcPr (table cell properties) element for this Cell, * null will be return if no such element exists. */ XElement tcPr = Xml.Element( XName.Get( "tcPr", DocX.w.NamespaceName ) ); if( tcPr == null ) { Xml.SetElementValue( XName.Get( "tcPr", DocX.w.NamespaceName ), string.Empty ); tcPr = Xml.Element( XName.Get( "tcPr", DocX.w.NamespaceName ) ); } /* * Get the tcW (table cell width) element for this Cell, * null will be return if no such element exists. */ XElement tcW = tcPr.Element( XName.Get( "tcW", DocX.w.NamespaceName ) ); if( tcW == null ) { tcPr.SetElementValue( XName.Get( "tcW", DocX.w.NamespaceName ), string.Empty ); tcW = tcPr.Element( XName.Get( "tcW", DocX.w.NamespaceName ) ); } if( value == -1 ) { // remove cell width; due to set on table prop. tcW.Remove(); return; } // The type attribute needs to be set to dxa which represents "twips" or twentieths of a point. In other words, 1/1440th of an inch. tcW.SetAttributeValue( XName.Get( "type", DocX.w.NamespaceName ), "dxa" ); // Using 20 to match DocX._pageSizeMultiplier. tcW.SetAttributeValue( XName.Get( "w", DocX.w.NamespaceName ), ( value * 20 ).ToString() ); } } /// /// LeftMargin in pixels. /// /// /// /// // Create a new document. ///using (DocX document = DocX.Create("Test.docx")) ///{ /// // Insert table into this document. /// Table t = document.InsertTable(3, 3); /// t.Design = TableDesign.TableGrid; /// /// // Get the center cell. /// Cell center = t.Rows[1].Cells[1]; /// /// // Insert some text so that we can see the effect of the Margins. /// center.Paragraphs[0].Append("Center Cell"); /// /// // Set the center cells Left, Margin to 10. /// center.MarginLeft = 25; /// /// // Save the document. /// document.Save(); ///} /// /// public double MarginLeft { get { /* * Get the tcPr (table cell properties) element for this Cell, * null will be return if no such element exists. */ XElement tcPr = Xml.Element( XName.Get( "tcPr", DocX.w.NamespaceName ) ); // If tcPr is null, this cell contains no width information. if( tcPr == null ) return double.NaN; /* * Get the tcMar * */ XElement tcMar = tcPr.Element( XName.Get( "tcMar", DocX.w.NamespaceName ) ); // If tcMar is null, this cell contains no margin information. // Get the left (LeftMargin) element XElement tcMarLeft = tcMar?.Element( XName.Get( "left", DocX.w.NamespaceName ) ); // If tcMarLeft is null, this cell contains no left margin information. // Get the w attribute of the tcMarLeft element. XAttribute w = tcMarLeft?.Attribute( XName.Get( "w", DocX.w.NamespaceName ) ); // If w is null, this cell contains no width information. if( w == null ) return double.NaN; // If w is not a double, something is wrong with this attributes value, so remove it and return double.NaN; double leftMarginInWordUnits; if( !double.TryParse( w.Value, out leftMarginInWordUnits ) ) { w.Remove(); return double.NaN; } // Using 20 to match DocX._pageSizeMultiplier. return ( leftMarginInWordUnits / 20 ); } set { /* * Get the tcPr (table cell properties) element for this Cell, * null will be return if no such element exists. */ XElement tcPr = Xml.Element( XName.Get( "tcPr", DocX.w.NamespaceName ) ); if( tcPr == null ) { Xml.SetElementValue( XName.Get( "tcPr", DocX.w.NamespaceName ), string.Empty ); tcPr = Xml.Element( XName.Get( "tcPr", DocX.w.NamespaceName ) ); } /* * Get the tcMar (table cell margin) element for this Cell, * null will be return if no such element exists. */ XElement tcMar = tcPr.Element( XName.Get( "tcMar", DocX.w.NamespaceName ) ); if( tcMar == null ) { tcPr.SetElementValue( XName.Get( "tcMar", DocX.w.NamespaceName ), string.Empty ); tcMar = tcPr.Element( XName.Get( "tcMar", DocX.w.NamespaceName ) ); } /* * Get the left (table cell left margin) element for this Cell, * null will be return if no such element exists. */ XElement tcMarLeft = tcMar.Element( XName.Get( "left", DocX.w.NamespaceName ) ); if( tcMarLeft == null ) { tcMar.SetElementValue( XName.Get( "left", DocX.w.NamespaceName ), string.Empty ); tcMarLeft = tcMar.Element( XName.Get( "left", DocX.w.NamespaceName ) ); } // The type attribute needs to be set to dxa which represents "twips" or twentieths of a point. In other words, 1/1440th of an inch. tcMarLeft.SetAttributeValue( XName.Get( "type", DocX.w.NamespaceName ), "dxa" ); // Using 20 to match DocX._pageSizeMultiplier. tcMarLeft.SetAttributeValue( XName.Get( "w", DocX.w.NamespaceName ), ( value * 20 ).ToString() ); } } /// /// RightMargin in pixels. /// /// /// /// // Create a new document. ///using (DocX document = DocX.Create("Test.docx")) ///{ /// // Insert table into this document. /// Table t = document.InsertTable(3, 3); /// t.Design = TableDesign.TableGrid; /// /// // Get the center cell. /// Cell center = t.Rows[1].Cells[1]; /// /// // Insert some text so that we can see the effect of the Margins. /// center.Paragraphs[0].Append("Center Cell"); /// /// // Set the center cells Right, Margin to 10. /// center.MarginRight = 25; /// /// // Save the document. /// document.Save(); ///} /// /// public double MarginRight { get { /* * Get the tcPr (table cell properties) element for this Cell, * null will be return if no such element exists. */ XElement tcPr = Xml.Element( XName.Get( "tcPr", DocX.w.NamespaceName ) ); // If tcPr is null, this cell contains no width information. if( tcPr == null ) return double.NaN; /* * Get the tcMar * */ XElement tcMar = tcPr.Element( XName.Get( "tcMar", DocX.w.NamespaceName ) ); // If tcMar is null, this cell contains no margin information. // Get the right (RightMargin) element XElement tcMarRight = tcMar?.Element( XName.Get( "right", DocX.w.NamespaceName ) ); // If tcMarRight is null, this cell contains no right margin information. // Get the w attribute of the tcMarRight element. XAttribute w = tcMarRight?.Attribute( XName.Get( "w", DocX.w.NamespaceName ) ); // If w is null, this cell contains no width information. if( w == null ) return double.NaN; // If w is not a double, something is wrong with this attributes value, so remove it and return double.NaN; double rightMarginInWordUnits; if( !double.TryParse( w.Value, out rightMarginInWordUnits ) ) { w.Remove(); return double.NaN; } // Using 20 to match DocX._pageSizeMultiplier. return ( rightMarginInWordUnits / 20 ); } set { /* * Get the tcPr (table cell properties) element for this Cell, * null will be return if no such element exists. */ XElement tcPr = Xml.Element( XName.Get( "tcPr", DocX.w.NamespaceName ) ); if( tcPr == null ) { Xml.SetElementValue( XName.Get( "tcPr", DocX.w.NamespaceName ), string.Empty ); tcPr = Xml.Element( XName.Get( "tcPr", DocX.w.NamespaceName ) ); } /* * Get the tcMar (table cell margin) element for this Cell, * null will be return if no such element exists. */ XElement tcMar = tcPr.Element( XName.Get( "tcMar", DocX.w.NamespaceName ) ); if( tcMar == null ) { tcPr.SetElementValue( XName.Get( "tcMar", DocX.w.NamespaceName ), string.Empty ); tcMar = tcPr.Element( XName.Get( "tcMar", DocX.w.NamespaceName ) ); } /* * Get the right (table cell right margin) element for this Cell, * null will be return if no such element exists. */ XElement tcMarRight = tcMar.Element( XName.Get( "right", DocX.w.NamespaceName ) ); if( tcMarRight == null ) { tcMar.SetElementValue( XName.Get( "right", DocX.w.NamespaceName ), string.Empty ); tcMarRight = tcMar.Element( XName.Get( "right", DocX.w.NamespaceName ) ); } // The type attribute needs to be set to dxa which represents "twips" or twentieths of a point. In other words, 1/1440th of an inch. tcMarRight.SetAttributeValue( XName.Get( "type", DocX.w.NamespaceName ), "dxa" ); // Using 20 to match DocX._pageSizeMultiplier. tcMarRight.SetAttributeValue( XName.Get( "w", DocX.w.NamespaceName ), ( value * 20 ).ToString() ); } } /// /// TopMargin in pixels. /// /// /// /// // Create a new document. ///using (DocX document = DocX.Create("Test.docx")) ///{ /// // Insert table into this document. /// Table t = document.InsertTable(3, 3); /// t.Design = TableDesign.TableGrid; /// /// // Get the center cell. /// Cell center = t.Rows[1].Cells[1]; /// /// // Insert some text so that we can see the effect of the Margins. /// center.Paragraphs[0].Append("Center Cell"); /// /// // Set the center cells Top, Margin to 10. /// center.MarginTop = 25; /// /// // Save the document. /// document.Save(); ///} /// /// public double MarginTop { get { /* * Get the tcPr (table cell properties) element for this Cell, * null will be return if no such element exists. */ XElement tcPr = Xml.Element( XName.Get( "tcPr", DocX.w.NamespaceName ) ); // If tcPr is null, this cell contains no width information. if( tcPr == null ) return double.NaN; /* * Get the tcMar * */ XElement tcMar = tcPr.Element( XName.Get( "tcMar", DocX.w.NamespaceName ) ); // If tcMar is null, this cell contains no margin information. // Get the top (TopMargin) element XElement tcMarTop = tcMar?.Element( XName.Get( "top", DocX.w.NamespaceName ) ); // If tcMarTop is null, this cell contains no top margin information. // Get the w attribute of the tcMarTop element. XAttribute w = tcMarTop?.Attribute( XName.Get( "w", DocX.w.NamespaceName ) ); // If w is null, this cell contains no width information. if( w == null ) return double.NaN; // If w is not a double, something is wrong with this attributes value, so remove it and return double.NaN; double topMarginInWordUnits; if( !double.TryParse( w.Value, out topMarginInWordUnits ) ) { w.Remove(); return double.NaN; } // Using 20 to match DocX._pageSizeMultiplier. return ( topMarginInWordUnits / 20 ); } set { /* * Get the tcPr (table cell properties) element for this Cell, * null will be return if no such element exists. */ XElement tcPr = Xml.Element( XName.Get( "tcPr", DocX.w.NamespaceName ) ); if( tcPr == null ) { Xml.SetElementValue( XName.Get( "tcPr", DocX.w.NamespaceName ), string.Empty ); tcPr = Xml.Element( XName.Get( "tcPr", DocX.w.NamespaceName ) ); } /* * Get the tcMar (table cell margin) element for this Cell, * null will be return if no such element exists. */ XElement tcMar = tcPr.Element( XName.Get( "tcMar", DocX.w.NamespaceName ) ); if( tcMar == null ) { tcPr.SetElementValue( XName.Get( "tcMar", DocX.w.NamespaceName ), string.Empty ); tcMar = tcPr.Element( XName.Get( "tcMar", DocX.w.NamespaceName ) ); } /* * Get the top (table cell top margin) element for this Cell, * null will be return if no such element exists. */ XElement tcMarTop = tcMar.Element( XName.Get( "top", DocX.w.NamespaceName ) ); if( tcMarTop == null ) { tcMar.SetElementValue( XName.Get( "top", DocX.w.NamespaceName ), string.Empty ); tcMarTop = tcMar.Element( XName.Get( "top", DocX.w.NamespaceName ) ); } // The type attribute needs to be set to dxa which represents "twips" or twentieths of a point. In other words, 1/1440th of an inch. tcMarTop.SetAttributeValue( XName.Get( "type", DocX.w.NamespaceName ), "dxa" ); // Using 20 to match DocX._pageSizeMultiplier. tcMarTop.SetAttributeValue( XName.Get( "w", DocX.w.NamespaceName ), ( value * 20 ).ToString() ); } } /// /// BottomMargin in pixels. /// /// /// /// // Create a new document. ///using (DocX document = DocX.Create("Test.docx")) ///{ /// // Insert table into this document. /// Table t = document.InsertTable(3, 3); /// t.Design = TableDesign.TableGrid; /// /// // Get the center cell. /// Cell center = t.Rows[1].Cells[1]; /// /// // Insert some text so that we can see the effect of the Margins. /// center.Paragraphs[0].Append("Center Cell"); /// /// // Set the center cells Top, Margin to 10. /// center.MarginBottom = 25; /// /// // Save the document. /// document.Save(); ///} /// /// public double MarginBottom { get { /* * Get the tcPr (table cell properties) element for this Cell, * null will be return if no such element exists. */ XElement tcPr = Xml.Element( XName.Get( "tcPr", DocX.w.NamespaceName ) ); // If tcPr is null, this cell contains no width information. if( tcPr == null ) return double.NaN; /* * Get the tcMar * */ XElement tcMar = tcPr.Element( XName.Get( "tcMar", DocX.w.NamespaceName ) ); // If tcMar is null, this cell contains no margin information. // Get the bottom (BottomMargin) element XElement tcMarBottom = tcMar?.Element( XName.Get( "bottom", DocX.w.NamespaceName ) ); // If tcMarBottom is null, this cell contains no bottom margin information. // Get the w attribute of the tcMarBottom element. XAttribute w = tcMarBottom?.Attribute( XName.Get( "w", DocX.w.NamespaceName ) ); // If w is null, this cell contains no width information. if( w == null ) return double.NaN; // If w is not a double, something is wrong with this attributes value, so remove it and return double.NaN; double bottomMarginInWordUnits; if( !double.TryParse( w.Value, out bottomMarginInWordUnits ) ) { w.Remove(); return double.NaN; } // Using 20 to match DocX._pageSizeMultiplier. return ( bottomMarginInWordUnits / 20 ); } set { /* * Get the tcPr (table cell properties) element for this Cell, * null will be return if no such element exists. */ XElement tcPr = Xml.Element( XName.Get( "tcPr", DocX.w.NamespaceName ) ); if( tcPr == null ) { Xml.SetElementValue( XName.Get( "tcPr", DocX.w.NamespaceName ), string.Empty ); tcPr = Xml.Element( XName.Get( "tcPr", DocX.w.NamespaceName ) ); } /* * Get the tcMar (table cell margin) element for this Cell, * null will be return if no such element exists. */ XElement tcMar = tcPr.Element( XName.Get( "tcMar", DocX.w.NamespaceName ) ); if( tcMar == null ) { tcPr.SetElementValue( XName.Get( "tcMar", DocX.w.NamespaceName ), string.Empty ); tcMar = tcPr.Element( XName.Get( "tcMar", DocX.w.NamespaceName ) ); } /* * Get the bottom (table cell bottom margin) element for this Cell, * null will be return if no such element exists. */ XElement tcMarBottom = tcMar.Element( XName.Get( "bottom", DocX.w.NamespaceName ) ); if( tcMarBottom == null ) { tcMar.SetElementValue( XName.Get( "bottom", DocX.w.NamespaceName ), string.Empty ); tcMarBottom = tcMar.Element( XName.Get( "bottom", DocX.w.NamespaceName ) ); } // The type attribute needs to be set to dxa which represents "twips" or twentieths of a point. In other words, 1/1440th of an inch. tcMarBottom.SetAttributeValue( XName.Get( "type", DocX.w.NamespaceName ), "dxa" ); // Using 20 to match DocX._pageSizeMultiplier. tcMarBottom.SetAttributeValue( XName.Get( "w", DocX.w.NamespaceName ), ( value * 20 ).ToString() ); } } public Color FillColor { get { /* * Get the tcPr (table cell properties) element for this Cell, * null will be return if no such element exists. */ XElement tcPr = Xml.Element( XName.Get( "tcPr", DocX.w.NamespaceName ) ); XElement shd = tcPr?.Element( XName.Get( "shd", DocX.w.NamespaceName ) ); XAttribute fill = shd?.Attribute( XName.Get( "fill", DocX.w.NamespaceName ) ); if( fill == null ) return Color.Empty; int argb = Int32.Parse( fill.Value.Replace( "#", "" ), NumberStyles.HexNumber ); return Color.FromArgb( argb ); } set { /* * Get the tcPr (table cell properties) element for this Cell, * null will be return if no such element exists. */ XElement tcPr = Xml.Element( XName.Get( "tcPr", DocX.w.NamespaceName ) ); if( tcPr == null ) { Xml.SetElementValue( XName.Get( "tcPr", DocX.w.NamespaceName ), string.Empty ); tcPr = Xml.Element( XName.Get( "tcPr", DocX.w.NamespaceName ) ); } /* * Get the tcW (table cell width) element for this Cell, * null will be return if no such element exists. */ XElement shd = tcPr.Element( XName.Get( "shd", DocX.w.NamespaceName ) ); if( shd == null ) { tcPr.SetElementValue( XName.Get( "shd", DocX.w.NamespaceName ), string.Empty ); shd = tcPr.Element( XName.Get( "shd", DocX.w.NamespaceName ) ); } shd.SetAttributeValue( XName.Get( "val", DocX.w.NamespaceName ), "clear" ); shd.SetAttributeValue( XName.Get( "color", DocX.w.NamespaceName ), "auto" ); shd.SetAttributeValue( XName.Get( "fill", DocX.w.NamespaceName ), value.ToHex() ); } } public TextDirection TextDirection { get { var tcPr = Xml.Element( XName.Get( "tcPr", DocX.w.NamespaceName ) ); var textDirection = tcPr?.Element( XName.Get( "textDirection", DocX.w.NamespaceName ) ); var val = textDirection?.Attribute( XName.Get( "val", DocX.w.NamespaceName ) ); if( val != null ) { TextDirection textDirectionValue; var success = Enum.TryParse( val.Value, out textDirectionValue ); if( success ) return textDirectionValue; else { val.Remove(); } } return TextDirection.right; } set { var tcPrXName = XName.Get( "tcPr", DocX.w.NamespaceName ); var textDirectionXName = XName.Get( "textDirection", DocX.w.NamespaceName ); var tcPr = Xml.Element( tcPrXName ); if( tcPr == null ) { Xml.SetElementValue( tcPrXName, string.Empty ); tcPr = Xml.Element( tcPrXName ); } var textDirection = tcPr.Element( textDirectionXName ); if( textDirection == null ) { tcPr.SetElementValue( textDirectionXName, string.Empty ); textDirection = tcPr.Element( textDirectionXName ); } textDirection.SetAttributeValue( XName.Get( "val", DocX.w.NamespaceName ), value.ToString() ); } } /// /// Returns the Cell.GridSpan => How many cells are merged. /// public int GridSpan { get { int gridSpanValue = 0; var tcPr = Xml.Element( XName.Get( "tcPr", DocX.w.NamespaceName ) ); var gridSpan = tcPr?.Element( XName.Get( "gridSpan", DocX.w.NamespaceName ) ); if( gridSpan != null ) { var gridSpanAttrValue = gridSpan.Attribute( XName.Get( "val", DocX.w.NamespaceName ) ); int value; if( gridSpanAttrValue != null && int.TryParse( gridSpanAttrValue.Value, out value ) ) gridSpanValue = value; } return gridSpanValue; } } #endregion #region Constructors internal Cell( Row row, DocX document, XElement xml ) : base( document, xml ) { _row = row; this.PackagePart = row.PackagePart; } #endregion #region Public Methods /// /// Set the table cell border /// /// /// ///// Create a new document. ///using (DocX document = DocX.Create("Test.docx")) ///{ /// // Insert a table into this document. /// Table t = document.InsertTable(3, 3); /// /// // Get the center cell. /// Cell center = t.Rows[1].Cells[1]; /// /// // Create a large blue border. /// Border b = new Border(BorderStyle.Tcbs_single, BorderSize.seven, 0, Color.Blue); /// /// // Set the center cells Top, Bottom, Left and Right Borders to b. /// center.SetBorder(TableCellBorderType.Top, b); /// center.SetBorder(TableCellBorderType.Bottom, b); /// center.SetBorder(TableCellBorderType.Left, b); /// center.SetBorder(TableCellBorderType.Right, b); /// /// // Save the document. /// document.Save(); ///} /// /// /// Table Cell border to set /// Border object to set the table cell border public void SetBorder( TableCellBorderType borderType, Border border ) { /* * Get the tcPr (table cell properties) element for this Cell, * null will be return if no such element exists. */ XElement tcPr = Xml.Element( XName.Get( "tcPr", DocX.w.NamespaceName ) ); if( tcPr == null ) { Xml.SetElementValue( XName.Get( "tcPr", DocX.w.NamespaceName ), string.Empty ); tcPr = Xml.Element( XName.Get( "tcPr", DocX.w.NamespaceName ) ); } /* * Get the tblBorders (table cell borders) element for this Cell, * null will be return if no such element exists. */ XElement tcBorders = tcPr.Element( XName.Get( "tcBorders", DocX.w.NamespaceName ) ); if( tcBorders == null ) { tcPr.SetElementValue( XName.Get( "tcBorders", DocX.w.NamespaceName ), string.Empty ); tcBorders = tcPr.Element( XName.Get( "tcBorders", DocX.w.NamespaceName ) ); } /* * Get the 'borderType' (table cell border) element for this Cell, * null will be return if no such element exists. */ var tcbordertype = borderType.ToString(); switch( borderType ) { case TableCellBorderType.TopLeftToBottomRight: tcbordertype = "tl2br"; break; case TableCellBorderType.TopRightToBottomLeft: tcbordertype = "tr2bl"; break; default: // only lower the first char of string (because of insideH and insideV) tcbordertype = tcbordertype.Substring( 0, 1 ).ToLower() + tcbordertype.Substring( 1 ); break; } XElement tcBorderType = tcBorders.Element( XName.Get( borderType.ToString(), DocX.w.NamespaceName ) ); if( tcBorderType == null ) { tcBorders.SetElementValue( XName.Get( tcbordertype, DocX.w.NamespaceName ), string.Empty ); tcBorderType = tcBorders.Element( XName.Get( tcbordertype, DocX.w.NamespaceName ) ); } // get string value of border style string borderstyle = border.Tcbs.ToString().Substring( 5 ); borderstyle = borderstyle.Substring( 0, 1 ).ToLower() + borderstyle.Substring( 1 ); // The val attribute is used for the border style tcBorderType.SetAttributeValue( XName.Get( "val", DocX.w.NamespaceName ), borderstyle ); int size; switch( border.Size ) { case BorderSize.one: size = 2; break; case BorderSize.two: size = 4; break; case BorderSize.three: size = 6; break; case BorderSize.four: size = 8; break; case BorderSize.five: size = 12; break; case BorderSize.six: size = 18; break; case BorderSize.seven: size = 24; break; case BorderSize.eight: size = 36; break; case BorderSize.nine: size = 48; break; default: size = 2; break; } // The sz attribute is used for the border size tcBorderType.SetAttributeValue( XName.Get( "sz", DocX.w.NamespaceName ), ( size ).ToString() ); // The space attribute is used for the cell spacing (probably '0') tcBorderType.SetAttributeValue( XName.Get( "space", DocX.w.NamespaceName ), ( border.Space ).ToString() ); // The color attribute is used for the border color tcBorderType.SetAttributeValue( XName.Get( "color", DocX.w.NamespaceName ), border.Color.ToHex() ); } /// /// Get a table cell border /// /// The table cell border to get public Border GetBorder( TableCellBorderType borderType ) { // instance with default border values var b = new Border(); /* * Get the tcPr (table cell properties) element for this Cell, * null will be return if no such element exists. */ XElement tcPr = Xml.Element( XName.Get( "tcPr", DocX.w.NamespaceName ) ); if( tcPr == null ) { // uses default border style } /* * Get the tcBorders (table cell borders) element for this Cell, * null will be return if no such element exists. */ XElement tcBorders = tcPr.Element( XName.Get( "tcBorders", DocX.w.NamespaceName ) ); if( tcBorders == null ) { // uses default border style } /* * Get the 'borderType' (cell border) element for this Cell, * null will be return if no such element exists. */ var tcbordertype = borderType.ToString(); switch( tcbordertype ) { case "TopLeftToBottomRight": tcbordertype = "tl2br"; break; case "TopRightToBottomLeft": tcbordertype = "tr2bl"; break; default: // only lower the first char of string (because of insideH and insideV) tcbordertype = tcbordertype.Substring( 0, 1 ).ToLower() + tcbordertype.Substring( 1 ); break; } XElement tcBorderType = tcBorders.Element( XName.Get( tcbordertype, DocX.w.NamespaceName ) ); if( tcBorderType == null ) { // uses default border style } // The val attribute is used for the border style XAttribute val = tcBorderType.Attribute( XName.Get( "val", DocX.w.NamespaceName ) ); // If val is null, this cell contains no border information. if( val == null ) { // uses default border style } else { try { string bordertype = "Tcbs_" + val.Value; b.Tcbs = ( BorderStyle )Enum.Parse( typeof( BorderStyle ), bordertype ); } catch { val.Remove(); // uses default border style } } // The sz attribute is used for the border size XAttribute sz = tcBorderType.Attribute( XName.Get( "sz", DocX.w.NamespaceName ) ); // If sz is null, this border contains no size information. if( sz == null ) { // uses default border style } else { // If sz is not an int, something is wrong with this attributes value, so remove it int numerical_size; if( !int.TryParse( sz.Value, out numerical_size ) ) sz.Remove(); else { switch( numerical_size ) { case 2: b.Size = BorderSize.one; break; case 4: b.Size = BorderSize.two; break; case 6: b.Size = BorderSize.three; break; case 8: b.Size = BorderSize.four; break; case 12: b.Size = BorderSize.five; break; case 18: b.Size = BorderSize.six; break; case 24: b.Size = BorderSize.seven; break; case 36: b.Size = BorderSize.eight; break; case 48: b.Size = BorderSize.nine; break; default: b.Size = BorderSize.one; break; } } } // The space attribute is used for the border spacing (probably '0') XAttribute space = tcBorderType.Attribute( XName.Get( "space", DocX.w.NamespaceName ) ); // If space is null, this border contains no space information. if( space == null ) { // uses default border style } else { // If space is not an int, something is wrong with this attributes value, so remove it int borderspace; if( !int.TryParse( space.Value, out borderspace ) ) { space.Remove(); // uses default border style } else { b.Space = borderspace; } } // The color attribute is used for the border color XAttribute color = tcBorderType.Attribute( XName.Get( "color", DocX.w.NamespaceName ) ); if( color == null ) { // uses default border style } else { // If color is not a Color, something is wrong with this attributes value, so remove it try { b.Color = ColorTranslator.FromHtml( string.Format( "#{0}", color.Value ) ); } catch { color.Remove(); // uses default border style } } return b; } public override Table InsertTable( int rowCount, int columnCount ) { var table = base.InsertTable( rowCount, columnCount ); table.PackagePart = this.PackagePart; this.InsertParagraph(); //It is necessary to put paragraph in the end of the cell, without it MS-Word will say that the document is corrupted //IMPORTANT: It will be better to check all methods that work with adding anything to cells return table; } #endregion /// /// Gets or Sets the fill color of this Cell. /// /// /// /// // Create a new document. /// using (DocX document = DocX.Create("Test.docx")) /// { /// // Insert a table into this document. /// Table t = document.InsertTable(3, 3); /// /// // Fill the first cell as Blue. /// t.Rows[0].Cells[0].FillColor = Color.Blue; /// // Fill the middle cell as Red. /// t.Rows[1].Cells[1].FillColor = Color.Red; /// // Fill the last cell as Green. /// t.Rows[2].Cells[2].FillColor = Color.Green; /// /// // Save the document. /// document.Save(); /// } /// /// } public class TableLook { #region Public Properties public bool FirstRow { get; set; } public bool LastRow { get; set; } public bool FirstColumn { get; set; } public bool LastColumn { get; set; } public bool NoHorizontalBanding { get; set; } public bool NoVerticalBanding { get; set; } #endregion #region Constructors public TableLook() { } public TableLook( bool firstRow, bool lastRow, bool firstColumn, bool lastColumn, bool noHorizontalBanding, bool noVerticalBanding ) { this.FirstRow = firstRow; this.LastRow = lastRow; this.FirstColumn = firstColumn; this.LastColumn = lastColumn; this.NoHorizontalBanding = noHorizontalBanding; this.NoVerticalBanding = noVerticalBanding; } #endregion } }