Word table from xml

  • Remove From My Forums
  • Question

  • Hi there,

    I have a question: imagine that you have an xml file with collection of persons

    <people>
    
    
    
    <person>...
    
    
    
    </person>
    
    
    
    <person>...
    
    
    
    </person> etc. 
    
    
    
    </people>
    
    
    
    

    and the you have word document (.docx) with table where you want to put the data from xml. How can I do that? What I want to do is to generate dynamically tables from given xml and word document (template). Content control doesn’t work cos’ they are
    useful only for single elements not collections. Schema mapping works only (why??? ;( ) for exporting data from Word document not importing ;( I can’t see any solution, is there any simple way to do that? Excel has such feature (import/export
    xml)

    Thanks 

    • Moved by

      Monday, August 2, 2010 12:56 PM
      not VSTO-specific (From:Visual Studio Tools for Office)

    • Edited by
      Bartłomiej Czudek
      Monday, August 2, 2010 1:41 PM
      poor English ;)

Answers

  • Hi Bartlomiej

    In that case, the «best» approach (best = most efficient) would be to generate the report using Office OpenXML. This will allow you to generate the file (or alter a «template» file) without needing to work with the Word object model at all. You can do everything
    with standard .NET Framework XML and Packaging namespaces.

    You’ll find more information at OpenXMLDeveloper.org and the OpenXML SDK forum on this server.

    As far as standard Word automation («interop») goes, the best way is to concatenate the data in a standard delimited text format, assign the string to a Range object, then convert that Range to a Table object (Range.ConvertToTable method).


    Cindy Meister, VSTO/Word MVP

    • Marked as answer by
      Bessie Zhao
      Monday, August 9, 2010 8:52 AM

Here is the sample code to create simple word file with Table. It will give you a loop hint how to proceed with it.

class Program
{
    static void  Main(string[] args)

    {
        Document doc = new Document();
        Section s = doc.AddSection();
        Table table = s.AddTable(true);

        //Create Header and Data
        String[] header = { "Item", "Description", "Qty", "Unit Price", "Price" };
        String[][] data = {
                              new String[]{ "Spire.Doc for .NET",".NET Word Component","1","$799.00","$799.00"},
                              new String[]{"Spire.XLS for .NET",".NET Excel Component","2","$799.00","$1,598.00"},
                              new String[]{"Spire.Office for .NET",".NET Office Component","1","$1,899.00","$1,899.00"},
                              new String[]{"Spire.PDF for .NET",".NET PDFComponent","2","$599.00","$1,198.00"},
                          };
        //Add Cells
        table.ResetCells(data.Length + 1, header.Length);

        //Header Row
        TableRow fRow = table.Rows[0];
        fRow.IsHeader = true;
        //Row Height
        fRow.Height = 23;
        //Header Format
        fRow.RowFormat.BackColor = Color.AliceBlue;
        for (int i = 0; i < header.Length; i++)
        {
            //Cell Alignment
            Paragraph p = fRow.Cells[i].AddParagraph();
            fRow.Cells[i].CellFormat.VerticalAlignment = VerticalAlignment.Middle;
            p.Format.HorizontalAlignment = HorizontalAlignment.Center;
            //Data Format
            TextRange TR = p.AppendText(header[i]);
            TR.CharacterFormat.FontName = "Calibri";
            TR.CharacterFormat.FontSize = 14;
            TR.CharacterFormat.TextColor = Color.Teal;
            TR.CharacterFormat.Bold = true;
        }

        //Data Row
        for (int r = 0; r < data.Length; r++)
        {
            TableRow dataRow = table.Rows[r + 1];

            //Row Height
            dataRow.Height = 20;

            //C Represents Column.
            for (int c = 0; c < data[r].Length; c++)
            {
                //Cell Alignment
                dataRow.Cells[c].CellFormat.VerticalAlignment = VerticalAlignment.Middle;
                //Fill Data in Rows
                Paragraph p2 = dataRow.Cells[c].AddParagraph();
                TextRange TR2 = p2.AppendText(data[r][c]);
                //Format Cells
                p2.Format.HorizontalAlignment = HorizontalAlignment.Center;
                TR2.CharacterFormat.FontName = "Calibri";
                TR2.CharacterFormat.FontSize = 12;
                TR2.CharacterFormat.TextColor = Color.Brown;
            }
        }

        //Save and Launch
        doc.SaveToFile("WordTable.docx", FileFormat.Docx2013);
        System.Diagnostics.Process.Start("WordTable.docx");


        Console.ReadLine();

    }

  • Download OpenXML_Word_Exe.zip
  • Download source

Introduction

Welcome back again in OpenXML world, where you can create a word table with the help of C# and OpenXML.

Here the magic is,  No need to install word on your machine, no Interop object required. Lets see how to drive it

Background

I have given brief explanation about ‘What is Open XML‘ in my previous article, if you are new to OpenXML then check out this link

http://www.codeproject.com/Tips/994905/Edit-Word-Documents-using-OpenXML-and-Csharp-Witho

OpenXML table structure

According to people, OpenXML is legthy and complex but if you understand it’s structure then it is really a cup of tea. So lets start with table structure first.

Things we need before going to openXML

Image 1   Image 2

Getting started with OpenXML Table

A table consists of rows and cells and is structured much like an HTML table. It is defined with the <w:tbl> element. Basic table structure can be defined as

<w:tbl>
    <w:tblpr>.....</w:tblpr>
    <w:tblgrid>....</w:tblgrid>
    <w:tr>....</w:tr>
</w:tbl>

In above structure we can see, Table has three main tag.

1. w:tblpr : Specifies the table-wide properties for the table. These properties can be overridden by individual table level

2. w:tblgrid : Specifies the columns for the table

3. w:tr : Specifies a table row

Let see them one by one in detail

1. w:tblpr :

This Specifies the table-wide properties for the table, Each property is a child element of <tblPr> , and they affect all rows and cells in the table, but the style can be overridden by each individual row, column or cell.

The most commonly used properties are shown below

Property Name Description
w:jc Represent table alignment.
w:shd Represent table shading.
w:Borders Represent table borders.
w:Caption Represent table Caption.
w:CellMar Represent table cell margins.
w:tblCellSpacing Represent table spacing.
w:tblLayout Represent table layout.
w:tblLook Represent table conditional formatting.

see below tag snippet

<w:tblPr>
	<w:tblStyle w:val="TestTableStyle"/>
	<w:jc w:val="center"/>
</w:tblPr>

2. w:tblgrid

The columns of a table are defined by the <w:tblGrid> element it contains attribute as <w:gridCol> which is the size of each columns, if the table has 4 columns then w:tblgrid has 4 w:gridCol tags

see below tag snippet

<w:tblGrid>
	<w:gridCol w:w="2800"/>
	<w:gridCol w:w="2600"/>
	<w:gridCol w:w="2800"/>
<w:tblGrid>

3.w:tr

This is the row defination tag, this is the core element of table. it has following subset

Property Name Description
w:trPr Represent row level properties, but can be overridden by individual cell
w:tblPrEx Represent table properties for the row,  These properties are typically used for legacy documents, as well as in cases where two independent tables are merged
w:tc Represent individual table cell.

see below tag snippet

<w:tr>
    <w:trPr>.....</w:trPr>
    <w:tblPrEx>....</w:tblPrEx>
    <w:tc>....</w:tc>
</w:tr>

Now we will see w:tr properties in depth.

3.1 w:trPr

This element represent row level properties, Each property is a child element of <trPr> , and they affect all cells in the row. Mostly used properties are as below

Property Name Description
w:cantSplit it prevents the contents of the row from breaking across multiple pages by moving the start of the row to the start of a new page, it help the row to start on next page
w:hidden Help to hide the entire row
w:jc Specifies the alignment of the row
w:tblCellSpacing Specifies the cell spacing, it is same like HTML table attribute
w:tblHeader Specifies the current row should be repeated as header of each table on new page
w:trHeight Represent the height of the row, if optional then height will be adjusted automatically

3.2 w:trPrEx

As described exceptional properties of the table, with the help of this property we can show any row with specific exception. w:trPrEx has almost same properties like <w:trPr>, some new properties are as below

Property Name Description
w:shd Specifies the background color, it is optional property, it has different attribute like color, fill, val.
w:tblBorders Specifies row borders
w:tblCellMar Specifies the margin of the cell, this is basically cell properties of exceptional row (we will see this property thoroughly in cell section)
w:tblInd Before leading edge of the row it adds indentation to the row,
w:tblLayout Specifies the inbuilt table layout
w:tblLook Specifies the inbuilt table layout specified by word application 

see below tag snippet

<w:tr>
   <w:tblPrEx>
	<w:tblBorders>
		<w:top w:val="single" w:sz="12" w:space="0" w:color="FF0000" />
		<w:start w:val="single" w:sz="24" w:space="0" w:color="00FF00" />
		<w:bottom w:val="single" w:sz="12" w:space="0" w:color="0000FF" />
		<w:end w:val="single" w:sz="24" w:space="0" w:color="000000" />
		<w:insideH w:val="single" w:sz="24" w:space="0" w:color="FFFF00" />
		<w:insideV w:val="single" w:sz="24" w:space="0" w:color="FF00FF" />
	</w:tblBorders>
   </w:tblPrEx>
</w:tr>

3.3 w:tc

This tag specifies data for individual table cell, these tags are nested under table row tags. The core elements of w:tc are as follows

Property Name Description
w:p Specifies the paragraph of each cell
w:tbl Specifies table as content of the cell
w:tcPr Specifies the properties to be applied to the current cell.

see below snippet

<w:tc>
   <w:tcPr>
	<w:tcW w:w="2600" w:type="dxa"/>
   </w:tcPr>
   <w:p>
	<w:r>
      	    <w:t>cell content</w:t>
	</w:r>
   </w:p>
</w:tc>

above markup snippet contains table cell, in which paragraph (<w:p>), Run (<w:p>), Text (<w:r>) are the child element of the cell.

3.3.1 w:p

Paragraph is the main part of the cell, The paragraph can contain rich formatting properties for the paragraph, Paragraphs may also contain bookmarks, hyperlinks, fields, comments, etc. The core element of paragraph is properties (<w:pPr>) and run (<w:r>

Both paragraph properties and run has their own properties like paragraph frames, indentation, alignment, numbering, border, paragraph style, shading and tabs.

see below markup

<w:p>
   <w:pPr>
	<w:pStyle> w:val="TestWeb"/>
	<w:spacing w:before="20" w:after="20"/>
   </w:pPr>
   <w:r>
	<w:t>This is cell content</w:t>
   </w:r>
</w:p>

3.3.2 w:tcPr

tcPr represent cellwise properties, this properties are used to decorate cell. Row and column wise properties can be overridden in this section 

Property Name Description
w:gridSpan Specifies the spanning cell across rows
w:hideMark Specifies hide end of the table cell mark
w:noWrap Specifies the prevent text from wrapping, it is boolean property
w:tcBorders Specifies table cell border
w:tcFitText Specifies text within the cell can be extend to the width of the cell, this is the boolean property
w:tcMar Specifies table cell margins
w:tcW Specifies table cell width
w:vAlign Specifies table cell vertical alignments
w:vMerge This property indicates if the cell is part of merged group cell, it has two possible values continue and restart

3.3.1.1 w:r

Run defines a text properties. Most commonly run contains only text but it may have content as symbols, tabs, hyphens, carriage returns, drawings, breaks, and footnote references

see below properties of Run element

Property Name Description
w:br Specifies a break e.g. <w:br/>
w:cr Specifies a carriage return
w:drawing Specifies the layout of the DrawingML object within the document
w:noBreakHypen Specifies the non breaking hypen.
w:rPr Specifies the properties of the run like
w:softHypen Specifies the inbuilt table layout specified by word application 
w:sym Specifies a special character or symbol
w:t Spcifies the actual text which will display in cell, This is very important and core element of Table markup, this element hold actual text contents.
w:tab Specifies the TAB character

see below markup snippet

<w:r>
   <w:rPr>
	<w:b/>
	<w:i/>
    </w:rPr>
    <w:t>This is sample text</w:t>
</w:r>

3.3.1.1.1 w:rPr

 This element contains different properties of the Run, which is then applies to actual text exist in  <w:t> section

here are the most commonly used properties of the run

Property Name Description
w:b Display text in bold, exist in Text element e.g. <w:b />
w:i Display text in Italics, exist in Text element e.g. <w:i />  
w:caps Display text in small or upper caps depend upon ‘val’ attributes e.g. <w:caps w:val=»true» />
w:color Display text in specified color, it accept color code for color e.g. <w:color w:val=»FF1244″ />
w:dstrike Display text in Strike through format e.g. <w:dstrike w:val=»true»/>
w:emboss Display text in emboss style e.g. <w:emboss w:val=»true» />
w:imprint Display text in imprint style e.g. <w:imprint w:val=»true»/>
w:outline Display text in outline style e.g. <outline w:val=»true»/>
w:rStyle Display character style depend upon style ID (Here style is inbuilt)
w:shadow Display text has shadow for each character <w:shadow w:val=»true»/>
w:smallCaps Display text in small capital letter, The difference between caps and smallCaps is, caps make the text size larger and convert text to capital where as smallCaps convert text to capital but does not increase the font e.g. <w:smallCaps w:val=»true»/>  
w:sz Display the text in specified size, e.g. <w:sz w:val=»14″/> .
w:u Display the text in underline, e.g. <w:u w:val=»double»/>
w:vanish Text in this element will be hidden from display, e.g. <vanish/>
w:vertAlign Display text in Super or subscript e.g. <vertAlign w:val=»superscript | baseline | subscript  «/>

So here is the raw hierarchy structure of OpenXML table format

Image 3

Go with Markup and code

Now with the above all markup’s we can create a table in word (DOCX) file, here i have develope a small application that will put a nice table in word file

first create table properties, see below xml markup’s (We have apply inbuilt table style and look as Accept4)

<w:tblPr>
	<w:tblStyle w:val="LightGrid-Accent4" />
	<w:tblW w:w="0" w:type="auto" />
	<w:tblLook w:val="04A0" />
</w:tblPr>

then we will add columns in table, see below xml markup’s (We have take 3 columns)

<w:tblGrid> 
	<w:gridCol w:w="2394" />
	<w:gridCol w:w="2394" /> 
	<w:gridCol w:w="2394" /> 
</w:tblGrid> 

Now we will add rows in it with text to be display. (We have added 1 row with 3 cell here)

<w:tr w:rsidR="004D1DA5" w:rsidTr="004D1DA5"> 
	<w:trPr> 
		<w:cnfStyle w:val="100000000000" /> 
	</w:trPr> 
	<w:tc> 
		<w:tcPr> 
			<w:cnfStyle w:val="001000000000" /> 
			<w:tcW w:w="2394" w:type="dxa" /> 
			<w:hideMark /> 
		</w:tcPr> 
		<w:p w:rsidR="004D1DA5" w:rsidRDefault="004D1DA5"> 
			<w:pPr> 
				<w:jc w:val="center" /> 
			</w:pPr> 
			<w:r> 
				<w:t>No</w:t> 
			</w:r> 
		</w:p> 
	</w:tc> 
	<w:tc> 
		<w:tcPr> 
			<w:tcW w:w="2394" w:type="dxa" /> 
			<w:hideMark /> 
		</w:tcPr> 
		<w:p w:rsidR="004D1DA5" w:rsidRDefault="004D1DA5"> 
			<w:pPr> 
				<w:jc w:val="center" /> 
				<w:cnfStyle w:val="100000000000" /> 
			</w:pPr> 
			<w:r> 
				<w:t>Name</w:t> 
			</w:r> 
		</w:p> 
	</w:tc> 
	<w:tc> 
		<w:tcPr> 
			<w:tcW w:w="2394" w:type="dxa" /> 
			<w:hideMark /> 
		</w:tcPr> 
		<w:p w:rsidR="004D1DA5" w:rsidRDefault="004D1DA5"> 
			<w:pPr> 
				<w:jc w:val="center" /> 
				<w:cnfStyle w:val="100000000000" /> 
			</w:pPr> 
			<w:r> 
				<w:t>Sex</w:t> 
			</w:r> 
		</w:p> 
	</w:tc> 
</w:tr> 

Here is code to create Markup

# Create table object and add table properties

Table table1 = new Table();


TableProperties tableProperties1 = new TableProperties();
TableStyle tableStyle1 = new TableStyle() { Val = "LightGrid-Accent4" };
TableWidth tableWidth1 = new TableWidth() { Width = "0", Type = TableWidthUnitValues.Auto };
TableLook tableLook1 = new TableLook() { Val = "04A0" };


tableProperties1.Append(tableStyle1);
tableProperties1.Append(tableWidth1);
tableProperties1.Append(tableLook1);

# define table columns and add them in table

TableGrid tableGrid1 = new TableGrid();
GridColumn gridColumn1 = new GridColumn() { Width = "2394" };
GridColumn gridColumn2 = new GridColumn() { Width = "2394" };
GridColumn gridColumn3 = new GridColumn() { Width = "2394" };


tableGrid1.Append(gridColumn1);
tableGrid1.Append(gridColumn2);
tableGrid1.Append(gridColumn3);

# Define new cell object with its associated paragraph, Run, Text object and their properties respectively.

TableRow tableRow1 = new TableRow(){RsidTableRowAddition="004D1DA5",RsidTableRowProperties="004D1DA5"};


TableRowProperties tableRowProperties1 = new TableRowProperties();
ConditionalFormatStyle conditionalFormatStyle1 = new ConditionalFormatStyle(){Val="100000000000"};
tableRowProperties1.Append(conditionalFormatStyle1);


TableCell tableCell1 = new TableCell();
TableCellProperties tableCellProperties1 = new TableCellProperties();
ConditionalFormatStyle conditionalFormatStyle2 = new ConditionalFormatStyle(){Val="001000000000"};
TableCellWidth tableCellWidth1 = new TableCellWidth(){Width="2394",Type=TableWidthUnitValues.Dxa};
HideMark hideMark1 = new HideMark();
tableCellProperties1.Append(conditionalFormatStyle2);
tableCellProperties1.Append(tableCellWidth1);
tableCellProperties1.Append(hideMark1);


Paragraph paragraph1 = new Paragraph(){RsidParagraphAddition="004D1DA5",RsidRunAdditionDefault="004D1DA5"};
ParagraphProperties paragraphProperties1 = new ParagraphProperties();
Justification justification1 = new Justification() { Val = JustificationValues.Center };
paragraphProperties1.Append(justification1);


Run run1 = new Run();
Text text1 = new Text();


text1.Text = "No";


run1.Append(text1);


paragraph1.Append(paragraphProperties1);
paragraph1.Append(run1);


tableCell1.Append(tableCellProperties1);
tableCell1.Append(paragraph1);

Yes, we are done with our code now try to test it.

Summing Up

OpenXML is  is an open, international, ECMA-376, Second Edition and ISO/IEC 29500 standard, They are based on technologies like XML and ZIP. You can improve your application performance with the help of OpenXML, Developer can interact with DOCX file without opening it. With the help of openXML you can perform complex operations with just a few lines of code.

In this article we have seen how to draw a word table using OpenXML and C#

Till more to happen and learn, we will see more good samples in coming versions of this article.

Suggestions and Queries are always welcome.

Thanks

koolprasad2003

Office Open XML

Office Open XML is introduced by Microsoft to work with documents. For e.g.: — read/write MS word documents.

Prerequisites

  • Visual Studio
  • MS Word Document
  • Open XML SDK

Execute below command to Install DocumentFormat.OpenXml SDK in your project

  1. Install-Package DocumentFormat.OpenXml Install-Package DocumentFormat.OpenXml  
Note

In this example, I am using a windows form application to interact with word document and display the result on the screen.

How to find first table from word document?

  1. Table table =  doc.MainDocumentPart.Document.Body.Elements<Table>().First();  

Here .First() is extension method to find first table from word document.

The WordprocessingDocument Methods

EXTENSION METHOD

DESCRIPTION

.Elements<Table>().First()

To get the first table from the word document

.Elements<Table>().Last()

To get the last table from the word document

.Elements<Table>().FisrtOrDefault()

To get the first table from the word document or return the default value if the document does not contain table.

.Elements<Table>().LastOrDefault()

To get the Last table from word document or return the default value if the document does not contain table.

.Elements<Table>().ElementAt(Index)

To get the exact table from the word document by index number. Default index number is 0.

Table.Elements<TableRow>().ElementAt(index)

To get the exact table row from selected table by index number. Default index number is 0.

Row.Elements<TableCell>().ElementAt(Index)

To get the exact row cell from selected row by index number. Default index number is 0.

 

Execute the following code to read the first table from the word document,

  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Data;  
  4. using System.Linq;  
  5. using System.Windows.Forms;  
  6. using DocumentFormat.OpenXml.Packaging;  
  7. using DocumentFormat.OpenXml.Wordprocessing;  
  8.   
  9. namespace ReadTable  
  10. {  
  11.     public partial class Form1 : Form  
  12.     {  
  13.         public Form1()  
  14.         {  
  15.             InitializeComponent();  
  16.         }  
  17.   
  18.           
  19.         private void btnBrowse_Click(object sender, EventArgs e)  
  20.         {  
  21.             DialogResult result = this.openDB.ShowDialog();  
  22.             if (result == DialogResult.OK)  
  23.             {  
  24.                 txtBrowse.Text = openDB.FileName;  
  25.             }  
  26.         }  
  27.   
  28.         private void btnReadTable_Click(object sender, EventArgs e)  
  29.         {  
  30.               
  31.             using (var doc = WordprocessingDocument.Open(txtBrowse.Text.Trim(), false))  
  32.             {  
  33.                   
  34.                 DataTable dt = new DataTable();  
  35.                 int rowCount = 0;  
  36.   
  37.                   
  38.                 Table table = doc.MainDocumentPart.Document.Body.Elements<Table>().First();  
  39.   
  40.                   
  41.                 IEnumerable<TableRow> rows = table.Elements<TableRow>();  
  42.   
  43.                   
  44.                 foreach (TableRow row in rows)  
  45.                 {  
  46.                     if (rowCount == 0)  
  47.                     {  
  48.                         foreach (TableCell cell in row.Descendants<TableCell>())  
  49.                         {  
  50.                             dt.Columns.Add(cell.InnerText);  
  51.                         }  
  52.                         rowCount += 1;  
  53.                     }  
  54.                     else  
  55.                     {  
  56.                         dt.Rows.Add();  
  57.                         int i = 0;  
  58.                         foreach (TableCell cell in row.Descendants<TableCell>())  
  59.                         {  
  60.                             dt.Rows[dt.Rows.Count — 1][i] = cell.InnerText;  
  61.                             i++;  
  62.                         }  
  63.                     }  
  64.                 }  
  65.   
  66.                   
  67.                   
  68.                 dgvTable.DataSource = dt;  
  69.             }  
  70.         }  
  71.     }  
  72. }  

Output

In the above example, I have used .First() extension method to get the first table from word document. You can use other extension methods to find exact table or you can use for/foreach loop to find the exact table from the word document.

Summary

In this session, I discussed how to read the table from the word document using c#. I hope the above session will help you to read the table from the word document using C#.

INTELLIGENT WORK FORUMS
FOR COMPUTER PROFESSIONALS

Contact US

Thanks. We have received your request and will respond promptly.

Log In

Come Join Us!

Are you a
Computer / IT professional?
Join Tek-Tips Forums!

  • Talk With Other Members
  • Be Notified Of Responses
    To Your Posts
  • Keyword Search
  • One-Click Access To Your
    Favorite Forums
  • Automated Signatures
    On Your Posts
  • Best Of All, It’s Free!

*Tek-Tips’s functionality depends on members receiving e-mail. By joining you are opting in to receive e-mail.

Posting Guidelines

Promoting, selling, recruiting, coursework and thesis posting is forbidden.

Students Click Here

read from xml file into a word document table

read from xml file into a word document table

(OP)

7 Feb 08 15:46

I have an xml file ( C:Emp.Xml) with employee information in it
It has data with empoyee_id , employee_name, location and salary information
These are the columns and the data is in xml format
Emp_id, Emp_name, Loc, Sal

The number of records in the xml file is varying

I would like to read the xml file and populate the value into a table in a word document
The table row size is dynamically changing based on the number of records in the XML file
Could some one please suggest a VBA macro as to how I can populate XML data into a Word document table

Red Flag Submitted

Thank you for helping keep Tek-Tips Forums free from inappropriate posts.
The Tek-Tips staff will check this out and take appropriate action.

Join Tek-Tips® Today!

Join your peers on the Internet’s largest technical computer professional community.
It’s easy to join and it’s free.

Here’s Why Members Love Tek-Tips Forums:

  • Tek-Tips ForumsTalk To Other Members
  • Notification Of Responses To Questions
  • Favorite Forums One Click Access
  • Keyword Search Of All Posts, And More…

Register now while it’s still free!

Already a member? Close this window and log in.

Join Us             Close

Понравилась статья? Поделить с друзьями:
  • Word surf 348 уровень ответы
  • Word surf 284 уровень ответы
  • Word surf 267 уровень ответы
  • Word surf 197 уровень ответы на игру
  • Word surf 165 уровень ответы