I have a problem for which I have been unable to find a solution. I am utilizing the following technologies...
- C# .NET Durable Function - Timer Trigger
- Azure Blob Storage - to back up workbook
- SendGrid - to email workbook
- ClosedXML (including Report)
I have been unable to generate an excel file, with the 'XLSX' extension, that will open without the following error "Excel cannot open file 'test.xlsx' because the file format or extension is not valid. Verify that the file has not been corrupted and that the file extension matches the format of the file."
Interestingly, I have been able to generate excel files with the 'XLS' extension, that open successfully when downloaded from container storage and email. Unfortunately, that will not suffice as these excel files will be sent to customers.
I am using the following method to update variables within a template stored in Azure. I believe this works, as again, I can generate a 'XLS' file with the referenced cell contents...
{{Value1}}
public async Task<MemoryStream> UpdateVariables(MemoryStream streamTemplate, List<DealDocumentFlattenedForCsv> data)
{
var template = new XLTemplate(streamTemplate);
template.AddVariable("Value1", data[0].Value1);
template.AddVariable("Value2", data[0].Value2);
template.AddVariable("Value3", data[0].Value3);
template.AddVariable("Value4", data[0].Value4);
template.Generate();
MemoryStream xlsStream = new();
template.SaveAs(xlsStream);
await xlsStream.FlushAsync();
xlsStream.Position = 0;
return xlsStream;
}
And successfully populated a table in the Excel template as follows
public async Task<MemoryStream> GetMemoryStreamForExcelDocument(List<DealDocumentFlattenedForCsv> data, MemoryStream stream, string sheetName, string tableName)
{
using var workBook = new XLWorkbook(stream);
var table = workBook.Table(tableName);
table.ReplaceData(data, propagateExtraColumns: true);
workBook.SaveAs(stream);
await stream.FlushAsync();
stream.Position = 0;
return stream;
}
I have tried setting content on the email attachment using the following values
- application-vnd.ms-excel (prior to 2007 - 'XLS')
- application/vnd.openxmlformats-officedocument.spreadsheetml.sheet (2007+ 'XLSX')
And I have tried emailMessage.Attachments / email.AddAttachment, as follows:
private static void BuildEmailMessage(SendGridMessage emailMessage, byte[] csvByteArray)
{
emailMessage.AddTo(new EmailAddress("email@email.com"));
emailMessage.AddContent("text/html", "This is the attachment <b>email</b>");
emailMessage.Attachments = new List<Attachment>
{
new Attachment()
{
Content = Convert.ToBase64String(csvByteArray),
Filename = "test.xlsx",
Type = "application/vnd.ms-excel",
//Type = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
Disposition = "attachment"
}
};
//emailMessage.AddAttachment("test.xlsx", Convert.ToBase64String(csvByteArray));
emailMessage.From = new EmailAddress("email@email.com");
emailMessage.SetSubject("test msg");
}
The following are the BlobStorage read and write methods
public MemoryStream ReadFileFromBlobStorage(string fileName, string containerName)
{
var blobContainerClient = _blobServiceClient.GetBlobContainerClient(containerName);
var blob = blobContainerClient.GetBlobClient(fileName);
var memoryStream = new MemoryStream();
blob.DownloadTo(memoryStream);
return memoryStream;
}
public async Task SaveFileToBlobStorageAsync(string containerName, string fileName, Stream stream)
{
stream.Position = 0;
var containerClient = _blobServiceClient.GetBlobContainerClient(containerName);
var blobClient = containerClient.GetBlobClient(fileName);
var blobHttpHeaders = new BlobHttpHeaders()
{
ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
};
await blobClient.UploadAsync(stream, blobHttpHeaders, conditions: null);
stream.Close();
}
When I download the excel document, with an 'XLSX' extension, I get the following...
Any help would be appreciated. Thank you in advance!