GcWord now includes Template tag syntax check upon Template processing. The template tag candidates will be scanned and the structure will be examined. If any errors are found, an exception will be thrown with detailed information about problem.
In the example below, Date Format specified in Paragraph is parsed. The characters specified in the format are scanned and reported in the exception.
var coll = new[] { DateTime.Parse("2022/02/12"), DateTime.Parse("1011/03/04") };
var doc = new GcWordDocument();
doc.DataTemplate.DataSources.Add("ds", coll);
doc.Body.Paragraphs.Add(@"{{ds.value}:format(yyyy:MM:dd)}");
doc.DataTemplate.Process();
//result
GrapeCity.Documents.Word.InvalidTemplateFormatException:
'Template key {{ds.value}:format(yyyy:MM:dd)} have non-escaped service char in the formatter param at position 23.
Chars '(',')',':','{','}' should be escaped.'
With GcWord templates, you can now add specific culture to specific data source added to the template. New culture parameter can now be provided in doc.DataTemplate.DataSources.Add(..) method. If this parameter is set, all culture-specific conversions with tags from the datasource will use the provided culture.
Following code adds separate cultures for separate data sources -
Demo - Culture specific parsing | Demo - Culture specific formatting
GcWord Templates allow using primitive types such as integer or float in templates and accessing them using the ‘value’ tag. Now the types Decimal, DateTime and DateTimeOffset can also be used in this way.
Following code demonstrates support of DateTime and DateTimeOffset types while adding to datasource, and their access using the value tag to set the Date/DateTime format.
var doc = new GcWordDocument();
// The data source (Napoleon's first italian company battle dates from Wikipedia):
doc.DataTemplate.DataSources.Add("dsItalianBattles", new DateTime[]
{
//first stage
DateTime.Parse("1796/04/12"),
DateTime.Parse("1796/04/14"),
DateTime.Parse("1796/04/15"),
DateTime.Parse("1796/04/19"),
DateTime.Parse("1796/04/22"),
//second stage
DateTime.Parse("1796/05/10"),
DateTime.Parse("1796/09/4"),
DateTime.Parse("1796/10/15"),
DateTime.Parse("1796/12/14"),
});
// The data source (world wide wars start dates):
doc.DataTemplate.DataSources.Add("dsWW", new DateTimeOffset[]
{
DateTimeOffset.Parse("28/07/1914"),
DateTimeOffset.Parse("01/09/1939"),
});
// Add a list template so that the data is formatted as a list:
var myListTemplate = doc.ListTemplates.Add(BuiltInListTemplateId.BulletDefault, "myListTemplate");
//DateTime list
doc.Body.Paragraphs.Add("Napoleon's first italian company battles dates:", doc.Styles[BuiltInStyleId.Heading1]);
// Add a list of battles dates:
var p = doc.Body.Paragraphs.Add("{{#dsItalianBattles}}{{dsItalianBattles.value}:format(yyyy-MM-dd)}{{/dsItalianBattles}}", doc.Styles[BuiltInStyleId.ListParagraph]);
p.ListFormat.Template = myListTemplate;
//DateTimeOffset list
doc.Body.Paragraphs.Add("World wars start dates:", doc.Styles[BuiltInStyleId.Heading1]);
p = doc.Body.Paragraphs.Add("{{#dsWW}}{{dsWW.value}:format(yyyy\\:MM\\:dd)}{{/dsWW}}", doc.Styles[BuiltInStyleId.ListParagraph]);
p.ListFormat.Template = myListTemplate;
You can now customize look of your content in MS Word using new API for applying shadow effect in shapes and text Word .docx files. The new Effects property is added to Font, Shape, Picture, GroupShape, CanvasShape, ShapeStyle and FormatSсheme classes. The Shadow effect is split in four classes:
Following snapshot shows Outer Shadow effect applied to 'Treadstone' text and BuiltInShadowId.ProspectiveLowerLeft enum applied to the shape using GcWord API.
You can apply both custom shadow and built-in shadow to Text and shapes. Please note that currently shadows are not supported in PDF/image exports.
Have a look on detailed API to apply shadow effects on text and shapes below.
View Help Text Shadow | Help Shapes Style Shadow Effect | Help Shape Format Shadow Effect | Demo
Now import your Markdown documents into GcWord and convert to .docx files. GcWord Sample browser now implements a new sample with full source code to convert Markdown .md files to .docx files and PDF. The conversion is done by the GcWordWeb.Samples.MarkdownToWordRenderer.WordRenderer class that uses the Markdig package (BSD 2-Clause license) for parsing .md files., and the GcWord OM to create MS Word documents from it. The WordRenderer C# source code is included in the sample. The MarkdownToWordRenderer sources are located in the Samples/Markdown/Renderer subdirectory of the sample zip.
View Demo
Read the release blog for full details.
Updates included in this release:
GcWord Templates Enhancements:
Read the release blog for full details.
Lists and arrays of primitive types (types for which Type.IsPrimitive gets true) and strings can now be used as data sources in GcWord Report Templates. The array elements' values are injected into the generated document with the "Value" template tag, as the example below shows.
var doc = new GcWordDocument();
// Add a few simple arrays as data sources:
doc.DataTemplate.DataSources.Add("dsInts", new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9 });
doc.DataTemplate.DataSources.Add("dsConsts", new double[] { Math.PI, Math.E, });
doc.DataTemplate.DataSources.Add("dsStrs", new List<string>() { "Pacific", "Atlantic", "Indian", "Southern", "Arctic", });
// Add a list template so that the data is formatted as a list:
var myListTemplate = doc.ListTemplates.Add(BuiltInListTemplateId.BulletDefault, "myListTemplate");
// Integers: doc.Body.Paragraphs.Add("Integers from 1 to 9:", doc.Styles[BuiltInStyleId.Heading1]);
var p = doc.Body.Paragraphs.Add("{{#dsInts}}{{dsInts.value}}{{/dsInts}}", doc.Styles[BuiltInStyleId.ListParagraph]);
p.ListFormat.Template = myListTemplate;
// Math constants:
doc.Body.Paragraphs.Add("Constants from the Math class:", doc.Styles[BuiltInStyleId.Heading1]);
p = doc.Body.Paragraphs.Add("{{#dsConsts}}{{dsConsts.value}}{{/dsConsts}}", doc.Styles[BuiltInStyleId.ListParagraph]);
p.ListFormat.Template = myListTemplate;
// Strings (oceans):
doc.Body.Paragraphs.Add("Strings (oceans):", doc.Styles[BuiltInStyleId.Heading1]);
p = doc.Body.Paragraphs.Add("{{#dsStrs}}{{dsStrs.value}:toupper()}{{/dsStrs}}", doc.Styles[BuiltInStyleId.ListParagraph]);
p.ListFormat.Template = myListTemplate;
You can now define and embed fonts in MS Word documents to render the document correctly, even if the Fonts are missing on the system. With the new Font API, you can now -
The following new additions have been added to the Font API supported in GcWord.
Users can manage fonts in GcWordDocument and GlossaryDocument classes.
The following code embeds the Times New Roman font into a DOCX under a custom name "My font 1":
GcWordDocument doc = new GcWordDocument();
const string myFontName1 = "My Font 1";
// Use first of the fonts to be embedded:
var p = doc.Body.Paragraphs.Add();
var run = p.GetRange().Runs.Add($"Text rendered using embedded font \"{myFontName1}\".");
// Apply custom font to the run:
run.Font.Name = myFontName1;
// (in this case we simply duplicate "Times New Roman"):
var font1 = doc.Fonts.Add(myFontName1);
// Use "Times New Roman" font settings:
font1.CharSet = FontCharSet.Ansi;
font1.Family = FontFamily.Roman;
font1.Pitch = FontPitch.Variable;
font1.Panose = new List<byte> { 2, 2, 6, 3, 5, 4, 5, 2, 3, 4 }; font1.Signature.CodePageRange1 = 0x000001ff;
font1.Signature.CodePageRange2 = 0x00000000;
font1.Signature.UnicodeRange1 = 0xE0002EFF;
font1.Signature.UnicodeRange2 = 0xC000785B;
font1.Signature.UnicodeRange3 = 0x00000009;
font1.Signature.UnicodeRange4 = 0x00000000;
// Load the "Times New Roman" font data:
byte[] data1 = File.ReadAllBytes(Path.Combine("Resources", "Fonts", "times.ttf"));
// Embed font data into the document:
font1.Embedded.Add(EmbeddedFontType.Regular, FontDataType.ObfuscatedTrueTypeFont, data1);
Help | Embed Fonts Demo | List Embed Fonts Demo| Remove Embed Fonts Demo
Check out the release notes for a full list of changes and additions.
In this release, we have made a few changes to streamline our packages. The following changes may require you to change references to GrapeCity.Documents packages in your projects (note that these changes affect only package/dll references, and should not require any changes in your code):
If you have any comments on the new features or want to share how these are helpful, drop a comment below!
Read the release blog for full details.