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

ExportPDF Custom Command Descriptor Issue

6 Answers 122 Views
PDFViewer
This is a migrated thread and some comments may be shown as answers.
Brandon
Top achievements
Rank 1
Brandon asked on 24 Jan 2017, 08:30 PM

Hello,

I have written a Custom Command Descriptor based on the Telerik demos and documentation that exports the currently loaded document to a local file. Everything appears to be working 100% correct with no errors. However, when I open the file all the pages are blank. The page count is correct, so it appears to be reading the PDFViewer document correctly into the stream, just not writing all of the bytes properly. Here is my code behind for the page that contains the Document Viewer control.

 

using System;
using System.IO;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using Telerik.Windows.Documents.Fixed.FormatProviders;
using Telerik.Windows.Documents.Fixed.FormatProviders.Pdf;
using Telerik.Windows.Documents.Fixed.Model;
using WeldTrackingWPF.ViewModel;
using Telerik.Windows.Controls;
using Telerik.Windows.Documents.Commands.Descriptors;
using Telerik.Windows.Documents.Commands;
 
namespace WeldTrackingWPF.View
{
    /// <summary>
    /// Interaction logic for ViewQualificationDoc.xaml
    /// </summary>
    public partial class ViewDoc : Page
    {
        public ViewDoc(byte[] fileBytes)
        {
 
            InitializeComponent();
 
            /// <summary>
            ///  Read bytes into memory stream
            ///  Pass stream in RadPdfViewer for viewing
            /// </summary>
 
 
            this.pdfViewer.CommandDescriptors = new CustomCommandDescriptors(this.pdfViewer);
 
            Stream stream = new MemoryStream(fileBytes);
 
            FormatProviderSettings settings = new FormatProviderSettings(ReadingMode.AllAtOnce);
 
            PdfFormatProvider provider = new PdfFormatProvider(stream, settings);
 
            RadFixedDocument doc = provider.Import();
 
            this.pdfViewer.Document = doc;
 
            IconSources.ChangeIconsSet(IconsSet.Modern);
 
 
 
        }
 
        private void Page_Initialized(object sender, EventArgs e)
        {
            var vm = new ViewDocViewModel();
            DataContext = vm;
        }
 
        private void PdfViewer_DocumentLoaded(object sender, EventArgs args)
        {
        }
 
        private void Page_Unloaded(object sender, RoutedEventArgs e)
        {             
        }
 
        private void tbCurrentPage_KeyDown(object sender, KeyEventArgs e)
        {
            TextBox textBox = sender as TextBox;
            if (textBox != null)
            {
                if (e.Key == System.Windows.Input.Key.Enter)
                {
                    textBox.GetBindingExpression(TextBox.TextProperty).UpdateSource();
                }
            }
        }
    }
 
    public class SaveCommand : FixedDocumentViewerCommandBase
    {
        public SaveCommand(FixedDocumentViewerBase fixedDocumentViewerBase)
            : base(fixedDocumentViewerBase)
        {
        }
 
        public override void Execute(object parameter)
        {
            Microsoft.Win32.SaveFileDialog dialog = new Microsoft.Win32.SaveFileDialog();
            dialog.Filter = "PDF files (*.pdf)|*.pdf";
 
            bool? result = dialog.ShowDialog();
 
            if (result.HasValue && result.Value)
            {
 
                using (Stream stream = File.OpenWrite(dialog.FileName))
                {
 
                    PdfFormatProvider provider = new PdfFormatProvider();
                    provider.Export(this.Viewer.Document, stream);
 
                }
            }
        }
    }
 
    public class CustomCommandDescriptors : DefaultCommandDescriptors
    {
        private readonly CommandDescriptor saveCommandDescriptor;
 
        public CommandDescriptor SaveCommandDescriptor
        {
            get
            {
                return this.saveCommandDescriptor;
            }
        }
 
        public CustomCommandDescriptors(FixedDocumentViewerBase fixedDocumentViewer) : base(fixedDocumentViewer)
        {
            this.saveCommandDescriptor = new CommandDescriptor(new SaveCommand(fixedDocumentViewer));
        }
    }
 
}

Any insight as to why these documents are being exported sans page content would be appreciated.

 

Thanks!

6 Answers, 1 is accepted

Sort by
0
Tanya
Telerik team
answered on 26 Jan 2017, 08:54 AM
Hi Brandon,

I checked the code you shared and noticed that the wrong provider is used to export the document of RadPdfViewer.

The PdfFormatProvider class is shared between RadPdfViewer and RadPdfProcessing and, depending on the constructor you are using, a provider instance for the different control is created. To be more precise, to create a provider to work RadPdfViewer, you should use the constructor that takes two parameters, as shown in Example 5 of the Showing a File article. The default constructor will create a PdfFormatProvider instance which is working with the model of RadPdfProcessing. 

Here is how I modified a part of the code you shared to use the PdfFormatProvider for PdfViewer:
public override void Execute(object parameter)
{
    Microsoft.Win32.SaveFileDialog dialog = new Microsoft.Win32.SaveFileDialog();
    dialog.Filter = "PDF files (*.pdf)|*.pdf";
 
    bool? result = dialog.ShowDialog();
 
    if (result.HasValue && result.Value)
    {
 
        using (Stream stream = File.OpenWrite(dialog.FileName))
        {
 
            PdfFormatProvider provider = new PdfFormatProvider(stream, FormatProviderSettings.ReadOnDemand);
            provider.Export(this.Viewer.Document, stream);
 
        }
    }
}

Hope this helps.

Regards,
Tanya
Telerik by Progress
Want to extend the target reach of your WPF applications, leveraging iOS, Android, and UWP? Try UI for Xamarin, a suite of polished and feature-rich components for the Xamarin framework, which you to write beautiful native mobile apps using a single shared C# codebase.
0
Brandon
Top achievements
Rank 1
answered on 26 Jan 2017, 02:27 PM

This results in the following error:

The stream type is not supported.

I assume that when using this Overload, the PdfFormatProvider is attempting to read the stream, which is not allowed on a FileStream created using File.OpenWrite. 

0
Brandon
Top achievements
Rank 1
answered on 26 Jan 2017, 03:23 PM

I believe that I overcame the above error by using dialog.OpenFile(), however now I am getting a NotSupportExecption stating the following:

An unhandled exception of type 'System.NotSupportedException' occurred in Telerik.Windows.Documents.Fixed.dll

Additional information: This method is only supported when initializing PdfFormatProvider through the PdfFormatProvider() constructor.

using (Stream stream = dialog.OpenFile())
{
 
    PdfFormatProvider provider = new PdfFormatProvider(stream, FormatProviderSettings.ReadOnDemand);
    provider.Export(this.Viewer.Document, stream);
 
}

 

 

0
Tanya
Telerik team
answered on 26 Jan 2017, 05:11 PM
Hi Brandon,

I have misunderstood your initial inquiry. Please, accept my apologies for misleading you.

RadPdfViewer doesn't support exporting the loaded document out-of-the-box. We have already logged a request to implement this functionality and you can submit your vote as well as track the progress of the task using the related public item.

At this point, I can suggest you check the Custom Save Command example in our SDK repository. The sample shows how you can customize the Open command in order to preserve the document stream and use it later in the Save command to export.

I hope this is helpful.

Regards,
Tanya
Telerik by Progress
Want to extend the target reach of your WPF applications, leveraging iOS, Android, and UWP? Try UI for Xamarin, a suite of polished and feature-rich components for the Xamarin framework, which you to write beautiful native mobile apps using a single shared C# codebase.
0
Brandon
Top achievements
Rank 1
answered on 26 Jan 2017, 06:06 PM

Currently, we are not loading documents through the OpenCommand on the viewer, they are loaded from the code behind after the document is retrieved from the database. For now, we have a work around in place where the byte[] array is stored in the page object, obviously not ideal, and used later to build the save stream.

This seems like a major oversight and it's very disappointing that this functionality is not offered out of the box.

0
Tanya
Telerik team
answered on 31 Jan 2017, 02:48 PM
Hello Brandon,

RadPdfViewer currently doesn't expose a way to save the document stream to a file. Therefore, the stream should be preserved internally and the approach you are using is pretty similar to the one demonstrated in the example - the stream is preserved in a variable when loading a document so it can be saved later.

If you would like, you can increase the priority of the task by voting for its implementation through the feedback item I linked in my previous reply.

Regards,
Tanya
Telerik by Progress
Want to extend the target reach of your WPF applications, leveraging iOS, Android, and UWP? Try UI for Xamarin, a suite of polished and feature-rich components for the Xamarin framework, which you to write beautiful native mobile apps using a single shared C# codebase.
Tags
PDFViewer
Asked by
Brandon
Top achievements
Rank 1
Answers by
Tanya
Telerik team
Brandon
Top achievements
Rank 1
Share this question
or