1

When using the DocX librairy, i am generating the docx document on server then download it.

For that, i need to convert my document in an array of bytes.

To do that, i was previousloy saving the document as a physical file like this :

// Save all changes to this document.
document.SaveAs(GENERATED_DOCX_LOCATION);

return System.IO.File.ReadAllBytes(GENERATED_DOCX_LOCATION);

but i would rather not do that. Is it possible to serialize this object to download it without saving it physically ?

I already tried that :

private byte[] ObjectToByteArray(object obj)
{
    if (obj == null)
        return null;
    BinaryFormatter bf = new BinaryFormatter();
    using (MemoryStream ms = new MemoryStream())
    {
        bf.Serialize(ms, obj);
        return ms.ToArray();
    }
}

With :

return this.ObjectToByteArray(document);

But obviously, DocX doesn't implement ISerializable.

EDIT : the code below doesn't work either

byte[] byteArray = null;
using (var stream = new MemoryStream())
{
    document.SaveAs(stream);
    byteArray = stream.ToArray();
}
return byteArray;
G.Dealmeida
  • 325
  • 3
  • 14
  • is this a web server and internal to your organisation? – Simon Price Oct 02 '17 at 11:27
  • yes it's a private server, managed by a dedicated team – G.Dealmeida Oct 02 '17 at 11:35
  • 1
    Take a look at this then and this should give you what you need (unless youre using MVC, which will be a different answer but I can code one up for you later if you need) but... this should work https://stackoverflow.com/questions/18477398/asp-net-file-download-from-server – Simon Price Oct 02 '17 at 11:37
  • Actually, it's not an HTTP server. Sorry i should have been more explicit. It's a Windows Service (a WCF application) which uses a binary pipe to transfer Data. So i dont think your link can apply here (but i keep it in favorite because we are planning to migrate in SOAP in a couple of month) – G.Dealmeida Oct 02 '17 at 11:49
  • ok, let me try a few things my side and i'll come back to you – Simon Price Oct 02 '17 at 11:55
  • next question I have is are you able to get the file into the byte array? – Simon Price Oct 02 '17 at 11:57
  • Yes, the first sample of code i posted do exactly that. GENERATED_DOCX_LOCATION is a private readonly string containing the location to write the document – G.Dealmeida Oct 02 '17 at 11:59

2 Answers2

1

Try this, replace my c:\temp... path with your document location and this will get and write the file for you from the byte array

void Main()
{
    byte[] bytes = System.IO.File.ReadAllBytes(@"C:\temp\test.csv");

    using (var bw = new BinaryWriter(File.Open(@"C:\temp\test2.csv", FileMode.OpenOrCreate)))
    {
        bw.Write(bytes);
        bw.Flush();
    }

}
Simon Price
  • 3,011
  • 3
  • 34
  • 98
  • Thank you for your consideration but i dont want to save the file test2.csv on the disk. i found a way to get out of this by changing the DocX librairy, see my post for more details. Thank you – G.Dealmeida Oct 03 '17 at 11:06
  • this was just an example of how you could do what you need to do, you dont have to save a csv file – Simon Price Oct 03 '17 at 11:17
  • It's not what i need to do because you start with a byte[] from a physical file, and i have a DocX to start with, in memory, not on the disk. – G.Dealmeida Oct 03 '17 at 12:00
0

There was no way to do it via the original DocX library.

It's a shame as this library uses a MemoryStream to manupulate the datas.

To solve my problem i simply added a new public readonly property to expose the private MemoryStream variable, then i used this simple code :

Code added in the DocX project :

public MemoryStream DocumentMemoryStream { get { return this.memoryStream; }  } 

Code in my main function :

return document.DocumentMemoryStream.ToArray();
G.Dealmeida
  • 325
  • 3
  • 14