RagnaRock
RagnaRock

Reputation: 2640

How to upload a blob (Excel file) to an Azure Storage account

I'm trying to create an Excel report using NPOI.XSSF library. It works fine when I save into a disk file using a FileStream; yet, if I use a MemoryStream and try to upload it to an Azure storage account, it uploads a file with the correct size but when I try to open it with excel it is corrupted.

This is my code:

public static void ExportToStorageAccount(string storageConnection, IEnumerable<ReportEntry> reportEntries)
{
    var storageAccount = CloudStorageAccount.Parse(storageConnection);
    var myClient = storageAccount.CreateCloudBlobClient();
    var container = myClient.GetContainerReference("reportsContainer");

    string fileName = GetFileName();

    using (var ms = new MemoryStream())
    {
        IWorkbook workbook = CreateWorkbook(reportEntries);
        workbook.Write(ms);

        var blockBlob = container.GetBlockBlobReference(fileName);
        var buffer = ms.GetBuffer();
        blockBlob.UploadFromStream(new MemoryStream(buffer, false));
    }
}

What am I doing wrong that makes the file to be corrupted?

Upvotes: 2

Views: 3488

Answers (2)

tushar TAZz
tushar TAZz

Reputation: 64

To upload the file to Azure blob, you can use the default "Azure.Storage.Blobs" library provided by microsoft. then create a refrence to the container and provide the path to the file in the blob.upload(path).

Upvotes: 0

Brian Rogers
Brian Rogers

Reputation: 129787

I think the problem is that you using GetBuffer on the first MemoryStream to create the second one. From the documentation:

Remarks

Note that the buffer contains allocated bytes which might be unused. For example, if the string "test" is written into the MemoryStream object, the length of the buffer returned from GetBuffer is 256, not 4, with 252 bytes unused. To obtain only the data in the buffer, use the ToArray method; however, ToArray creates a copy of the data in memory.

What is likely happening is that you are getting unwanted extra zero bytes at the end of the stream from the buffer. Excel doesn't know what to do with the extra bytes, so it declares that the workbook is corrupted. Since XLSX is a compressed format, it's entirely possible that the file size would be the same with the extra zeros as without them, so you might not be able to tell just by looking at that.

In short, you should use ToArray instead to prevent the corruption.

To fix, change this line:

var buffer = ms.GetBuffer();

To this:

var buffer = ms.ToArray();

Upvotes: 1

Related Questions