public IActionResult Index() { List studentList = new List() { new Student() { StudentID = 1, StudentName = "John"} , new Student() { StudentID = 2, StudentName = "Moin"} , new Student() { StudentID = 3, StudentName = "Bill"} , new Student() { StudentID = 4, StudentName = "Ram"} , new Student() { StudentID = 5, StudentName = "Ron"} }; var filename = Path.Combine(_env.WebRootPath, "files", "data.xlsx"); var result = StreamExcelDocument(studentList, filename, "Student"); return View(); } public static FileStreamResult StreamExcelDocument(List listOfReports, string filename, string sheetName) { var tempFilename = filename; var dt = ListToDataTable(listOfReports); dt.TableName = sheetName; CreateExcelDocument(dt, tempFilename); var rawData = System.IO.File.ReadAllBytes(tempFilename); var ms = new MemoryStream(rawData); var fr = new FileStreamResult(ms, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet") { FileDownloadName = filename }; // System.IO.File.Delete(tempFilename); // We don't need this anymore return fr; } /// /// Create an Excel file, and write it to a file. /// /// DataTable containing the data to be written to the Excel. /// Name of file to be written. /// True if successful, false if something went wrong. public static bool CreateExcelDocument(DataTable dt, string excelFilename) { try { using (SpreadsheetDocument spreadsheet = SpreadsheetDocument.Create(excelFilename, SpreadsheetDocumentType.Workbook)) { WriteExcelFile(dt, spreadsheet); } return true; } catch (Exception) { return false; } } private static void WriteExcelFile(DataTable dt, SpreadsheetDocument spreadsheet) { // Create the Excel file contents. This function is used when creating an Excel file either writing // to a file, or writing to a MemoryStream. spreadsheet.AddWorkbookPart(); if (spreadsheet.WorkbookPart == null) return; spreadsheet.WorkbookPart.Workbook = new Workbook(); var definedNamesCol = new DefinedNames(); // The following line of code (which prevents crashes in Excel 2010) spreadsheet.WorkbookPart.Workbook.Append(new BookViews(new WorkbookView())); // If we don't add a "WorkbookStylesPart", OLEDB will refuse to connect to this .xlsx file ! var workbookStylesPart = spreadsheet.WorkbookPart.AddNewPart("rIdStyles"); workbookStylesPart.Stylesheet = GenerateStyleSheet(); workbookStylesPart.Stylesheet.Save(); var sheets = spreadsheet.WorkbookPart.Workbook.AppendChild(new Sheets()); // For each worksheet you want to create var worksheetName = dt.TableName; // Create worksheet part, and add it to the sheets collection in workbook var worksheetPart = spreadsheet.WorkbookPart.AddNewPart(); SheetData sheetData = new SheetData(); //add the first row Row firstRow = new Row(); firstRow.RowIndex = (UInt32)1; //create a cell in A1 (the upper left most cell of the merged cells) Cell dataCell = new Cell(); dataCell.CellReference = "A1"; CellValue cellValue = new CellValue(); cellValue.Text = "Raw Matrials and Price List"; dataCell.Append(cellValue); firstRow.AppendChild(dataCell); sheetData.AppendChild(firstRow); //add the second row Row secondrow = new Row(); secondrow.RowIndex = (UInt32)2; //create a cell in A2 (the upper left most cell of the merged cells) Cell secdataCell = new Cell(); secdataCell.CellReference = "A2"; CellValue seccellValue = new CellValue(); seccellValue.Text = "From: 121"; Cell secdataCell2 = new Cell(); secdataCell2.CellReference = "C2"; CellValue seccellValue2 = new CellValue(); seccellValue2.Text = "To: 250"; secdataCell.Append(seccellValue); secdataCell2.Append(seccellValue2); secondrow.AppendChild(secdataCell); secondrow.AppendChild(secdataCell2); sheetData.AppendChild(secondrow); //based on the table data to add row and cell. DocumentFormat.OpenXml.Spreadsheet.Row headerRow = new DocumentFormat.OpenXml.Spreadsheet.Row(); List columns = new List(); foreach (System.Data.DataColumn column in dt.Columns) { columns.Add(column.ColumnName); DocumentFormat.OpenXml.Spreadsheet.Cell cell = new DocumentFormat.OpenXml.Spreadsheet.Cell(); cell.DataType = DocumentFormat.OpenXml.Spreadsheet.CellValues.String; cell.CellValue = new DocumentFormat.OpenXml.Spreadsheet.CellValue(column.ColumnName); headerRow.AppendChild(cell); } sheetData.AppendChild(headerRow); foreach (System.Data.DataRow dsrow in dt.Rows) { DocumentFormat.OpenXml.Spreadsheet.Row newRow = new DocumentFormat.OpenXml.Spreadsheet.Row(); foreach (String col in columns) { DocumentFormat.OpenXml.Spreadsheet.Cell cell = new DocumentFormat.OpenXml.Spreadsheet.Cell(); cell.DataType = DocumentFormat.OpenXml.Spreadsheet.CellValues.String; cell.CellValue = new DocumentFormat.OpenXml.Spreadsheet.CellValue(dsrow[col].ToString()); // newRow.AppendChild(cell); } sheetData.AppendChild(newRow); } // Add a WorkbookPart to the document. worksheetPart.Worksheet = new Worksheet(sheetData); //create a MergeCells class to hold each MergeCell MergeCells mergeCells = new MergeCells(); //append a MergeCell to the mergeCells for each set of merged cells mergeCells.Append(new MergeCell() { Reference = new StringValue("A1:d1") }); mergeCells.Append(new MergeCell() { Reference = new StringValue("A2:b2") }); mergeCells.Append(new MergeCell() { Reference = new StringValue("c2:d2") }); worksheetPart.Worksheet.InsertAfter(mergeCells, worksheetPart.Worksheet.Elements().First()); var sheet = new Sheet { Id = spreadsheet.WorkbookPart.GetIdOfPart(spreadsheet.WorkbookPart.WorksheetParts.First()), SheetId = 1, Name = worksheetName }; // If you want to define the Column Widths for a Worksheet, you need to do this *before* appending the SheetData // http://social.msdn.microsoft.com/Forums/en-US/oxmlsdk/thread/1d93eca8-2949-4d12-8dd9-15cc24128b10/ sheets.Append(sheet); // Append this worksheet's data to our Workbook, using OpenXmlWriter, to prevent memory problems //WriteDataTableToExcelWorksheet(dt, worksheetPart, definedNamesCol); spreadsheet.WorkbookPart.Workbook.Append(definedNamesCol); spreadsheet.WorkbookPart.Workbook.Save(); } private static Stylesheet GenerateStyleSheet() { // If you want certain Excel cells to have a different Format, color, border, fonts, etc, then you need to define a "CellFormats" records containing // these attributes, then assign that style number to your cell. // // For example, we'll define "Style # 3" with the attributes we'd like for our header row (Row #1) on each worksheet, where the text is a bit bigger, // and is white text on a dark-gray background. // // NB: The NumberFormats from 0 to 163 are hardcoded in Excel (described in the following URL), and we'll define a couple of custom number formats below. // https://msdn.microsoft.com/en-us/library/documentformat.openxml.spreadsheet.numberingformat.aspx // http://lateral8.com/articles/2010/6/11/openxml-sdk-20-formatting-excel-values.aspx // uint iExcelIndex = 164; return new Stylesheet( new NumberingFormats( // new NumberingFormat() // Custom number format # 164: especially for date-times { NumberFormatId = UInt32Value.FromUInt32(iExcelIndex++), FormatCode = StringValue.FromString("dd/MMM/yyyy hh:mm:ss") }, new NumberingFormat() // Custom number format # 165: especially for date times (with a blank time) { NumberFormatId = UInt32Value.FromUInt32(iExcelIndex++), FormatCode = StringValue.FromString("dd/MMM/yyyy") } ), new Fonts( new Font( // Index 0 - The default font. new FontSize() { Val = 10 }, new Color() { Rgb = new HexBinaryValue() { Value = "000000" } }, new FontName() { Val = "Arial" }), new Font( // Index 1 - A 12px bold font, in white. new Bold(), new FontSize() { Val = 12 }, new Color() { Rgb = new HexBinaryValue() { Value = "FFFFFF" } }, new FontName() { Val = "Arial" }), new Font( // Index 2 - An Italic font. new Italic(), new FontSize() { Val = 10 }, new Color() { Rgb = new HexBinaryValue() { Value = "000000" } }, new FontName() { Val = "Times New Roman" }) ), new Fills( new Fill( // Index 0 - The default fill. new PatternFill() { PatternType = PatternValues.None }), new Fill( // Index 1 - The default fill of gray 125 (required) new PatternFill() { PatternType = PatternValues.Gray125 }), new Fill( // Index 2 - The yellow fill. new PatternFill( new ForegroundColor() { Rgb = new HexBinaryValue() { Value = "FFFFFF00" } } ) { PatternType = PatternValues.Solid }), new Fill( // Index 3 - Dark-gray fill. new PatternFill( new ForegroundColor() { Rgb = new HexBinaryValue() { Value = "FF404040" } } ) { PatternType = PatternValues.Solid }) ), new Borders( new Border( // Index 0 - The default border. new LeftBorder(), new RightBorder(), new TopBorder(), new BottomBorder(), new DiagonalBorder()), new Border( // Index 1 - Applies a Left, Right, Top, Bottom border to a cell new LeftBorder(new Color() { Auto = true }) { Style = BorderStyleValues.Thin }, new RightBorder(new Color() { Auto = true }) { Style = BorderStyleValues.Thin }, new TopBorder(new Color() { Auto = true }) { Style = BorderStyleValues.Thin }, new BottomBorder(new Color() { Auto = true }) { Style = BorderStyleValues.Thin }, new DiagonalBorder()) ), new CellFormats( new CellFormat() { FontId = 0, FillId = 0, BorderId = 0 }, // Style # 0 - The default cell style. If a cell does not have a style index applied it will use this style combination instead new CellFormat() { NumberFormatId = 164 }, // Style # 1 - DateTimes new CellFormat() { NumberFormatId = 165 }, // Style # 2 - Dates (with a blank time) new CellFormat(new Alignment() { Horizontal = HorizontalAlignmentValues.Center, Vertical = VerticalAlignmentValues.Center }) { FontId = 1, FillId = 3, BorderId = 0, ApplyFont = true, ApplyAlignment = true }, // Style # 3 - Header row new CellFormat() { NumberFormatId = 3 }, // Style # 4 - Number format: #,##0 new CellFormat() { NumberFormatId = 4 }, // Style # 5 - Number format: #,##0.00 new CellFormat() { FontId = 1, FillId = 0, BorderId = 0, ApplyFont = true }, // Style # 6 - Bold new CellFormat() { FontId = 2, FillId = 0, BorderId = 0, ApplyFont = true }, // Style # 7 - Italic new CellFormat() { FontId = 2, FillId = 0, BorderId = 0, ApplyFont = true }, // Style # 8 - Times Roman new CellFormat() { FontId = 0, FillId = 2, BorderId = 0, ApplyFill = true }, // Style # 9 - Yellow Fill new CellFormat( // Style # 10 - Alignment new Alignment() { Horizontal = HorizontalAlignmentValues.Center, Vertical = VerticalAlignmentValues.Center } ) { FontId = 0, FillId = 0, BorderId = 0, ApplyAlignment = true }, new CellFormat() { FontId = 0, FillId = 0, BorderId = 1, ApplyBorder = true } // Style # 11 - Border ) ); // return } public static DataTable ListToDataTable(List list) { var dt = new DataTable(); foreach (var info in typeof(T).GetProperties()) { dt.Columns.Add(new DataColumn(info.Name, GetNullableType(info.PropertyType))); } foreach (var t in list) { var row = dt.NewRow(); foreach (var info in typeof(T).GetProperties()) { if (!IsNullableType(info.PropertyType)) row[info.Name] = info.GetValue(t, null); else row[info.Name] = (info.GetValue(t, null) ?? DBNull.Value); } dt.Rows.Add(row); } return dt; } private static Type GetNullableType(Type t) { var returnType = t; if (t.IsGenericType && t.GetGenericTypeDefinition() == typeof(Nullable<>)) { returnType = Nullable.GetUnderlyingType(t); } return returnType; } private static bool IsNullableType(Type type) { return (type == typeof(string) || type.IsArray || (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>))); }