Code Monkey home page Code Monkey logo

templateengine.docx's Introduction

TemplateEngine.Docx

Template engine for generating Word docx documents on the server-side with a human-created Word templates, based on content controls Word feature.

Based on Eric White code sample.

Installation

You can get it with NuGet package.

nuget install command

Example of usage

Here is source code of sample usage.

How to create template

  • Create Word document with prototype of content:
    document example

  • Switch to developer ribbon tab. If you can't see it, go to settings of ribbon menu and enable developer tab:
    developer mode

  • All data binds on content control tag value:
    create content control

Filling fields

docx template

using System;
using System.IO;

namespace TemplateEngine.Docx.Example
{
    class Program
    {
        static void Main(string[] args)
        {				
            File.Delete("OutputDocument.docx");
            File.Copy("InputTemplate.docx", "OutputDocument.docx");
		
	        var valuesToFill = new Content(
		        new FieldContent("Report date", DateTime.Now.ToString()));

		    using(var outputDocument = new TemplateProcessor("OutputDocument.docx")
				.SetRemoveContentControls(true))
            {
                outputDocument.FillContent(valuesToFill);
                outputDocument.SaveChanges();
            } 
		}
	}
}			

Filling tables

filling table

using System;
using System.IO;

namespace TemplateEngine.Docx.Example
{
    class Program
    {
        static void Main(string[] args)
        {				
            File.Delete("OutputDocument.docx");
            File.Copy("InputTemplate.docx", "OutputDocument.docx");
		
			var valuesToFill = new Content(
		        new TableContent("Team Members Table")
			        .AddRow(
				        new FieldContent("Name", "Eric"),
				        new FieldContent("Role", "Program Manager"))
			        .AddRow(
				        new FieldContent("Name", "Bob"),
				        new FieldContent("Role", "Developer")),

		        new FieldContent("Count", "2"));
		
		    using(var outputDocument = new TemplateProcessor("OutputDocument.docx")
				.SetRemoveContentControls(true))
            {
                outputDocument.FillContent(valuesToFill);
                outputDocument.SaveChanges();
            } 
		}
	}
}			

Filling lists

filling list

using System;
using System.IO;

namespace TemplateEngine.Docx.Example
{
    class Program
    {
        static void Main(string[] args)
        {				
            File.Delete("OutputDocument.docx");
            File.Copy("InputTemplate.docx", "OutputDocument.docx");
		
			var valuesToFill = new Content(
		        new ListContent("Team Members List")
					.AddItem(
						new FieldContent("Name", "Eric"), 
						new FieldContent("Role", "Program Manager"))
					.AddItem(
						new FieldContent("Name", "Bob"),
						new FieldContent("Role", "Developer")));

		    using(var outputDocument = new TemplateProcessor("OutputDocument.docx")
				.SetRemoveContentControls(true))
            {
                outputDocument.FillContent(valuesToFill);
                outputDocument.SaveChanges();
            } 
		}
	}
}			

Filling nested lists

filling nested list

using System;
using System.IO;

namespace TemplateEngine.Docx.Example
{
    class Program
    {
        static void Main(string[] args)
        {				
            File.Delete("OutputDocument.docx");
            File.Copy("InputTemplate.docx", "OutputDocument.docx");
		
			var valuesToFill = new Content(
		       	new ListContent("Team Members Nested List")
					.AddItem(new ListItemContent("Role", "Program Manager")
						.AddNestedItem(new FieldContent("Name", "Eric"))
						.AddNestedItem(new FieldContent("Name", "Ann")))
					.AddItem(new ListItemContent("Role", "Developer")
						.AddNestedItem(new FieldContent("Name", "Bob"))
						.AddNestedItem(new FieldContent("Name", "Richard"))));


		    using(var outputDocument = new TemplateProcessor("OutputDocument.docx")
				.SetRemoveContentControls(true))
            {
                outputDocument.FillContent(valuesToFill);
                outputDocument.SaveChanges();
            } 
		}
	}
}			

Filling list inside table

filling list inside table

using System;
using System.IO;

namespace TemplateEngine.Docx.Example
{
    class Program
    {
        static void Main(string[] args)
        {				
            File.Delete("OutputDocument.docx");
            File.Copy("InputTemplate.docx", "OutputDocument.docx");
		
			var valuesToFill = new Content(
		       new TableContent("Projects Table")
					.AddRow(
						new FieldContent("Name", "Eric"), 
						new FieldContent("Role", "Program Manager"), 
						new ListContent("Projects")
							.AddItem(new FieldContent("Project", "Project one"))
							.AddItem(new FieldContent("Project", "Project two")))
					.AddRow(
						new FieldContent("Name", "Bob"),
						new FieldContent("Role", "Developer"),
						new ListContent("Projects")
							.AddItem(new FieldContent("Project", "Project one"))
							.AddItem(new FieldContent("Project", "Project three"))));


		    using(var outputDocument = new TemplateProcessor("OutputDocument.docx")
				.SetRemoveContentControls(true))
            {
                outputDocument.FillContent(valuesToFill);
                outputDocument.SaveChanges();
            } 
		}
	}
}			

Filling table inside list

filling table inside list

using System;
using System.IO;

namespace TemplateEngine.Docx.Example
{
    class Program
    {
        static void Main(string[] args)
        {				
            File.Delete("OutputDocument.docx");
            File.Copy("InputTemplate.docx", "OutputDocument.docx");
		
			var valuesToFill = new Content(
		      new ListContent("Projects List")
					.AddItem(new ListItemContent("Project", "Project one")
						.AddTable(TableContent.Create("Team members")
							.AddRow(
								new FieldContent("Name", "Eric"), 
								new FieldContent("Role", "Program Manager"))
							.AddRow(
								new FieldContent("Name", "Bob"), 
								new FieldContent("Role", "Developer"))))
					.AddItem(new ListItemContent("Project", "Project two")
						.AddTable(TableContent.Create("Team members")
							.AddRow(
								new FieldContent("Name", "Eric"),
								new FieldContent("Role", "Program Manager"))))
					.AddItem(new ListItemContent("Project", "Project three")
						.AddTable(TableContent.Create("Team members")
							.AddRow(
								new FieldContent("Name", "Bob"),
								new FieldContent("Role", "Developer")))));


		    using(var outputDocument = new TemplateProcessor("OutputDocument.docx")
				.SetRemoveContentControls(true))
            {
                outputDocument.FillContent(valuesToFill);
                outputDocument.SaveChanges();
            } 
		}
	}
}			

Filling table with several blocks

filling table with several blocks

using System;
using System.IO;

namespace TemplateEngine.Docx.Example
{
    class Program
    {
        static void Main(string[] args)
        {				
            File.Delete("OutputDocument.docx");
            File.Copy("InputTemplate.docx", "OutputDocument.docx");
		
			var valuesToFill = new Content(
				new TableContent("Team Members Statistics")
					.AddRow(
						new FieldContent("Name", "Eric"),
						new FieldContent("Role", "Program Manager"))
					.AddRow(
					    new FieldContent("Name", "Richard"),
						new FieldContent("Role", "Program Manager"))
					.AddRow(
						new FieldContent("Name", "Bob"),
						new FieldContent("Role", "Developer")),

				new TableContent("Team Members Statistics")
					.AddRow(
						new FieldContent("Statistics Role", "Program Manager"),
						new FieldContent("Statistics Role Count", "2"))						
					.AddRow(
						new FieldContent("Statistics Role", "Developer"),
						new FieldContent("Statistics Role Count", "1")));


		    using(var outputDocument = new TemplateProcessor("OutputDocument.docx")
				.SetRemoveContentControls(true))
            {
                outputDocument.FillContent(valuesToFill);
                outputDocument.SaveChanges();
            } 
		}
	}
}			

Filling table with merged rows

filling table with merged rows

using System;
using System.IO;

namespace TemplateEngine.Docx.Example
{
    class Program
    {
        static void Main(string[] args)
        {				
            File.Delete("OutputDocument.docx");
            File.Copy("InputTemplate.docx", "OutputDocument.docx");
		
			var valuesToFill = new Content(
				new TableContent("Team members info")
					.AddRow(
						new FieldContent("Name", "Eric"),
						new FieldContent("Role", "Program Manager"),
						new FieldContent("Age", "37"),
						new FieldContent("Gender", "Male"))
					.AddRow(
						new FieldContent("Name", "Bob"),
						new FieldContent("Role", "Developer"),
						new FieldContent("Age", "33"),
						new FieldContent("Gender", "Male"))
					.AddRow(
						new FieldContent("Name", "Ann"),
						new FieldContent("Role", "Developer"),
						new FieldContent("Age", "34"),
						new FieldContent("Gender", "Female")));


		    using(var outputDocument = new TemplateProcessor("OutputDocument.docx")
				.SetRemoveContentControls(true))
            {
                outputDocument.FillContent(valuesToFill);
                outputDocument.SaveChanges();
            } 
		}
	}
}			

Filling table with merged columns

table with merged columns

using System;
using System.IO;

namespace TemplateEngine.Docx.Example
{
    class Program
    {
        static void Main(string[] args)
        {				
            File.Delete("OutputDocument.docx");
            File.Copy("InputTemplate.docx", "OutputDocument.docx");
		
			var valuesToFill = new Content(
				new TableContent("Team members projects")
					.AddRow(
						new FieldContent("Name", "Eric"),
						new FieldContent("Role", "Program Manager"),
						new FieldContent("Age", "37"),
						new FieldContent("Projects", "Project one, Project two"))
					.AddRow(
						new FieldContent("Name", "Bob"),
						new FieldContent("Role", "Developer"),
						new FieldContent("Age", "33"),
						new FieldContent("Projects", "Project one"))
					.AddRow(
						new FieldContent("Name", "Ann"),
						new FieldContent("Role", "Developer"),
						new FieldContent("Age", "34"),
						new FieldContent("Projects", "Project two")));


		    using(var outputDocument = new TemplateProcessor("OutputDocument.docx")
				.SetRemoveContentControls(true))
            {
                outputDocument.FillContent(valuesToFill);
                outputDocument.SaveChanges();
            } 
		}
	}
}			

Filling images

filling images

using System;
using System.IO;

namespace TemplateEngine.Docx.Example
{
    class Program
    {
        static void Main(string[] args)
        {				
            File.Delete("OutputDocument.docx");
            File.Copy("InputTemplate.docx", "OutputDocument.docx");
		
			var valuesToFill = new Content(
		       new ImageContent("photo", File.ReadAllBytes("Tesla.jpg"))
			);

		    using(var outputDocument = new TemplateProcessor("OutputDocument.docx")
				.SetRemoveContentControls(true))
            {
                outputDocument.FillContent(valuesToFill);
                outputDocument.SaveChanges();
            } 
		}
	}
}		

Filling images inside a table

filling images inside a table

using System;
using System.IO;

namespace TemplateEngine.Docx.Example
{
    class Program
    {
        static void Main(string[] args)
        {				
            File.Delete("OutputDocument.docx");
            File.Copy("InputTemplate.docx", "OutputDocument.docx");
		
			var valuesToFill = new Content(
		       new TableContent("Scientists Table")
					.AddRow(new FieldContent("Name", "Nicola Tesla"),
						new FieldContent("Born", new DateTime(1856, 7, 10).ToShortDateString()),
						new ImageContent("Photo", File.ReadAllBytes("Tesla.jpg")),
						new FieldContent("Info",
							"Serbian American inventor, electrical engineer, mechanical engineer, physicist, and futurist best known for his contributions to the design of the modern alternating current (AC) electricity supply system"))
					.AddRow(new FieldContent("Name", "Thomas Edison"),
						new FieldContent("Born", new DateTime(1847, 2, 11).ToShortDateString()),
						new ImageContent("Photo", File.ReadAllBytes("Edison.jpg")),
						new FieldContent("Info",
							"American inventor and businessman. He developed many devices that greatly influenced life around the world, including the phonograph, the motion picture camera, and the long-lasting, practical electric light bulb."))
					.AddRow(new FieldContent("Name", "Albert Einstein"),
						new FieldContent("Born", new DateTime(1879, 3, 14).ToShortDateString()),
						new ImageContent("Photo", File.ReadAllBytes("Einstein.jpg")),
						new FieldContent("Info",
							"German-born theoretical physicist. He developed the general theory of relativity, one of the two pillars of modern physics (alongside quantum mechanics). Einstein's work is also known for its influence on the philosophy of science. Einstein is best known in popular culture for his mass–energy equivalence formula E = mc2 (which has been dubbed 'the world's most famous equation')."))
			);

		    using(var outputDocument = new TemplateProcessor("OutputDocument.docx")
				.SetRemoveContentControls(true))
            {
                outputDocument.FillContent(valuesToFill);
                outputDocument.SaveChanges();
            } 
		}
	}
}			

Filling images inside a list

filling images inside a list

using System;
using System.IO;

namespace TemplateEngine.Docx.Example
{
    class Program
    {
        static void Main(string[] args)
        {				
            File.Delete("OutputDocument.docx");
            File.Copy("InputTemplate.docx", "OutputDocument.docx");
		
			var valuesToFill = new Content(
		     new ListContent("Scientists List")
				  .AddItem(new FieldContent("Name", "Nicola Tesla"),
					  new ImageContent("Photo", File.ReadAllBytes("Tesla.jpg")),
					  new FieldContent("Dates of life", string.Format("{0}-{1}",
						  1856, 1943)),
					  new FieldContent("Info",
						  "Serbian American inventor, electrical engineer, mechanical engineer, physicist, and futurist best known for his contributions to the design of the modern alternating current (AC) electricity supply system"))
				  .AddItem(new FieldContent("Name", "Thomas Edison"),
					  new ImageContent("Photo", File.ReadAllBytes("Edison.jpg")),
					  new FieldContent("Dates of life", string.Format("{0}-{1}",
						  1847, 1931)),
					  new FieldContent("Info",
						  "American inventor and businessman. He developed many devices that greatly influenced life around the world, including the phonograph, the motion picture camera, and the long-lasting, practical electric light bulb."))
				  .AddItem(new FieldContent("Name", "Albert Einstein"),
					  new ImageContent("Photo", File.ReadAllBytes("Einstein.jpg")),
					  new FieldContent("Dates of life", string.Format("{0}-{1}",
						  1879, 1955)),
					  new FieldContent("Info",
						  "German-born theoretical physicist. He developed the general theory of relativity, one of the two pillars of modern physics (alongside quantum mechanics). Einstein's work is also known for its influence on the philosophy of science. Einstein is best known in popular culture for his mass–energy equivalence formula E = mc2 (which has been dubbed 'the world's most famous equation')."))
			);

		    using(var outputDocument = new TemplateProcessor("OutputDocument.docx")
				.SetRemoveContentControls(true))
            {
                outputDocument.FillContent(valuesToFill);
                outputDocument.SaveChanges();
            } 
		}
	}
}			

Content structure

content structure

Have fun!

yandex counter

templateengine.docx's People

Contributors

abatar1 avatar aivolkov avatar ilya-mim avatar jakubpetr avatar kmamkin avatar kozzykoder avatar lancheg avatar nickab avatar robertmuehsig avatar zioseri avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

templateengine.docx's Issues

Prototype for list item not found

Prototype for list item 'Department, From, To, Count' not found
I can't create list in document MS Word. Please, help me. How create list in MS Word?
ListContent departments = new ListContent("Departments"); foreach (Department item in Conclusion.Departments) { departments.AddItem( new FieldContent("Department", item.Name), new FieldContent("From", item.From.ToShortDateString()), new FieldContent("To", item.To.ToShortDateString()), new FieldContent("Count", item.CountDays.ToString()) ); }
In MS Word - http://www.imageup.ru/img88/2701576/image1.png.html

Issue when table is added on existing document with other table.

Hello,

I have a word document that contains multiple tables generated by the engine. When i insert a new table between 2 existing table ( more precisely, i add a new paragraph, in this new paragraph i add a new table generated by the engine) when i generate the new word document, all tables the first row. I add a simple example to reproduce the issue. The sample define 2 templates : Test1 contains only 2 table. Test2 contains a third table between the two table. You'll notice that the generated word based on Test2 template contains duplicate rows.
TemplateDocx.zip

Duplicates of tests found by PVS-Studio

V3013 It is odd that the body of ‘RepeatContentConstructorWithNameAndEnumerableFieldContent_FillsNameAndItems’ function is fully equivalent to the body of ‘RepeatContentConstructorWithNameAndEnumerableListItemContent_FillsNameAndItems’ function. RepeatContentTests.cs

V3013 It is odd that the body of ‘ListContentConstructorWithNameAndEnumerableFieldContent_FillsNameAndItems’ function is fully equivalent to the body of ‘ListContentConstructorWithNameAndEnumerableListItemContent_FillsNameAndItems’ function. ListContentTests.cs

Hidden RepeatContent inside TableContent generates malformed document

Word error message when opening (in russian):
worderror

Template: HiddenRepeatReproTemplate.docx

Repro:

using System;
using System.IO;
using TemplateEngine.Docx;

namespace HiddenRepeatRepro
{
	static class Program
	{
		static void Main(string[] args)
		{
			string templateFile = "HiddenRepeatReproTemplate.docx";
			string outputFile = "HiddenRepeatRepro.docx";

			File.Delete(outputFile);
			File.Copy(templateFile, outputFile);

			var repeat = new RepeatContent("repeat1")
				.AddItem(new FieldContent("val", "123"))
				.AddItem(new FieldContent("val", "456"));

			repeat.Hide(); // breaks document

			var table = new TableContent("table1")
				.AddRow(repeat);

			var content = new Content(table);

			using (var template = new TemplateProcessor(outputFile).SetRemoveContentControls(true))
			{
				template.FillContent(content);
				template.SaveChanges();
			}
		}
	}
}

Filling a table total row do not work

I was following your first example of filling in a table with few rows and one total row at the end. I wasn't able to make the total row show any data - it was black after processing. Then I decided to check your own example code. Here is extract of the code I am following as example and which I tested:

...
// Add table.
new TableContent("Team Members Table")
.AddRow(
new FieldContent("Name", "Eric"),
new FieldContent("Role", "Program Manager"))
.AddRow(
new FieldContent("Name", "Bob"),
new FieldContent("Role", "Developer")),
// Add field inside table that not to propagate.
new FieldContent("Count", "2"),
...

The example above was failing too - to fill in the total row.
Here what the final table looks like (note I can paste here the table content only):

Name Role
Eric Program Manager
Bob Developer
Total members

As you can see the Total row looks like:

Total members

but should look like:

Total 2 members

So I believe that I am following the example correctly and there is a bug when filling in the content.

Question: How to make table control?

Hi, I looked at the example in the repository, and certainly don't understand how to create wrapper around table. I know about the Content Controls and Design Mode. But I can't figure out which kind of control is used for table. Probably that's why data can't be render in the word document. Below is the picture about which control I am asking for.
control
Sorry for annoying question.

Заполнение шаблона из базы данных.

Скажите пожалуйста, как можно реализовать заполнение таблицы значениями из базы данных? В таблицу записывается только одно значение из базы, а не все.
Пробую сделать так -

var appVal= from value in db.ApplicantValues where value.ApplicantId == 21 select value.Value;
foreach (var v in appVal.ToList())
                {
                    var valuesToFill = new Content(
                    
                    new TableContent("table")
                    .AddRow(
                        new FieldContent("value", v)
                        )

                    );

                   
                        using (var outputDocument = new TemplateProcessor(Server.MapPath("Test.docx"))
                                    .SetRemoveContentControls(false))
                        {
                            outputDocument.FillContent(valuesToFill);
                            outputDocument.SaveChanges();
                        }
                    

                }

RepeatContent appears not to work

Either RepeatContent doesn't work, or I have the wrong idea about how to use it. I have created a very simple docx (in Word 2013) containing a single repeating section with Title and Tag both set to "TestRepeater." The content of the repeating section is a single text field named/tagged "TestField" followed by a carriage return. When I try to fill it with two lines of content using code like below, I end up with a "Field content for field '' not found" error message in the output, and the repeating section remains unfilled and is not removed, but is duplicated.

var valuesToFill = new Content(
    new RepeatContent("TestRepeater")
        .AddItem(new FieldContent("TestField", "value 1"))
        .AddItem(new FieldContent("Testfield", "value 2")));

using (var outputDocument = new TemplateProcessor(@"f:\RepeatContentTest.docx")
    .SetRemoveContentControls(true))
{
    outputDocument
        .FillContent(valuesToFill)
        .SaveChanges();
}

What I really want is a repeating section with a header field and a table inside, so that I can generate a series of (an unknown number of) tables with each table bearing a title. But until I have a repeating section working, I don't see how to proceed.

RepeatingSectionTest.docx

Remove holder if content empty

i'm create word document by template
template contains table and list (and some other text data). the table contains several repeated rows.
table:

Header1 | value1
Header2 | value2
Header3 | value3

list:
1. value

which must translate into:
table:

Header1| row1-value1
Header2| row1-value2
Header3| row1-value3
------------------------
Header1| row2-value1
Header2| row2-value2
Header3| row2-value3
------------------------
...

(yes, in table header places in first column, but not row)

list:

1.value 1
2.value 2
3.value 3
...

all work fine, except one small things - if table or list does not contains any row in result document i see template data...
how i can remove this data from result document if repeated data are empty?

Error while hiding nested RepeatContent.

Exception locate is file RepeatProcessor.cs, line 105 (code: contentControl.DescendantsAndSelf(W.sdt).Remove();)

Error message: The parent is missing

Input file: InputTemplate.docx

Programm code:

using System.IO;
using TemplateEngine.Docx;

namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            File.Delete("OutputDocument.docx");
            File.Copy("InputTemplate.docx", "OutputDocument.docx");

            var valuesToFill = new Content(
                new RepeatContent("RepeatParentContent")
                    .AddItem(
                        new RepeatContent("RepeatChildrenContent").Hide()
                            .AddItem(new FieldContent("OrganizationName", "Рога и копыта")))
            );

            using (var outputDocument = new TemplateProcessor("OutputDocument.docx")
                .SetRemoveContentControls(true))
            {
                outputDocument.FillContent(valuesToFill);
                outputDocument.SaveChanges();
            }
        }
    }
}

Is NuGet Updated?

I just added the library to my project using NuGet (version 1.1.1) and when I execute the following code:

    public static void CopyTemplate()
    {
        File.Copy("TemplateBasic.docx", "outputPath.docx", true);
        var valuesToFill = new Content(
            new FieldContent("ReportDate", DateTime.Now.ToString()));

        using (var outputDoc = new TemplateProcessor("OutputDoc.docx"))
        {
            outputDoc.FillContent(valuesToFill);
            outputDoc.SaveChanges();
        }
    }

It fails indicating a null reference in the LoadPart method.
The template that I use is very basic, it only contains a field.
If I get the latest code from GitHub instead, everything works.
Is the NuGet library out of sync?

How to insert line break?

Need a way to insert line breaks (paragraph) in a FieldContent, as using \r\n in the string does not work.

Repetating Contents

Hi!
When I put fields inside repeating contents, templateEngine doesn't fill value of Fields Contents inside of content.
Can you please show example how to fill fields inside repeating contents?

How insert paragraph on new line (\r\n)

What if I need to insert Paragraph on new line ?

Early here was issue #2 , and was addes code:

public static void ReplaceNewLinesWithBreaks(XElement xElem)
        {
            if (xElem == null) return;

            var textWithBreaks = xElem.Descendants(W.t).Where(t => t.Value.Contains("\r\n"));
            foreach (var textWithBreak in textWithBreaks)
            {
                var text = textWithBreak.Value;
                var split = text.Replace("\r\n", "\n").Split(new[] { "\n" }, StringSplitOptions.None);
                textWithBreak.Value = string.Empty;
                foreach (var s in split)
                {
                    textWithBreak.Add(new XElement(W.t, s));
                    textWithBreak.Add(new XElement(W.br));
                }
                textWithBreak.Descendants(W.br).Last().Remove();
            }
        }

But when it insert br - it don't copy style for element (like padding). How can I add real paragraph ? I tried make like this, but it's breaking document:

 public static void ReplaceNewLinesWithBreaks(XElement xElem)
        {
            if (xElem == null) return;

            var textWithBreaks = xElem.Descendants(W.t).Where(t => t.Value.Contains("\r\n"));
            foreach (var textWithBreak in textWithBreaks)
            {
                var text = textWithBreak.Value;
                var split = text.Replace("\r\n", "\n").Split(new[] { "\n" }, StringSplitOptions.None);
                textWithBreak.Value = string.Empty;
                foreach (var s in split)
                {
                    xElem.Add(new XElement(W.p, new XElement(W.r, new XElement(W.t, s))));      //here changed code              
                }                                
            }
        }

Maybe I can get some true parent element, where I can add those new Paragraphs ?

Thank you!!

Create a grouped table?

Is there any way to create a grouped table? I want to create a table of items, where the items are grouped by having a merged header row.

something like this:

[Section 1]
[Section Item1 Column 1] [Section Item1 Column 2]
[Section Item1 Column 1] [Section Item1 Column 2]
[Section 2]
[Section Item2 Column 1] [Section Item2 Column 2]
[Section Item2 Column 1] [Section Item2 Column 2]
[Section Item2 Column 1] [Section Item2 Column 2]

That would be awesome if that was possible.

Filling ImageContent and with images of arbitrary size

I would like to be able able to protect the aspect ratio of the images I am placing in my template.

My Picture Content Control is inside a table cell and I am trying to make sure my image shrinks respecting the original aspect ratio just enough to fit in.

For this, I could resize the image myself, before using it to fill the control. I understand this is outside the scope of TemplateEngine.Docx,. However, I couldn't find a better place to ask this. Could someone show me the way to solve this?

Add support for conditional statements

It's would be nice to have functionality that allows to display templates based on condition.
For example if property of FieldContent equals true display one block of templates and another one in case of false.

Empty content exception

When generating empty content (for example, RepeatContent) library throws. Some lists can be empty in generated document so I think library should not throw but generate as hidden.

Stack:

Unhandled Exception: System.ArgumentNullException: Value cannot be null.
Parameter name: source
   at System.Linq.Enumerable.SelectMany[TSource,TResult](IEnumerable`1 source, Func`2 selector)
   at TemplateEngine.Docx.Container.<>c.<get_FieldNames>b__26_1(RepeatContent t)
   at System.Linq.Enumerable.<SelectManyIterator>d__17`2.MoveNext()
   at System.Linq.Enumerable.<ConcatIterator>d__59`1.MoveNext()
   at System.Linq.Enumerable.<ConcatIterator>d__59`1.MoveNext()
   at System.Linq.Enumerable.<ConcatIterator>d__59`1.MoveNext()
   at System.Linq.Enumerable.<ConcatIterator>d__59`1.MoveNext()
   at System.Linq.Enumerable.<ConcatIterator>d__59`1.MoveNext()
   at System.Linq.Enumerable.<SelectManyIterator>d__17`2.MoveNext()
   at System.Linq.Enumerable.<DistinctIterator>d__64`1.MoveNext()
   at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
   at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
   at TemplateEngine.Docx.TableContent.get_FieldNames()
   at TemplateEngine.Docx.Processors.TableProcessor.FillContent(XContainer contentControl, IContentI
tem item)
   at TemplateEngine.Docx.Processors.TableProcessor.FillContent(XElement contentControl, IEnumerable
`1 items)
   at TemplateEngine.Docx.Processors.ContentProcessor.FillContent(XElement content, IEnumerable`1 da
ta)
   at TemplateEngine.Docx.TemplateProcessor.FillContent(Content content)
   at HiddenRepeatRepro.Program.Main(String[] args) in D:\Work\HiddenRepeatRepro\Program.cs:line 49

Template: EmptyContentTemplate.docx

Repro:

using System;
using System.IO;
using TemplateEngine.Docx;

namespace EmptyContentRepro
{
	static class Program
	{
		static void Main(string[] args)
		{
			string templateFile = "EmptyContentTemplate.docx";
			string outputFile = "EmptyContentRepro.docx";

			File.Delete(outputFile);
			File.Copy(templateFile, outputFile);

			var repeat = new RepeatContent("repeat1"); // empty
			var table = new TableContent("table1").AddRow(repeat);
			var content = new Content(table);

			using (var template = new TemplateProcessor(outputFile).SetRemoveContentControls(true))
			{
				template.FillContent(content);
				template.SaveChanges();
			}
		}
	}
}

Hard reference to DocumentFormat.OpenXml v2.5.0

The current Nuget package (v1.1.4) lists the following dependancy:

DocumentFormat.OpenXml (>= 2.5.0)

but upgrading DocumentFormat.OpenXml to a newer version (ex. 2.7,2) causes a runtime exception:

System.IO.FileNotFoundException: 'Could not load file or assembly 'DocumentFormat.OpenXml, Version=2.5.5631.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35' or one of its dependencies. The system cannot find the file specified.'

Ignore Table Content Control error

Hi,

I am getting a number of errors when I provide to many Field Content Controls to the parser:

Field Content Control 'user.Id' not found.

But the document continues parsing, which is fine.

However when I provide more fields in a table, the parsing fails without continuing:

Table Content Control 'data.Users' doesn't contain rows with cell content controls 'Id', 'Name', 'Email', 'LanguageId'.

(some of the fields are in the document, some are not)

Is it possible to configure parsing to ignore extra fields provided to the parser?
I am dynamically providing objects to the parsers, so when new properties are added to the object, they are offered to the parser. However in a table this throws an exception 😞

Styled content?

I need to replace the field with styled (bold, italic, e.t.c) content. I have the ability to convert my content to an OpenXML string. For example:

<w: pxmlns: w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"><w: r><w: txml: space="preserve">Thisisjust</w: t></w: r><w: r><w: rPr><w: b/></w: rPr><w: txml: space="preserve">arandom</w: t></w: r><w: r><w: txml: space="preserve">pargraph</w: t></w: r></w: p>

However, I can't figure out how to replace the placeholder with that styled content.

Десериализация Content

Объект Content отлично сериализуется в json, но десериализовать его не получается из за интерфейсов в конструкторе.
Я думаю было бы отлично реализовать что-нибудь типа new Content(json).
Это значительно расширит возможности применения библиотеки.
А что думаете Вы?

Deploying DLL to GAC

Hello! There is a problem when deploying the DLL of your project (installed via NuGet) to GAC. Using Visual Studio deployment (deploying SharePoint solution) fails with error "Error occurred in deployment step 'Add Solution': This solution contains one or more assemblies targeted for the global assembly cache. You should use a strong name for any assembly that will be in the global assembly cache."
Then, when I tried to use Gacutil I've got "Failure adding assembly to the cache: Attempt to install an assembly without a strong name". According to Google this can be fixed with signing the project of DLL (project properties -> Signing tab). For myself I've got it fixed with signing the project of your library and rebuilding it.

Filling nested lists with multiple levels and additional fields

Hi,
I couldn't find a solution or an example on how to fill a document that consists of a list with multiple levels and more than one field on each level.

  1. Level1Header
    Level1Description1
    Level2Description2
    1.1 Level2Header
    Level2Description1
    Level2Description2
    1.1.1 Level3Header
    Level3Description1
    Level3Description2

I hope my description is understandable and you can provide me an example, so I can understand how nested lists work.

Best Regards,
Roman

Cannot install NuGet package in project targetting .NET 4.5.1

When trying to install the NuGet Package I receive the message "Could not install package 'TemplateEngine.Docx 1.1.5'. You are trying to install this package into a project that targets '.NETFramework,Version=v4.5.1', but the package does not contain any assembly references or content files that are
compatible with that framework. For more information, contact the package author."

Is this really not compatible with this version?

BUG: Table inside a Table Cell

There seems to be a bug in table nesting. I tried to put a table in a table cell, when it generates there is no error but the whole row does not show anything. The main table is part of a List
Conceptual Structure:

<List>
 <MainTable>
   <Row>
      <Cell1>
             fields....
      </Cell1>
     <Cell2>
             <ChildTable>
                    <Row>
                          fields...  
                    </Row>
             </ChildTable>
     </Cell2>

   </Row>
  </MainTable>
</List>

Header/Footer support

Library is not working with fields declared in header/footer (I tested only footer)
Библиотека не работает с полями определенными в колонтитулах

Создание документа по шаблону и отправка пользователю для скачивания

Можно ли создать документ по шаблону без сохранения на сервере, чтобы он сразу отправлялся пользователю для скачивания?
Ситуация такая - есть сайт, пользователи заходят, заполняют форму, данные сохраняются на сервере, а для пользователя формируется файл с заполненными им данными. Получается, что если одновременно для нескольких пользователей генерируется файл, то он удаляется, перезаписывается, и пользователь может получить не свои данные...

Add subdocuments in the header section of other document

Hi,

We want to insert the body of document A into the header of document B. For this task we could use a SUBDOCUMENT content control which we need to place it in the header of the document B.

¿Would it be possible to implement it with this template engine?

Thanks in advance

Ignore errors

Code

Is there a way to prevent errors being written into the .docx?

The .docx I'm using doesn't implement all of the Content Control tags that are passed into the document.

Error 'Sequence contains no elements' when TableContent have not rows. (count == 0)

callstack:

at System.Linq.Enumerable.First[TSource](IEnumerable1 source) at TemplateEngine.Docx.Processors.TableProcessor.GetPrototype(XContainer tableContentControl, IEnumerable1 fieldNames)
at TemplateEngine.Docx.Processors.TableProcessor.FillContent(XContainer contentControl, IContentItem item)
at TemplateEngine.Docx.Processors.TableProcessor.FillContent(XElement contentControl, IEnumerable1 items) at TemplateEngine.Docx.Processors.ContentProcessor.FillContent(XElement content, IEnumerable1 data)
at TemplateEngine.Docx.Processors.ContentProcessor.FillContent(XElement content, Content data)
at TemplateEngine.Docx.TemplateProcessor.FillContent(Content content)

Add support for RepeatContent within RepeatContent (or ListContent)

Adding a RepeatContent to a RepeatContent does not work.
It would be helpful to create a nested structure of text.
image
(n products, have n patches with n changes)
Otherwise nested ListContent would be an alternative to have nested ListContent blocks .

something like:

var valuesToFill = new Content(new RepeatContent("RepeatParentContent")
.AddItem(new FieldContent("Title", "Tests"),
new RepeatContent("RepeatChildrenContent", new FieldContent("SubTest", "WORKS!!!!"))
.AddItem(new RepeatContent("RepeatChildrenContent", new FieldContent("SubTest", "WORKS also!!!!")))
);

Newer Nuget-package

Hi,

Thank you for this library!

It's been a while since the NuGet package was updated, and I see changes that I would very much like to use. Would you mind updating the package? :)

Tables without rows give a cryptic error message

I made a mistake building the Content and created a Table with zero rows.

The error thrown was

Message: System.ArgumentNullException : Value cannot be null.
Parameter name: source

Result StackTrace:	
at System.Linq.Enumerable.SelectMany[TSource,TResult](IEnumerable`1 source, Func`2 selector)
   at TemplateEngine.Docx.Container.<>c__DisplayClass26_0.<get_FieldNames>b__3(TableContent t)
   at System.Linq.Enumerable.SelectManySingleSelectorIterator`2.MoveNext()
   at System.Linq.Enumerable.ConcatIterator`1.MoveNext()
   at System.Linq.Enumerable.ConcatIterator`1.MoveNext()
   at System.Linq.Enumerable.SelectManySingleSelectorIterator`2.MoveNext()
   at System.Linq.Set`1.UnionWith(IEnumerable`1 other)
   at System.Linq.Enumerable.DistinctIterator`1.FillSet()
   at System.Linq.Enumerable.DistinctIterator`1.ToList()
   at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
   at TemplateEngine.Docx.RepeatContent.get_FieldNames()
   at TemplateEngine.Docx.Processors.RepeatProcessor.FillContent(XElement contentControl, IContentItem item)
   at TemplateEngine.Docx.Processors.RepeatProcessor.FillContent(XElement contentControl, IEnumerable`1 items)
   at TemplateEngine.Docx.Processors.ContentProcessor.FillContent(XElement content, IEnumerable`1 data)
   at TemplateEngine.Docx.Processors.ContentProcessor.FillContent(XElement content, Content data)
   at TemplateEngine.Docx.TemplateProcessor.FillContent(Content content)
   at Slingshot.Templates.WordTemplate.WordTemplateProcessor.FillContent(Content valuesToFill)
   at Slingshot.Templates.WordTemplate.WordTemplateProcessor.FillContentFromModel(Object model)
   at Slingshot.PropostaDeServico.PropostaDeServicoTemplate.GerarDocumento(IArchive archive, PropostaDeServicoModel model)
   at Slingshot.PipelineAtm.PipelineAtmFull.GerarAtmFull(Stream sementeStream, Stream outputStream)
   at Slingshot.PipelineAtm.Tests.PipelineAtmFullTests.CreateOutput()
Result Message:	
System.ArgumentNullException : Value cannot be null.
Parameter name: source

I traced it to an attempt by a RepeatContent to enumerate all its children, on class Container, at FieldNames:

var repeatsFieldNames = Repeats == null
   ? new List<string>()
   : Repeats.Select(t => t.Name).Concat(Repeats.SelectMany(t => t.Items.SelectMany(r => r.FieldNames)));

I'm not sure if TableContents must have rows, but I recommend a better error message to save us the time diagnosing this situation.

License doesn't allow linux use

Greetings! This library is excellent and I've been happily using it on Windows for a while. However, I would like to have it compiled and used on a Linux environment, but the license (MS-LPL) doesn't allow that freedom. If it makes no difference to you, can you change the license to a very similar, but more permissive one such as MS-PL?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.