Home » excel » c# – file is corrupt and cannot be opened when saving an excel document using openXML 2.0

c# – file is corrupt and cannot be opened when saving an excel document using openXML 2.0

Posted by: admin May 14, 2020 Leave a comment

Questions:

I am trying to save rows pass through to this method from another spreadsheet and save this spreadsheet as an attachment to an email. The email sends fine, but the attachment does not open with the error “file is corrupt and cannot be opened”. I tried saving the file to a filstream on the c: but got the same error. What is wrong with this code?

 public static void CreateErrorMailWithExcelAttachment(List<Row> rows)
        {
            if (rows.Count > 0)
            {
                using (MemoryStream stream = new MemoryStream())
                {
                    //Create a spreadsheet document by supplying the file name.
                    using (SpreadsheetDocument spreadsheetDocument = SpreadsheetDocument.Create(stream, SpreadsheetDocumentType.Workbook))
                    {

                        // Add a WorkbookPart to the document.
                        spreadsheetDocument.AddWorkbookPart();
                        spreadsheetDocument.WorkbookPart.Workbook = new Workbook();

                        spreadsheetDocument.WorkbookPart.AddNewPart<WorksheetPart>();
                        spreadsheetDocument.WorkbookPart.WorksheetParts.First().Worksheet = new Worksheet();

                        // create sheet data
                        spreadsheetDocument.WorkbookPart.WorksheetParts.First().Worksheet.AppendChild(new SheetData());

                        // Add Rows to the Sheet.
                        foreach (Row row in rows)
                        {
                            spreadsheetDocument.WorkbookPart.WorksheetParts.First().Worksheet.First().AppendChild(new Row(row.OuterXml));
                        }

                        spreadsheetDocument.WorkbookPart.Workbook.Save();
                    }

                    Dictionary<string, byte[]> attachments = new Dictionary<string, byte[]>();
                    attachments.Add("Book1.xlsx", stream.ToArray());

                    SendEmail
                        (
                            acsis.Common.AppContext.Configuration.GetValue(Constants.ApplicationName, "SMTPServer"),
                            acsis.Common.AppContext.Configuration.GetValue(Constants.ApplicationName, "SMTPUser"),
                            acsis.Common.AppContext.Configuration.GetValue(Constants.ApplicationName, "SMTPPass"),
                            "[email protected]",
                            acsis.Common.AppContext.Configuration.GetValue(Constants.ApplicationName, "InstitutionalDatabaseAdminEmail"),
                            "Failed rows from bulk investor spreadsheet upload",
                            "Test",
                            false,
                            attachments
                        );
                }
            }
        }
How to&Answers:

Inside your WorkbookPart you need to add a element specifying each of the sheets that are in the workbook. It’s tricky to write up exactly the change you need to your code because you’ve got a lot of unassigned creators, but basically you need:

workbook1.AddNamespaceDeclaration("r","http://schemas.openxmlformats.org/officeDocument/2006/relationships");
Sheets sheets1 = new Sheets();
Sheet sheet1 = new Sheet(){ Name = "Sheet1", SheetId = (UInt32Value)1U, Id = "R71b609d3bfb541ee" };
sheets1.Append(sheet1);
workbook1.Append(sheets1);
workbookPart1.Workbook = workbook1;

You’ll have to get the relId identifier and put that in there, but then you should be good to go.

Hope that helps!