1

I have a byte array of xps file content stored in a sql server, I'm trying to retrieve it back and display it into a DocumentViewer control.

cmd.CommandText = "select text from [table] where docName = '" + selectedText + "'";
using (SqlDataReader read = cmd.ExecuteReader())
{
    while (read.Read())
    {
        byte[] retrieve = ((byte[])read["text"]); //text is column name for the byte array
        var package = System.IO.Packaging.Package.Open(new MemoryStream(retrieve));
        var xpsDocument = new XpsDocument(package, System.IO.Packaging.CompressionOption.Maximum);
        pptViewer.Visibility = System.Windows.Visibility.Visible;
        pptViewer.Document = xpsDocument.GetFixedDocumentSequence();
    }
}

The issue is this line new XpsDocument(package, System.IO.Packaging.CompressionOption.Maximum) requires an extra parameter - the Uri of the file. I don't have it as it isn't stored locally - I convert it to a byte array and then store it, so the original xps file is gone.

Is possible to convert the byte array into an xps document without any uri? If not, how else can I display the document inside my wpf app (from a byte array, of coruse)?

cosmo
  • 751
  • 2
  • 14
  • 42
  • File.WriteAllBytes(string path, byte[] bytes) with correct extension will do? – Sin Aug 02 '17 at 08:12
  • https://stackoverflow.com/questions/381508/can-a-byte-array-be-written-to-a-file-in-c – Sin Aug 02 '17 at 08:15

1 Answers1

3

You can use a method for extracting a FixedDocumentSequence from your byte array, something like:

private FixedDocumentSequence GetFixedDocumentSequence(byte[] xpsBytes)
{
    Uri packageUri;
    XpsDocument xpsDocument = null;

    using (MemoryStream xpsStream = new MemoryStream(xpsBytes))
    {
        using (Package package = Package.Open(xpsStream))
        {
            packageUri = new Uri("memorystream://myXps.xps");

            try
            {
                PackageStore.AddPackage(packageUri, package);
                xpsDocument = new XpsDocument(package, CompressionOption.Maximum, packageUri.AbsoluteUri);

                return xpsDocument.GetFixedDocumentSequence();
            }
            finally
            {
                if (xpsDocument != null)
                {
                    xpsDocument.Close();
                }
                PackageStore.RemovePackage(packageUri);
            }
        }
    }
}

And then call it for setting your DocumentViewer in your code:

pptViewer.Document = GetFixedDocumentSequence(retrieve);
Il Vic
  • 5,576
  • 4
  • 26
  • 37
  • why does the try finally wrap add package instead of that being before the `try` ? you don't want to try to remove a package in the finally that was never added, right? – Maslow Oct 17 '18 at 18:57
  • Yes you are right @Maslow. Indeed you can use also the `GetPackage` method to check if the package was added. – Il Vic Oct 21 '18 at 07:21