none
How to work with Table Styles??? RRS feed

  • Question

  • I'm new to OpenXML, please help me!

    Let's look at the following simple code:

    Table tbl = new Table();
    TableProperties tableProp = new TableProperties();
    
    TableStyle tableStyle = new TableStyle() { Val = "TableGrid" };
    tableProp.Append(tableStyle);
    
    tbl.AppendChild(tableProp);
    
    foreach (var row in extraData.Entities)
    {
        TableRow tr = new TableRow();
        Paragraph p = new Paragraph(new Run(new Text(row.entityName)));
        TableCell tc = new TableCell(p);
        tr.Append(tc);
        tbl.AppendChild(tr);
    }

    If I run this code, I get the table where the rows are spaced out normally, just like the lines of text in the same paragraph are spaced out by default. But the table has visible single grid lines.

    If I comment out these 2 lines:

    //TableStyle tableStyle = new TableStyle() { Val = "TableGrid" };
    //tableProp.Append(tableStyle);

    then I don't get visible grid lines (which is what I want), but the rows are spaced out more widely, looks more like paragraphs are spaced out by default.

    Here are my questions:

    1) Aside from "TableGrid", there must be other predefined styles, where do I find the full list of those?

    2) How do I make a table without grid lines, so that table rows have the same height as if "TableGrid" style were applied?

    Sunday, November 4, 2012 10:46 PM

Answers

  • Hi Datafeed

    Word has no way to uniquely identify a table. Traditionally (meaning programming using the Word APIs) we've used BOOKMARKs to "target" tables. The bookmark can contain the entire table, or simple be a "point" in a cell (usually the first).


    Cindy Meister, VSTO/Word MVP, my blog

    Friday, November 9, 2012 9:39 AM
    Moderator
  • Hi Datafeed,

    Sorry for late response. I have meet some trouble to create a table in a simplest document. Now I solved it.

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using DocumentFormat.OpenXml.Packaging;
    using DocumentFormat.OpenXml.Wordprocessing;
    using com.mksword.Net.OpenXmlTools;
    
    namespace ConsoleApplication14
    {
        class Class1 : WordprocessingDocumentUtil 
        {
            public void Action()
            {
                if (CreateW14Document(CreateTable))
                    SetLog("OK", OXULogType.INFO);
                else
                    SetLog("No", OXULogType.FATAL);
            }
    
            private bool CreateTable(WordprocessingDocument WPD)
            {
                bool result = false;
                Table tab = new Table();
                TableProperties tbps = new TableProperties();
                TableStyle tbstlye = new TableStyle() { Val = "TableGrid" };
                TableWidth tbwidth = new TableWidth()
                {
                    Width = "0",
                    Type = TableWidthUnitValues.Auto
                };
                TableBorders tbbs = new TableBorders();
                TopBorder tpb = new TopBorder()
                {
                    Val = BorderValues.Single
                };
                BottomBorder tbb = new BottomBorder()
                {
                    Val = BorderValues.Single
                };
                RightBorder trb = new RightBorder()
                {
                    Val = BorderValues.Single
                };
                LeftBorder tlb = new LeftBorder()
                {
                    Val = BorderValues.Single
                };
                InsideHorizontalBorder tihb = new InsideHorizontalBorder()
                {
                    Val = BorderValues.Single
                };
                InsideVerticalBorder tivb = new InsideVerticalBorder()
                {
                    Val = BorderValues.Single
                };
                tbbs.Append(tpb);
                tbbs.Append(tbb);
                tbbs.Append(trb);
                tbbs.Append(tlb);
                tbbs.Append(tihb);
                tbbs.Append(tivb);
                tbps.Append(tbbs);
                tbps.Append(tbstlye);
                tbps.Append(tbwidth);
                TableGrid TG = new TableGrid();
                GridColumn GC1 = new GridColumn() { Width = "3192" };
                GridColumn GC2 = new GridColumn() { Width = "3192" };
                GridColumn GC3 = new GridColumn() { Width = "3192" };
                TG.Append(GC1);
                TG.Append(GC2);
                TG.Append(GC3);
                TableRow TR1 = new TableRow();
                TableCell TC1 = new TableCell();
                AddTableCellProperty(TC1);
                Paragraph P1 = new Paragraph();
                TC1.Append(P1);
                TableCell TC2 = new TableCell();
                AddTableCellProperty(TC2);
                Paragraph P2 = new Paragraph();
                TC2.Append(P2);
                TableCell TC3 = new TableCell();
                AddTableCellProperty(TC3);
                Paragraph P3 = new Paragraph();
                TC3.Append(P3);
                TR1.Append(TC1);
                TR1.Append(TC2);
                TR1.Append(TC3);
                tab.Append(tbps);
                tab.Append(TG);
                tab.Append(TR1);
                WPD.MainDocumentPart.Document.Body.Append(tab);
                result = true;
                return result;
            }
    
            private void AddTableCellProperty(TableCell TC)
            {
                TableCellProperties TCP = new TableCellProperties();
                TableCellWidth TCW = new TableCellWidth()
                {
                    Width = "3192",
                    Type = TableWidthUnitValues.Dxa
                };
                TCP.Append(TCW);
                TC.Append(TCP);
            }
    
            
        }
    }

    This code will create a table with gridline( only one row, three column). If you comment the TableBorders and its children the gridline will invisible. And you can chage the type of BorderValues to change border's style to you want. This defintion might looks more different like the document which generate via Office Word. However it can work. I how it hit your goal.

    PS:

    I found the TableStyle isn't the necessary part in this program at the end. You can comment it and document will not affect by it at all.

    Have a good day,

    Tom


    Tom Xu [MSFT]
    MSDN Community Support | Feedback to us



    Thursday, November 8, 2012 9:06 AM
    Moderator

All replies

  • Hi Datafeed,

    Thanks for posting in the MSDN Forum.

    Would you please tell me where is the table? WordprocessingDocument, SpreadsheetDocument or PresentationDocument?

    Have a good day,

    Tom


    Tom Xu [MSFT]
    MSDN Community Support | Feedback to us

    Monday, November 5, 2012 4:35 AM
    Moderator
  • Hi Tom,

    Thank you very much for your response!

    My table is in WordprocessingDocument. Btw, I have just figured out the answers to my 2 previous questions, but I do have one more new question, which I would like to ask! I believe the new question belongs to this thread, because it's about Table Styles too.

    Here is the new one: I have one more table in that WordprocessingDocument, and it's a bit fancier table than the previous one: it has a few columns with headers, and headers are colored in customized colors. I don't want to recreate the header row programmatically, it seems like too much trouble for sure. I would like to have a header row in my template document, I would like to open that template, to add regular rows to that table and save the resulting document as a new file. What I can't figure out is this: how do I find that table in the document??? There seems to be no ID property, no Name property... So how do I create Table object in C# that references that particular table, so that I can work with it and add rows to it???

    P.S. For those who are wondering about the answers to my 2 previous questions:

    1) I opened up the styles.xml file, and found out, that there were two table styles defined in it: "TableGrid" and "TableNormal".

    2) I defined another style in that file that fits my requirements, and referenced it from my code.

     

    Monday, November 5, 2012 5:31 AM
  • For those who are wondering how I resolved the 3rd question:

    In a template, I inserted a dummy row with a fancy string, that can not be encountered in a document under normal circumstances. Then I cycle through the children of the body, looking for one whose inner xml contains aformentioned string. Thus I get a pointer to that table, remove a dummy row, and keep working with the table. But it all sounds like a hack, so if you know a proper cleaner way to do it, I will be happy to hear from you.

    Tuesday, November 6, 2012 12:00 AM
  • Hi Datafeed,

    I will create some sample code tonight, and tell you what I found tomorrow.

    Have a good day,

    Tom


    Tom Xu [MSFT]
    MSDN Community Support | Feedback to us

    Tuesday, November 6, 2012 7:30 AM
    Moderator
  • Tom,

    I'm looking forward to seeing your solution!

    Thank you very much!

    Wednesday, November 7, 2012 6:30 AM
  • Hi Datafeed,

    Sorry for late response. I have meet some trouble to create a table in a simplest document. Now I solved it.

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using DocumentFormat.OpenXml.Packaging;
    using DocumentFormat.OpenXml.Wordprocessing;
    using com.mksword.Net.OpenXmlTools;
    
    namespace ConsoleApplication14
    {
        class Class1 : WordprocessingDocumentUtil 
        {
            public void Action()
            {
                if (CreateW14Document(CreateTable))
                    SetLog("OK", OXULogType.INFO);
                else
                    SetLog("No", OXULogType.FATAL);
            }
    
            private bool CreateTable(WordprocessingDocument WPD)
            {
                bool result = false;
                Table tab = new Table();
                TableProperties tbps = new TableProperties();
                TableStyle tbstlye = new TableStyle() { Val = "TableGrid" };
                TableWidth tbwidth = new TableWidth()
                {
                    Width = "0",
                    Type = TableWidthUnitValues.Auto
                };
                TableBorders tbbs = new TableBorders();
                TopBorder tpb = new TopBorder()
                {
                    Val = BorderValues.Single
                };
                BottomBorder tbb = new BottomBorder()
                {
                    Val = BorderValues.Single
                };
                RightBorder trb = new RightBorder()
                {
                    Val = BorderValues.Single
                };
                LeftBorder tlb = new LeftBorder()
                {
                    Val = BorderValues.Single
                };
                InsideHorizontalBorder tihb = new InsideHorizontalBorder()
                {
                    Val = BorderValues.Single
                };
                InsideVerticalBorder tivb = new InsideVerticalBorder()
                {
                    Val = BorderValues.Single
                };
                tbbs.Append(tpb);
                tbbs.Append(tbb);
                tbbs.Append(trb);
                tbbs.Append(tlb);
                tbbs.Append(tihb);
                tbbs.Append(tivb);
                tbps.Append(tbbs);
                tbps.Append(tbstlye);
                tbps.Append(tbwidth);
                TableGrid TG = new TableGrid();
                GridColumn GC1 = new GridColumn() { Width = "3192" };
                GridColumn GC2 = new GridColumn() { Width = "3192" };
                GridColumn GC3 = new GridColumn() { Width = "3192" };
                TG.Append(GC1);
                TG.Append(GC2);
                TG.Append(GC3);
                TableRow TR1 = new TableRow();
                TableCell TC1 = new TableCell();
                AddTableCellProperty(TC1);
                Paragraph P1 = new Paragraph();
                TC1.Append(P1);
                TableCell TC2 = new TableCell();
                AddTableCellProperty(TC2);
                Paragraph P2 = new Paragraph();
                TC2.Append(P2);
                TableCell TC3 = new TableCell();
                AddTableCellProperty(TC3);
                Paragraph P3 = new Paragraph();
                TC3.Append(P3);
                TR1.Append(TC1);
                TR1.Append(TC2);
                TR1.Append(TC3);
                tab.Append(tbps);
                tab.Append(TG);
                tab.Append(TR1);
                WPD.MainDocumentPart.Document.Body.Append(tab);
                result = true;
                return result;
            }
    
            private void AddTableCellProperty(TableCell TC)
            {
                TableCellProperties TCP = new TableCellProperties();
                TableCellWidth TCW = new TableCellWidth()
                {
                    Width = "3192",
                    Type = TableWidthUnitValues.Dxa
                };
                TCP.Append(TCW);
                TC.Append(TCP);
            }
    
            
        }
    }

    This code will create a table with gridline( only one row, three column). If you comment the TableBorders and its children the gridline will invisible. And you can chage the type of BorderValues to change border's style to you want. This defintion might looks more different like the document which generate via Office Word. However it can work. I how it hit your goal.

    PS:

    I found the TableStyle isn't the necessary part in this program at the end. You can comment it and document will not affect by it at all.

    Have a good day,

    Tom


    Tom Xu [MSFT]
    MSDN Community Support | Feedback to us



    Thursday, November 8, 2012 9:06 AM
    Moderator
  • Tom,

    Thank you very much for your response!

    It's very helpful in a way... But it doesn't quite answer my last question: how do I find existing table in a WordProcessingDocument, so that I can modify that table? The table object doesn't seem to have "Name" or "ID" property, and "rsid" doesn't seem to be a unique identifier......

    Thursday, November 8, 2012 8:56 PM
  • Hi Datafeed

    Word has no way to uniquely identify a table. Traditionally (meaning programming using the Word APIs) we've used BOOKMARKs to "target" tables. The bookmark can contain the entire table, or simple be a "point" in a cell (usually the first).


    Cindy Meister, VSTO/Word MVP, my blog

    Friday, November 9, 2012 9:39 AM
    Moderator