RadWordsProcessing enables you to open, create, modify and save flow documents and supports the most common flow document formats – DOCX, RTF, HTML and plain text. To utilize the abilities of the library you need to add three assemblies to your project:
Since we are talking about flow formats, no wonder the base class of the document model is RadFlowDocument. Let’s create one.
RadFlowDocument document =
new
RadFlowDocument();
Let’s create one and associate it with our document. Further, to make sure our document is neatly aligned, let’s specify that all content added to the editor should be justified.
RadFlowDocumentEditor editor =
new
RadFlowDocumentEditor(document);
editor.ParagraphFormatting.TextAlignment.LocalValue = Alignment.Justified;
Now we are ready to start populating content. We can add a table to the document, place the text in one of its cells and the image in the other. Both of our table cells would need their own child paragraph elements, so we are going to add one in the first cell.
Table bodyTable = editor.InsertTable(1, 2);
Paragraph paragraphWithText = bodyTable.Rows[0].Cells[0].Blocks.AddParagraph();
editor.MoveToParagraphStart(paragraphWithText);
And in that first paragraph let’s say hello:
editor.InsertLine(
"Dear Telerik User,"
);
See how easy that was? The content editor would flow any content you want for you. Say you want to add a large paragraph of text. That’s not a problem – the InsertLine() method will add it for you and will break the line so you can immediately add to the next paragraph after that.
editor.InsertLine(
"We're happy to introduce the new Telerik RadWordsProcessing component for WPF. High performance library that enables you to read, write and manipulate documents in DOCX, RTF, HTML and plain text format."
);
Let’s play around a little. Say you don’t want to break the current line, but you want to style separate words in your paragraph in different ways. That’s pretty easy too. The InsertLine() and InsertText() methods return the Run element they’ve added to the document. This allows you to directly modify the properties of the run. The next snippet will add some bold, italic, underlined, larger than the rest of the document and colorized text and will then complete the second paragraph.
editor.InsertText(
"The current beta version comes with full rich-text capabilities including "
);
editor.InsertText(
"bold, "
).FontWeight = FontWeights.Bold;
editor.InsertText(
"italic, "
).FontStyle = FontStyles.Italic;
Run underlined = editor.InsertText(
"underline,"
);
underlined.Underline.Pattern = UnderlinePattern.Dotted;
underlined.Underline.Color =
new
ThemableColor(Colors.Black);
editor.InsertText(
" font sizes and "
).FontSize = 20;
editor.InsertText(
"colors "
).ForegroundColor = GreenColor;
editor.InsertLine(
"as well as text alignment and indentation. Other options include tables, lists, hyperlinks, bookmarks and comments, inline and floating images. Even more sweetness is added by the built-in styles and themes."
);
And here is the result:
This seems like enough text to me, let’s finish the email and sign it. We can also include a link to the Telerik site, so the users we send this to will be able to reach us.
editor.InsertLine(
"We hope you’ll enjoy RadWordsProcessing as much as we do. Happy coding!"
);
editor.InsertParagraph().Spacing.SpacingAfter = 0;
editor.InsertLine(
"Regards,"
);
editor.InsertHyperlink(
"Telerik Team "
,
"http://www.telerik.com"
,
false
,
"Telerik Site"
);
Just like the InsertText() method returns the inserted run, the InsertParagraph() method returns the paragraph that was added. This allows you to make all sort of modifications, in this case I set the spacing-after of the paragraph saying “Regards” to 0.
At this point all desired text is in the first table cell, whereas the second cell is completely empty which is why it is not visible in the above pictures. Let’s add a paragraph that contains a picture in it.
In my project I’ve create a helper class that will obtain the picture as a resource stream. Here is what it does:
public
static
Stream GetSampleResourceStream(
string
resource)
{
var streamInfo = Application.GetResourceStream(GetResourceUri(SampleDataFolder + resource));
if
(streamInfo !=
null
)
{
return
streamInfo.Stream;
}
return
null
;
}
private
static
Uri GetResourceUri(
string
resource)
{
AssemblyName assemblyName =
new
AssemblyName(
typeof
(FileHelper).Assembly.FullName);
string
resourcePath =
"/"
+ assemblyName.Name +
";component/"
+ resource;
Uri resourceUri =
new
Uri(resourcePath, UriKind.Relative);
return
resourceUri;
}
I can just use that stream and directly insert it through the content editor:
Paragraph paragraphWithImage = bodyTable.Rows[0].Cells[1].Blocks.AddParagraph();
editor.MoveToParagraphStart(paragraphWithImage);
using
(Stream stream = FileHelper.GetSampleResourceStream(
"WordsProcessing.png"
))
{
editor.InsertImageInline(stream,
"png"
,
new
Size(470, 261));
}
Our document is ready. All that is left is to export it.
Each of the file formats supported by RadWordsProcessing corresponds to a format provider class which enables you to easily import and export documents. Since we are exporting to HTML, we should create an HtmlFormatProvider instance.
HtmlFormatProvider formatProvider =
new
HtmlFormatProvider();
The format provider exposes two overloads – one exports the document to a string and the other to the stream you pass to it. I’ll go ahead and use both. In this way my users will be able to view the generated HTML in a WebBrowser control:
string
html = formatProvider.Export(document);
WebBrowser browser =
new
WebBrowser();
browser.NavigateToString(html);
Window window =
new
Window() { Width = 1000, Height = 350 };
window.Content = browser;
window.Show();
And they will be able to save it at a destination of their choice:
SaveFileDialog dialog =
new
SaveFileDialog();
dialog.Filter = String.Format(
"{0} files|*{1}|All files (*.*)|*.*"
,
"HTML"
,
formatProvider.SupportedExtensions.First());
dialog.FilterIndex = 1;
if
(dialog.ShowDialog() ==
true
)
{
using
(var stream = dialog.OpenFile())
{
formatProvider.Export(document, stream);
}
}
I will just add a couple of buttons to the view that will execute the above code:
<
Window.Resources
>
<
local:ExampleViewModel
x:Key
=
"context"
/>
</
Window.Resources
>
<
Grid
>
<
StackPanel
Margin
=
"3"
DataContext
=
"{Binding Source={StaticResource context}}"
>
<
telerik:RadButton
Content
=
"Save"
Command
=
"{Binding SaveCommand}"
Margin
=
"0,10,0,0"
/>
<
telerik:RadButton
Content
=
"Show"
Command
=
"{Binding ShowCommand}"
Margin
=
"0,10,0,0"
/>
</
StackPanel
>
</
Grid
>
The code for the project is available in our SDK repository here. Go ahead and try it out. I also encourage you to reach out to us and tell us what you need from your document processing library.
Stay tuned for more goodies we are cooking for you.
Petya Sotirova was a Technical Support Manager for Telerik and Kendo UI.