Streaming XOD from a memory buffer to HTML5 Web Viewer

1,892 views
Skip to first unread message

Support

unread,
May 3, 2016, 3:02:18 PM5/3/16
to pdfnet-w...@googlegroups.com

Q:

I’ve recently downloaded the WebViewer and PDFNet.sdk trials and got most what I need working.  Now I’m trying to figure out how to send an .xod file that is loaded in memory to the WebViewer using the html5 option. I’m working in a MVC 4 C# project and below is the code snippet that I’m using that is failing.

 

        public ActionResult PdfCompleted(byte[] pdf)

        {

            PDFNet.Initialize();

            var streamedPdf = new MemoryStream(pdf);

            var doc = new PDFDoc(streamedPdf);

            var filter = pdftron.PDF.Convert.ToXod(doc); //, @"C:\Temp\FromMemPdf.xod");

            var xodBytes = new byte[filter.Size()];

            var streamedXod = new MemoryStream(xodBytes);

            return new FileStreamResult(streamedXod, "application/xod");

        }

 

 

The error message I get is as follows.

 

Uncaught Error: Invalid XOD file: Zip end header data is wrong size!

 

If I use the same code to write to a file on the file system and then upload that, all is fine. So there must be something wrong with how I’m using the API to send it to the WebViewer. Please help or provide code sample if what I’m trying to do is possible.
 
----------
A:
 

You are receiving this error in the WebViewer because most likely, the XOD data is not streamed correctly. In order to do so, the Filter returned by Convert.ToXod must be consumed until no more bytes can be read. The call to Filter.Size() is not guaranteed to be the actual size of a fully converted document. The code snippet below demonstrates how to convert and stream PDF to XOD and feed the data directly to WebViewer:


    String file = Request["file"];
    if (String.IsNullOrEmpty(file)) {
        // if no parameter passed, just use the default file
        file = "newsletter.pdf";
    }

    file = String.Format("{0}{1}{2}", Server.MapPath("."), "/../../TestFiles/", file);
    
    // Clear the header and contents in order to serve xod file instead of html.
    Response.Clear();
    Response.ContentType = "application/vnd.ms-xpsdocument";
    
    try {
        PDFNet.Initialize();

        // thumbnails are not used for streaming, so generating and transfering them is a waste of resources
        pdftron.PDF.Convert.XODOutputOptions options = new pdftron.PDF.Convert.XODOutputOptions();
        options.SetOutputThumbnails(false);

        // point to the source file on disk that is to be converted, and begin the conversion
        Debug.WriteLine("Prepare conversion...");
        pdftron.Filters.Filter filter = pdftron.PDF.Convert.ToXod(file, options);

        // now ready to stream the document as it is converted
        pdftron.Filters.FilterReader fReader = new pdftron.Filters.FilterReader(filter);

        byte[] buffer = new byte[64 * 1024]; //64 KB chunks

        int bytesRead = 0;
        bytesRead = fReader.Read(buffer);
        Response.BufferOutput = false;

        int totalBytesSent = 0;

        Debug.WriteLine("Commence streaming...");
        while (bytesRead > 0) {
            // write bytes to the response stream
             Response.OutputStream.Write(buffer, 0, bytesRead); // last write will likely be less than buffer size

            // write to output how many bytes have been sent
            totalBytesSent += bytesRead;
            Debug.WriteLine("Server sent total " + totalBytesSent + " bytes.");
            // read next bytes
            bytesRead = fReader.Read(buffer);
        }

        Debug.WriteLine("Done.");
        // ensure all bytes have been sent and stop execution

        PDFNet.Terminate();
        HttpContext.Current.ApplicationInstance.CompleteRequest();
    }
    catch (Exception ex) {
        Debug.WriteLine("Error: " + ex.Message);
        Debug.WriteLine("at " + ex.StackTrace);
    }



This sample code can be obtained by downloading any of the .NET packages here: http://www.pdftron.com/pdfnet/downloads.html. Please see the "WebViewerStreaming" sample.
I a m not sure if you are already doing this, but you also need to use StreamingPartRetriever instead HttpPartRetriever on the HTML5 viewer side.

Anuj Agrawal

unread,
Sep 14, 2016, 5:21:48 PM9/14/16
to PDFTron WebViewer
I am also trying to achieve something similar. We're using Amazon S3 to read a file and convert it to XOD and save it as a separate copy on Amazon S3 server. After converting a PDFDoc to XOD, how do I get a stream to be uploaded to S3 server?

PDFDoc sourceDocument = new PDFDoc(sourceResponseStream);
pdftron.PDF.Convert.XODOutputOptions convertOptions = new pdftron.PDF.Convert.XODOutputOptions();
pdftron.Filters.Filter filter = pdftron.PDF.Convert.ToXod(sourceDocument, convertOptions);
PutObjectRequest destinationRequest = new PutObjectRequest
{BucketName = "BucketName",Key = "XOD1"};
destinationRequest.ContentType = "application/xod";
destinationRequest.InputStream = ???

Matt Parizeau

unread,
Sep 15, 2016, 2:55:50 PM9/15/16
to PDFTron WebViewer
You should be able to implement your own stream object that uses a FilterReader to get the data http://stackoverflow.com/questions/8119631/is-there-a-c-sharp-equivalent-way-for-java-inputstream-and-outputstream

Matt Parizeau
Software Developer
PDFTron Systems Inc.
Reply all
Reply to author
Forward
0 new messages