string html = File.ReadAllText("Source.html");
string newHtml = html.Replace("<br>", "[br]");
File.WriteAllText("NewSource.html", newHtml);
using (Stream stream = File.OpenRead("NewSource.html"))
{
HtmlFormatProvider htmlFormatProvider = new HtmlFormatProvider();
flowDocument = htmlFormatProvider.Import(stream);
TxtFormatProvider txtFormatProvider = new TxtFormatProvider();
string text = txtFormatProvider.Export(flowDocument);
string newText = text.Replace("[br]", "\r\n");
}
The current implementation uses System.Windows.Media.Imaging.BitmapImage class in order to take the image pixels for the PDF export. However, BitmapImage class throws NotSupportedException when being initialized with a WMF or EMF image. WORKAROUND: WMF and EMF images may be converted to PNG images before the PDF export. The following code snippet shows how to convert all inline WMF image to PNG images by using System.Drawing.Image class:private
static
void
ConvertInlineWmfImagesToPng(RadFlowDocument document)
{
foreach
(ImageInline image
in
document.EnumerateChildrenOfType<ImageInline>())
{
if
(image.Image.ImageSource.Extension.Equals(
"wmf"
, StringComparison.InvariantCultureIgnoreCase))
{
using
(MemoryStream wmfImageStream =
new
MemoryStream(image.Image.ImageSource.Data))
{
using
(MemoryStream pngImageStream =
new
MemoryStream())
{
var imageDrawing = System.Drawing.Image.FromStream(wmfImageStream);
imageDrawing.Save(pngImageStream, ImageFormat.Png);
byte
[] pngBytes = pngImageStream.ToArray();
image.Image.ImageSource =
new
ImageSource(pngBytes,
"png"
);
}
}
}
}
}
I have created a very simple template (see attached file), import it, add my contents and later try to do a MailMerge.
However, the call to this function fails with the following exception:System.ArgumentException
HResult=0x80070057
Message=The document element is already associated with a parent.
Parametername: item
Source=Telerik.Windows.Documents.Flow
StackTrace:
at Telerik.Windows.Documents.Flow.Model.Collections.DocumentElementCollection`2.VerifyDocumentElementOnInsert(T item) in c:\DeveloperTooling_Agent13\_work\91\s\Documents\Flow\Flow\Model\Collections\DocumentElementCollection.cs:line 69
at Telerik.Windows.Documents.Core.Data.DocumentElementCollectionBase`2.InsertRange(Int32 index, IEnumerable`1 items) in c:\DeveloperTooling_Agent13\_work\91\s\Documents\Core\Core\Core\Data\DocumentElementCollectionBase.cs:line 129
at Telerik.Windows.Documents.Flow.Model.InlineRangeEditor.InsertInlinesInRange(InlineBase start, IEnumerable`1 inlines) in c:\DeveloperTooling_Agent13\_work\91\s\Documents\Flow\Flow\Model\InlineRangeEditor.cs:line 132
at Telerik.Windows.Documents.Flow.Model.Fields.FieldInfo.UpdateFieldCore(FieldUpdateContext context) in c:\DeveloperTooling_Agent13\_work\91\s\Documents\Flow\Flow\Model\Fields\FieldInfo.cs:line 236
at Telerik.Windows.Documents.Flow.Model.Fields.FieldInfo.UpdateFieldInternal(FieldUpdateContext context) in c:\DeveloperTooling_Agent13\_work\91\s\Documents\Flow\Flow\Model\Fields\FieldInfo.cs:line 186
at Telerik.Windows.Documents.Flow.Model.MailMergeProcessor.ExecuteMailMerge(RadFlowDocument document, Object record) in c:\DeveloperTooling_Agent13\_work\91\s\Documents\Flow\Flow\Model\MailMergeProcessor.cs:line 57
at Telerik.Windows.Documents.Flow.Model.MailMergeProcessor.Execute(RadFlowDocument document, IEnumerable collection) in c:\DeveloperTooling_Agent13\_work\91\s\Documents\Flow\Flow\Model\MailMergeProcessor.cs:line 25
at Telerik.Windows.Documents.Flow.Model.RadFlowDocument.MailMerge(IEnumerable collection) in c:\DeveloperTooling_Agent13\_work\91\s\Documents\Flow\Flow\Model\RadFlowDocument.cs:line 337
at JOIM.TextExport.DocumentGenerator.Export(String outputPath) in P:\Tolaris\JOIM.Common\JOIM.TextExport\DocumentGenerator.cs:line 581
using Telerik.Windows.Documents.Flow.FormatProviders.Docx; using Telerik.Windows.Documents.Flow.Model; using Telerik.Windows.Documents.Spreadsheet.Model; ... using (StreamfileStream = File.Open(templatePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) { var provider = newDocxFormatProvider(); _document = provider.Import(fileStream); } ... _document = Document.MailMerge(new [] { MergeFieldData });
When <div> elements contain non-inline HTML elements, they and their styles are removed on import.
Input:
<div style="margin-left: 200px;">
<ol>
<li>Item 1</li>
<li>Item 2</li>
</ol>
</div>
Output:
<ol style="list-style-type: decimal;">
<li value="1"><span>Item 1</span></li>
<li value="2"><span>Item 2</span></li>
</ol>
Workaround: Set the style properties to the inner elements. They will not disappear.
When the last run from a paragraph is underlined, the associated bullet has underline applied as well. The same applies for the background color.
When importing from HTML, all successive spaces in a spans are trimmed. Instead, in some cases one space should be left, e.g. between words. For example, the importing the following HTML should leave one space after the hyperlink: <p><a href="www.telerik.com" target="_blank"><span>test</span></a> and more.</p> Workaround: After importing, check if the runs after the hyperlinks start with space: foreach (var hyperlinkEnd in this.document.EnumerateChildrenOfType<FieldCharacter>().Where(f => f.FieldCharacterType == FieldCharacterType.End)) { Paragraph currentParagraph = hyperlinkEnd.Paragraph; int indexOfNextRun = currentParagraph.Inlines.IndexOf(hyperlinkEnd) + 1; if (currentParagraph.Inlines.Count > indexOfNextRun) { Run run = currentParagraph.Inlines[indexOfNextRun] as Run; if (run != null && run.Text[0] != ' ') { run.Text = " " + run.Text; } } }
Currently Run.Shading is not exported to PDF. Note: This scenario is common when converting HTML to PDF, as Run.Shading is set when construct like <span style="background-color:#ffcc00;"> is used. Workaround: Iterate all the Runs in the already imported HTML document and set their HighlightColor to Shading.BackgroundColor.LocalValue. Check this code snippet:
foreach (Run run in document.EnumerateChildrenOfType<Run>())
{
if (!run.Properties.HighlightColor.HasLocalValue)
{
run.HighlightColor = run.Shading.BackgroundColor.LocalValue;
}
}
If HTML document is imported, and it contains image with invalid URL, then the image is imported with this URL in the document model. On subsequent export to Docx, the library tries to download the image data, which throws WebException. Instead, the image should be replaced with generic 'error' image. Workaround: Manually test the image URL for correctness on HTML import, and replace the data: static void Main(string[] args) { HtmlFormatProvider htmlFormatProvider = new HtmlFormatProvider(); htmlFormatProvider.ImportSettings.LoadFromUri += (sender, e) => { if (!IsValid(e.Uri)) { e.SetData(File.ReadAllBytes("no-image.png")); } }; } private static bool IsValid(string uri) { try { using (WebClient client = new WebClient()) { client.DownloadData(uri); } } catch (WebException) { return false; } return true; }
<ul>
<li>
<div>Text</div>
</li>
</ul>
Special chars (åäö) with PdfFormatProvider wont work.
Project submitted!
public void SpecialCharsTest()
{
RadFlowDocument document = new RadFlowDocument();
RadFlowDocumentEditor editor = new RadFlowDocumentEditor(document);
editor.InsertText("Before text");
editor.InsertText("åäö ÅÄÖ ☕"); // This line will not appear in the pdf
editor.InsertText("After text");
using (Stream output = new FileStream("specialCharTest.pdf", FileMode.OpenOrCreate))
{
PdfFormatProvider provider = new PdfFormatProvider();
provider.Export(document, output);
}
}
Special characters wont work :-/
This element serves as a frame and allows the element to be positioned as a floating element. More information about it is available in section 22.9.2.18 ST_XAlign (Horizontal Alignment Location) of Open Office XML.
DECLINED: Duplicate with - Implement support for Text Frame Properties.