RadDocument: IOException while exporting the document to byte array

2 Answers 23 Views
Telerik Trainer
Ghiath
Top achievements
Rank 1
Ghiath asked on 04 Mar 2024, 11:38 AM | edited on 04 Mar 2024, 11:51 AM

I am currently experiencing an I/O exception when trying to export the RadDocument to a byte array using the Telerik.Windows.Documents.FormatProviders.Pdf.PdfFormatProvider.

Here is a code snippet of how am I using the Provider:

PdfFormatProvider pdfProvider = new PdfFormatProvider();

_printReportByteArray = pdfProvider.Export(_printReportDocument);

using (var memoryStream = new MemoryStream(_printReportByteArray))
{
    this.PrintReportViewer.DocumentSource = new PdfDocumentSource(memoryStream);
}

The exception occurs at

pdfProvider.Export(_printReportDocument)

It appears that the provider is trying to load the font file from the Windows directory, but for some reason this particular file is causing the exception randomly on certain machines (not on all machines). I would like to know if there is a way to resolve this issue. Like loading the font file into the memory instead of relying on the Windows directory.

Note: the font file does exist at the provided path location, and is not missing.

Here is the full exception message:

System.IO.IOException: I/O error occurred while opening the file "C:\WINDOWS\FONTS\MSYH.TTC".
   at MS.Internal.FontCache.FileMapping.OpenFile(String fileName)
   at MS.Internal.FontCache.FontSource.GetUnmanagedStream()
   at System.Windows.Media.GlyphTypeface.ComputeSubset(ICollection`1 glyphs)
   at Telerik.Windows.Documents.FormatProviders.Pdf.Fonts.GlyphMappings.ComputeSubset(PdfFontKey key, ICollection`1 glyphs)
   at Telerik.Windows.Documents.FormatProviders.Pdf.RadPdf.PdfFontFile2.CreateFileFontFile()
   at Telerik.Windows.Documents.FormatProviders.Pdf.RadPdf.PdfFontFile2.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 Telerik.Windows.Documents.FormatProviders.DocumentFormatProviderBase.Export(RadDocument document)
   at Cairful.Desktop.Module.Care.NursingReports.NursingReports.Dialogs.PrintReportsDialogVM.PrintReportDocument()
   at Cairful.Desktop.Module.Care.NursingReports.NursingReports.Dialogs.PrintReportsDialog.PrintReportsDialog_OnLoaded(Object sender, RoutedEventArgs e)
   at System.Windows.RoutedEventHandlerInfo.InvokeHandler(Object target, RoutedEventArgs routedEventArgs)
   at System.Windows.EventRoute.InvokeHandlersImpl(Object source, RoutedEventArgs args, Boolean reRaised)
   at System.Windows.UIElement.RaiseEventImpl(DependencyObject sender, RoutedEventArgs args)
   at System.Windows.UIElement.RaiseEvent(RoutedEventArgs e)
   at System.Windows.BroadcastEventHelper.BroadcastEvent(DependencyObject root, RoutedEvent routedEvent)
   at System.Windows.BroadcastEventHelper.BroadcastLoadedEvent(Object root)
   at MS.Internal.LoadedOrUnloadedOperation.DoWork()
   at System.Windows.Media.MediaContext.FireLoadedPendingCallbacks()
   at System.Windows.Media.MediaContext.FireInvokeOnRenderCallbacks()
   at System.Windows.Media.MediaContext.RenderMessageHandlerCore(Object resizedCompositionTarget)
   at System.Windows.Media.MediaContext.RenderMessageHandler(Object resizedCompositionTarget)
   at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs)
   at System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Int32 numArgs, Delegate catchHandler)


2 Answers, 1 is accepted

Sort by
0
Dess | Tech Support Engineer, Principal
Telerik team
answered on 04 Mar 2024, 01:36 PM

Hi, Ghiath,

I am sorry to hear that you are facing any difficulties with our PdfProcessing library. However, according to the provided information, it wouldn't be easy to determine what causes this undesired behavior. Could you please elaborate?

Even though I can make only conjectures for the possible reasons, I would recommend you to register the specific font which may not be a part of the standard fontsRegistering a Font.

An alternative approach is to implement your own FontsProvider

It is hard for us to investigate the issues without actually having the problematic file. Please try and prepare a sample file without the sensitive information. If you decide you can also submit a support ticket from your Telerik account and send us the original file. You can be certain that it will be used only for investigation purposes of this case and your privacy will be respected. Confidentiality is also described in our product EULA - See Section 11 of the EULA and Article V Section 11 of the DevCraft Complete and DevCraft Ultimate EULAs. 
  
Looking forward to your reply. 
  

Regards,
Dess | Tech Support Engineer, Principal
Progress Telerik

A brand new ThemeBuilder course was just added to the Virtual Classroom. The training course was designed to help you get started with ThemeBuilder for styling Telerik and Kendo UI components for your applications. You can check it out at https://learn.telerik.com
Ghiath
Top achievements
Rank 1
commented on 20 Mar 2024, 11:27 AM | edited

I wanted to try your proposed solution, but I encountered another issue. The FontsProperties class used in the FontsProvider implementation and other types are implemented in both the "Telerik.Documents.Core" and "Telerik.Windows.Documents.Core" (which I already use) NuGet packages. To get your solution working, I had to remove the "Telerik.Windows.Documents.Core" NuGet package. However, this package is required in various codes across different projects within my solution, primarily for PDF processing (e.g., PdfViewer).

The NuGet packages are causing conflicts, and I cannot remove the "Telerik.Windows.Documents.Core" package to make your solution work. Do you know how to resolve this issue?.

Here's an example of the error I'm getting:

Error CS0433: The type 'PageOrientation' exists in both 'Telerik.Documents.Core, Version=2024.1.124.20, Culture=neutral, PublicKeyToken=5803cfa389c90ce7' and 'Telerik.Windows.Documents.Core, Version=2024.1.124.20, Culture=neutral, PublicKeyToken=5803cfa389c90ce7'.

Dess | Tech Support Engineer, Principal
Telerik team
commented on 20 Mar 2024, 04:23 PM

Hi, Ghiath,

According to the described scenario, it seems that the assemblies for .NET Standard and .NET Framework are mixed. The Telerik Document Processing libraries are available in .NET Framework and .NET Standard (.NET Core) compatible versions. Both versions are available as NuGet packages but with different names. The assemblies for .NET Standard do not contain the word Windows in their name. Use these assemblies which are applicable for the target framework you are using in the project and do not mix different versions.

Telerik Document Processing is part of several Telerik bundles and is installed following the steps for installing the suite with which you've obtained the product: Installing on Your Computer

Ghiath
Top achievements
Rank 1
commented on 21 Mar 2024, 11:15 AM

To implement the FontsProvider I need the NuGet package "Telerik.Documents.Core" (FontsProviderBase exists only in this NuGet), therefor I cannot implement this class using the NuGet "Telerik.Windows.Documents.Core". 
But I can't use the NuGet "Telerik.Documents.Core", because this creates conflicts with the NuGet "Telerik.Windows.Documents.Core".
I also cannot delete the NuGet "Telerik.Windows.Documents.Core" because I need it in my projects.
I hope my issue is clear now.
0
Dess | Tech Support Engineer, Principal
Telerik team
answered on 22 Mar 2024, 07:16 AM

Hi, Ghiath,

I have reviewed the provided information in the entire communication once again to get better understanding of the precise case. It seems that you are using the .NET Framework version of the Document Processing assemblies. Please correct me if I am wrong. This means that you don't need to implement a FontsProvider since the fonts are locally installed on the Windows machine and it is not expected to be an issue like in the .NET Standard version. 

On the other hand, RadDocument is not related to the Document Processing Libraries in any way. The same is relevant for the PdfDocumentSource. The PdfFormatProvider class is available in many Telerik products with exactly the same name (but different implementation) and it is not only available in the Document Processing Libraries.

That is why I suppose that you are using a UI control from one of the Telerik suites, e.g. either a PdfViewer or a RichTextEditor control. Could you please specify what is the exact product you are currently using? What is the UI control that you need to export from? This information would give us the proper understanding for the complete use case and specify the correct product for this forum thread. Thus, the appropriate support engineers and community would gladly assist you. Thank you.

Regards,
Dess | Tech Support Engineer, Principal
Progress Telerik

Love the Telerik and Kendo UI products and believe more people should try them? Invite a fellow developer to become a Progress customer and each of you can get a $50 Amazon gift voucher.

Ghiath
Top achievements
Rank 1
commented on 08 Apr 2024, 02:01 PM

Thank you for your response. I understand that the font files are located locally on my machine, but relying on these files is causing the original problem I mentioned in my initial post.

Quote from my first post:
"It appears that the provider is trying to load the font file from the Windows directory, but for some reason this particular file is causing the exception randomly on certain machines (not on all machines). I would like to know if there is a way to resolve this issue. Like loading the font file into the memory instead of relying on the Windows directory."

To reiterate my issue: I am using the .NET Framework version of the Document Processing NuGets, especially those that containing "Windows" in their names (e.g., Telerik.Windows.Documents.Core), to generate and display some files.

Here is the flow of what I'm doing:
Creating RadDocument:

RadDocument radDocument = new RadDocument
{
    LayoutMode = DocumentLayoutMode.Paged,
    SectionDefaultPageSize = PaperTypeConverter.ToSize(PaperTypes.A4),
    SectionDefaultPageMargin = new Padding(40, 0, 40, 0)
};

Section documentSection = new Section();
radDocument.Sections.Add(documentSection);

RadDocument headerDocument = new RadDocument();
Header header = new Header { Body = headerDocument };
documentSection.Headers.Default = header;

Section headerSection = new Section();
headerDocument.Sections.Add(headerSection);

Paragraph headerParagraph = new Paragraph();
headerSection.Blocks.Add(headerParagraph);
headerParagraph.Inlines.Add(TextSpan(headerText + "\n", 12, Colors.Gray));
....
footerDocument.Sections.Add(footerSection);
footerSection.Blocks.Add(TextParagraph("\n\n" + footerText, 12, Colors.Gray));
This RadDocument is then used for the UI control "RadPdfViewer" as a document source:

PdfFormatProvider pdfProvider = new PdfFormatProvider();
PrintReportViewer.ClearDocument();
_printReportByteArray = pdfProvider.Export(_printReportDocument);

using (var memoryStream = new MemoryStream(_printReportByteArray))
{
    this.PrintReportViewer.DocumentSource = new PdfDocumentSource(memoryStream);
}
The PdfFormatProvider class comes from the "Telerik.Windows.Documents.FormatProviders.Pdf" namespace. Additionally, I may need to export the Document to a byte array without using it as a document source for the "RadPdfViewer" control, for instance, for saving the generated document in the Database. However, exporting the Document is causing the error mentioned in my first post.

To implement your suggested solution regarding FontsProvider, I need the NuGet package "Telerik.Documents.Core" because FontsProviderBase exists only in this NuGet. That means I cannot implement this class using the NuGet "Telerik.Windows.Documents.Core". Unfortunately, I can't use the NuGet "Telerik.Documents.Core" either, as it conflicts with the NuGet "Telerik.Windows.Documents.Core" I'm already using. An example of the conflict I'm encountering:

Error CS0433: The type 'PageOrientation' exists in both 'Telerik.Documents.Core, Version=2024.1.124.20, Culture=neutral, PublicKeyToken=5803cfa389c90ce7' and 'Telerik.Windows.Documents.Core, Version=2024.1.124.20, Culture=neutral, PublicKeyToken=5803cfa389c90ce7'.
So, I have to choose between using "Telerik.Documents.Core" or "Telerik.Windows.Documents.Core". Unfortunately, I cannot delete the NuGet "Telerik.Windows.Documents.Core" because I need it in various projects.

Once again, here is the error encountered when exporting the "RadDocument":

System.IO.IOException: I/O error occurred while opening the file "C:\WINDOWS\FONTS\MSYH.TTC".
   at MS.Internal.FontCache.FileMapping.OpenFile(String fileName)
   at MS.Internal.FontCache.FontSource.GetUnmanagedStream()
   at System.Windows.Media.GlyphTypeface.ComputeSubset(ICollection`1 glyphs)
   at Telerik.Windows.Documents.FormatProviders.Pdf.Fonts.GlyphMappings.ComputeSubset(PdfFontKey key, ICollection`1 glyphs)
   at Telerik.Windows.Documents.FormatProviders.Pdf.RadPdf.PdfFontFile2.CreateFileFontFile()
   at Telerik.Windows.Documents.FormatProviders.Pdf.RadPdf.PdfFontFile2.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 Telerik.Windows.Documents.FormatProviders.DocumentFormatProviderBase.Export(RadDocument document)
   at Cairful.Desktop.Module.Care.NursingReports.NursingReports.Dialogs.PrintReportsDialogVM.PrintReportDocument()
   at Cairful.Desktop.Module.Care.NursingReports.NursingReports.Dialogs.PrintReportsDialog.PrintReportsDialog_OnLoaded(Object sender, RoutedEventArgs e)
   at System.Windows.RoutedEventHandlerInfo.InvokeHandler(Object target, RoutedEventArgs routedEventArgs)
   at System.Windows.EventRoute.InvokeHandlersImpl(Object source, RoutedEventArgs args, Boolean reRaised)
   at System.Windows.UIElement.RaiseEventImpl(DependencyObject sender, RoutedEventArgs args)
   at System.Windows.UIElement.RaiseEvent(RoutedEventArgs e)
   at System.Windows.BroadcastEventHelper.BroadcastEvent(DependencyObject root, RoutedEvent routedEvent)
   at System.Windows.BroadcastEventHelper.BroadcastLoadedEvent(Object root)
   at MS.Internal.LoadedOrUnloadedOperation.DoWork()
   at System.Windows.Media.MediaContext.FireLoadedPendingCallbacks()
   at System.Windows.Media.MediaContext.FireInvokeOnRenderCallbacks()
   at System.Windows.Media.MediaContext.RenderMessageHandlerCore(Object resizedCompositionTarget)
   at System.Windows.Media.MediaContext.RenderMessageHandler(Object resizedCompositionTarget)
   at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs)
   at System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Int32 numArgs, Delegate catchHandler)
The exception occurs at:
pdfProvider.Export(_printReportDocument)
Vladislav
Telerik team
commented on 11 Apr 2024, 07:54 AM

Hi, Ghiath,

As my colleague Dess mentioned earlier, there are several PDF format providers in several of our products and not all of them are supported by the Document Processing team. The RadDocument class is part of either the RadRichTextBox (from Telerik UI for WPF suite) or the RadRichTextEditor (part of the WinForms suite). Judging by the information that I have up to this point, I would guess that you are using the RadRichTextBox from the WPF suite, but I would ask you to confirm this, so we will be able to send the thread to the right team that can address the issue that you are having.

I am looking forward to your reply.

Ghiath
Top achievements
Rank 1
commented on 11 Apr 2024, 08:32 AM | edited

Hello Vladislav,
yes, your assumption is correct, I am using the WPF version. A tip for replicating this problem would be to attempt exporting the document several times in a short period of time, e.g. by using a loop.
Additionally, Is there a possible quick workaround? Perhaps a different method to convert the RadDocument into a byte array and still using the result as a document source?
Thank you.
Dimitar
Telerik team
commented on 15 Apr 2024, 10:47 AM

Hi Ghiath, 

I have tested this but I cannot reproduce it. I have attached my test project. Could you please check it and let me know what I am missing?

I am looking forward to your reply.

Ghiath
Top achievements
Rank 1
commented on 15 Apr 2024, 01:36 PM

Hello Dimitar, I have executed your code, and I was unable to replicate the error as well. I attempted several changes, like modifying the code, changing the NuGet version, and using a problematic file that generated the error in my primary project, but the error did not occur. The issue seems to be exclusive to my main project for some reason.
 I managed to find a workaround, which did not produce the error:
var provider = new Telerik.Windows.Documents.FormatProviders.OpenXml.Docx.DocxFormatProvider();
var docxByteArray = provider.Export(_printReportDocument);
RadDocument docxDocument;

using (MemoryStream docxStream = new MemoryStream(docxByteArray))
{
    DocxFormatProvider provider1 = new DocxFormatProvider();
    docxDocument = provider1.Import(docxStream);
}

PdfFormatProvider pdfProvider = new PdfFormatProvider();
using (MemoryStream pdfStream = new MemoryStream())
{
    pdfProvider.Export(docxDocument, pdfStream);
    return pdfStream.ToArray();
}
However, I believe this approach might not be ideal. Do you have any suggestions for an improved solution?
Or Is it possible to convert a RadDocument to a byte array in another way, while still using the resulting byte array as a document source?
Dimitar
Telerik team
commented on 16 Apr 2024, 05:08 AM

Hi Ghiath, 

I do not see any reason for not using this appraoch. However, I am still not sure why this not working in your actual project. We do not have other reports of similar issues. If possible I would recommend opening a new ticket and attaching the project there. This will allow us to properly investigate.

Do not hesitate to contact us if you have other questions.

Tags
Telerik Trainer
Asked by
Ghiath
Top achievements
Rank 1
Answers by
Dess | Tech Support Engineer, Principal
Telerik team
Share this question
or