简体   繁体   中英

How to Obtain a Byte Array or Stream from a PresentationDocument object

I have Open Office XML code that slices and dices PowerPoint files.

Due to the nature of the Open XML SDK, much of this code reads to and writes from files on the file system. The goal is to eliminate these temporary files completely, and replace them with byte arrays and/or in-memory streams.

Some of this code merges together PowerPoints from different slide sources. An example of this code follows. Imagine a database containing PowerPoint presentations. PmlDocument is a class in Open XML Power Tools:

foreach (var item in database)
{
    var openXmlDocument = new OpenXmlPowerToolsDocument(item.data);
    var document = new PmlDocument(openXmlDocument);
    sources.Add(new SlideSource(document, false));
}

PmlDocument newDocument = PresentationBuilder.BuildPresentation(sources);
byte[] data = newDocument.DocumentByteArray;

Where byte[] data represents a new PowerPoint PPTX, which I can then save back to the database.

This code works perfectly fine, because I'm already working with byte arrays in this example. The problem occurs when I have to deal with PresentationDocument objects. A great deal of processing already occurs in our program with these objects, and the current way to obtain the byte array from such objects is to do this:

presentationDocument.SaveAs(fileName);
byte[] array = File.ReadAllBytes(fileName);

Which is not what I want.

Unfortunately, there doesn't appear to be a better way to extract the bytes from a PresentationDocument . Does anyone know how to do this in memory, perhaps with a MemoryStream object?

Note: I've read OfficeTalk: Working with In-Memory Open XML Documents , but it appears to assume that you already have a byte array in the proper document format.

Looking at the source here , PresentationDocument inherits from OpenXmlPackage Which implements the SaveAs method, and when followed eventually calls:

/// <summary>
/// Creates a clone of this OpenXml package, opened on the given stream.
/// The cloned OpenXml package is opened with the same settings, i.e.,
/// FileOpenAccess and OpenSettings, as this OpenXml package.
/// </summary>
/// <param name="stream">The IO stream on which to open the OpenXml package.</param>
/// <returns>The cloned OpenXml package.</returns>
public OpenXmlPackage Clone(Stream stream)`

In the end this just copies the OpenXmlPart to the stream

using (OpenXmlPackage clone = CreateClone(stream))
{
     foreach (var part in Parts)
     {
         clone.AddPart(part.OpenXmlPart, part.RelationshipId);
     }
}

When you know it's there, you can eventually find it in the documentation !

All-in-all, this gives you the ability to save directly to the bytes without going to file first.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM