This is a migrated thread and some comments may be shown as answers.

Mail Merge - PDF Export - Watermark problem

4 Answers 118 Views
RichTextBox
This is a migrated thread and some comments may be shown as answers.
Robert
Top achievements
Rank 1
Robert asked on 25 Feb 2015, 12:03 PM
test

4 Answers, 1 is accepted

Sort by
0
Robert
Top achievements
Rank 1
answered on 25 Feb 2015, 12:08 PM
I am sorry, but it somehow crashed when I was writing the report.
Here is my problem - When Exporting to PDF, and the document contains Watermark, the program completely crashes.
Here is how I am doing the mail merge:
//loop throught documents
do
{
    RadDocument currentDocument = document.MailMergeCurrentRecord();
    if (currentDocument != null)
    {
        //freeze images
        foreach (var image in currentDocument.EnumerateChildrenOfType<ImageInline>())
            image.ImageSource.Freeze();
 
        //Floating images
        foreach (var image in currentDocument.EnumerateChildrenOfType<FloatingImageBlock>())
            image.ImageInline.ImageSource.Freeze();
 
        lock (baton)
            documentQueue.Enqueue(currentDocument);//add new document to a queue for further processing
        currentDocument = null;
    }
 
} while (document.MailMergeDataSource.MoveToNext());


Once I get the document, I generate PDF stream using the following code:
public static async Task<Stream> ExportToPDF(RadDocument document)
{
    PdfFormatProvider provider = new PdfFormatProvider();
    Stream output = new MemoryStream();
 
    await StartSTATask(() =>
    {
        provider.Export(document, output);
    });
    output.Position = 0;
    return output;
}


Everything works just fine, unless I insert Watermark in the document. Then it suddenly crashes on the PDF Export on the following line:
provider.Export(document, output)

Here is full error message:
at System.Windows.Threading.DispatcherObject.VerifyAccess()
   at System.Windows.Media.Imaging.BitmapSource.get_PixelWidth()
   at System.Windows.Media.Imaging.WriteableBitmap.InitFromBitmapSource(BitmapSource source)
   at Telerik.Windows.Media.Imaging.RadBitmap..ctor(BitmapSource image)
   at Telerik.Windows.Documents.FormatProviders.Pdf.PdfDocumentExporter.SetImageAlpha(WatermarkImageSettings imageSettings, Byte alpha)
   at Telerik.Windows.Documents.FormatProviders.Pdf.PdfDocumentExporter.DrawWatermark(Header header, SectionLayoutBox sectionBox, PdfContentsWriter writer)
   at Telerik.Windows.Documents.FormatProviders.Pdf.PdfDocumentExporter.ExportHeadersAndFooters(SectionLayoutBox sectionBox, PdfContentsWriter writer)
   at Telerik.Windows.Documents.FormatProviders.Pdf.PdfDocumentExporter.ExportPage(SectionLayoutBox sectionBox, PdfContentsWriter writer)
   at Telerik.Windows.Documents.FormatProviders.Pdf.PdfDocumentExporter.<>c__DisplayClass1.<Export>b__0(PdfContentsWriter contentsWriter)
   at Telerik.Windows.Documents.FormatProviders.Pdf.RadPdf.PdfContents.WriteContents(PdfWriter writer)
   at Telerik.Windows.Documents.FormatProviders.Pdf.RadPdf.PdfStream.WriteToCore(PdfWriter writer)
   at Telerik.Windows.Documents.FormatProviders.Pdf.RadPdf.PdfObject.WriteTo(PdfWriter writer)
   at Telerik.Windows.Documents.FormatProviders.Pdf.RadPdf.PdfWriter.WritePdfObject(PdfObject obj)
   at Telerik.Windows.Documents.FormatProviders.Pdf.PdfDocumentExporter.Export()
   at Telerik.Windows.Documents.FormatProviders.Pdf.PdfFormatProvider.Export(RadDocument document, Stream output)
   at IP_DocumentProcessor.MailMerge.IP_MailMerge.<>c__DisplayClass14.<ExportToPDF>b__13() in d:\VB Projects + Silverlight\VS2012APP\IP_DocumentProcessor\IP_DocumentProcessor\MailMerge\IP_MailMerge.cs:line 476
   at IP_DocumentProcessor.MailMerge.IP_MailMerge.<>c__DisplayClass1a.<StartSTATask>b__19() in d:\VB Projects + Silverlight\VS2012APP\IP_DocumentProcessor\IP_DocumentProcessor\MailMerge\IP_MailMerge.cs:line 500
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
   at IP_DocumentProcessor.MailMerge.IP_MailMerge.<StartSTATask>d__1c.MoveNext() in d:\VB Projects + Silverlight\VS2012APP\IP_DocumentProcessor\IP_DocumentProcessor\MailMerge\IP_MailMerge.cs:line 510
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at IP_DocumentProcessor.MailMerge.IP_MailMerge.<ExportToPDF>d__16.MoveNext() in d:\VB Projects + Silverlight\VS2012APP\IP_DocumentProcessor\IP_DocumentProcessor\MailMerge\IP_MailMerge.cs:line 474
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
   at IP_DocumentProcessor.MailMerge.IP_MailMerge.<GenerateStreams>d__7.MoveNext() in d:\VB Projects + Silverlight\VS2012APP\IP_DocumentProcessor\IP_DocumentProcessor\MailMerge\IP_MailMerge.cs:line 282
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.AsyncMethodBuilderCore.<ThrowAsync>b__1(Object state)
   at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
   at System.Threading.QueueUserWorkItemCallback.System.Threading.IThreadPoolWorkItem.ExecuteWorkItem()
   at System.Threading.ThreadPoolWorkQueue.Dispatch()


I am quite lost and cannot solve this issue, therefore any help would be highly appreciated.
Thank you.
Robert
0
Accepted
Boby
Telerik team
answered on 27 Feb 2015, 05:24 PM
Hello Robert,

The problem is that the Watermarks images are not frozen. Following is a code sample which will freeze the images in the main document, in all child documents and in the watermarks:
private RadDocument GetDocumentForExport()
{
    using (var reader = File.OpenText(@"D:\temp\headerinlineimage.xaml"))
    {
        var doc = new XamlFormatProvider().Import(reader.ReadToEnd());
 
        this.FreezeWatermarks(doc);
 
        this.FreezeImageSources(doc);
 
        foreach (RadDocument childDocument in GetAllChildDocuments(doc))
        {
            this.FreezeImageSources(childDocument);
        }
 
        return doc;
    }
}
 
private void FreezeWatermarks(RadDocument doc)
{
    foreach (Section section in doc.Sections)
    {
        this.FreezeWatermark(section.Headers.Default);
        this.FreezeWatermark(section.Headers.Even);
        this.FreezeWatermark(section.Headers.First);
    }
}
 
private void FreezeWatermark(Header header)
{
    if (header != null && header.WatermarkSettings.ImageSettings != null && header.WatermarkSettings.ImageSettings.ImageSource != null)
    {
        header.WatermarkSettings.ImageSettings.ImageSource.Freeze();
    }
}
 
private void FreezeImageSources(RadDocument document)
{
    foreach (var imageInline in document.EnumerateChildrenOfType<ImageInline>())
    {
        imageInline.ImageSource.Freeze();
    }
}
 
internal IEnumerable<RadDocument> GetAllChildDocuments(RadDocument document)
{
    foreach (CommentRangeEnd commentRangeEnd in document.EnumerateChildrenOfType<CommentRangeEnd>())
    {
        if (commentRangeEnd.Comment != null && commentRangeEnd.Comment.Body != null)
        {
            yield return commentRangeEnd.Comment.Body;
        }
    }
 
    foreach (NoteRangeEndBase noteRangeEnd in document.EnumerateChildrenOfType<NoteRangeEndBase>())
    {
        if (noteRangeEnd.Note != null && noteRangeEnd.Note.Body != null)
        {
            yield return noteRangeEnd.Note.Body;
        }
    }
 
    foreach (var doc in GetAllHeaderFooterDocuments(document))
    {
        yield return doc;
    }
}
 
internal IEnumerable<RadDocument> GetAllHeaderFooterDocuments(RadDocument document)
{
    foreach (Section section in document.Sections)
    {
        foreach (RadDocument headerFooterDocument in GetAllHeaderFooterDocuments(section))
        {
            yield return headerFooterDocument;
        }
    }
}
 
private IEnumerable<RadDocument> GetAllHeaderFooterDocuments(Section section)
{
    foreach (RadDocument document in GetAllNotNullHeadersFooters(section.Headers).Select(x => x.Body))
    {
        if (document != null)
        {
            yield return document;
        }
 
    }
 
    foreach (RadDocument document in GetAllNotNullHeadersFooters(section.Footers).Select(x => x.Body))
    {
        if (document != null)
        {
            yield return document;
        }
    }
}
 
internal IEnumerable<HeaderFooterBase> GetAllNotNullHeadersFooters<T>(HeadersFootersBase<T> headersFooters) where T : HeaderFooterBase, new()
{
    if (headersFooters.First != null)
    {
        yield return headersFooters.First;
    }
 
    if (headersFooters.Even != null)
    {
        yield return headersFooters.Even;
    }
 
    if (headersFooters.Default != null)
    {
        yield return headersFooters.Default;
    }
}

You can use all of it or only the part for freezing the watermarks (FreezeWatermarks() method).

Regards,
Boby
Telerik
 

Check out the Telerik Platform - the only platform that combines a rich set of UI tools with powerful cloud services to develop web, hybrid and native mobile apps.

 
0
Robert
Top achievements
Rank 1
answered on 02 Mar 2015, 01:37 PM
Fantastic, thank you!
0
Robert
Top achievements
Rank 1
answered on 02 Mar 2015, 01:38 PM
Fantastic, thank you!
Tags
RichTextBox
Asked by
Robert
Top achievements
Rank 1
Answers by
Robert
Top achievements
Rank 1
Boby
Telerik team
Share this question
or