{"id":28073,"date":"2019-11-06T00:00:00","date_gmt":"2019-11-05T23:00:00","guid":{"rendered":"https:\/\/blexin.com\/creare-report-con-open-xml-sdk\/"},"modified":"2021-05-20T18:49:35","modified_gmt":"2021-05-20T16:49:35","slug":"creating-reports-with-open-xml-sdk","status":"publish","type":"post","link":"https:\/\/blexin.com\/en\/blog-en\/creating-reports-with-open-xml-sdk\/","title":{"rendered":"Creating reports with Open XML SDK"},"content":{"rendered":"\n<figure class=\"wp-block-image size-large\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"608\" data-attachment-id=\"28059\" data-permalink=\"https:\/\/blexin.com\/en\/blog-en\/creating-reports-with-open-xml-sdk\/attachment\/ab37f718-0d69-4960-9b90-8eb7ff437b53-2\/\" data-orig-file=\"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/ab37f718-0d69-4960-9b90-8eb7ff437b53.png?fit=1024%2C608&amp;ssl=1\" data-orig-size=\"1024,608\" data-comments-opened=\"0\" data-image-meta=\"{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}\" data-image-title=\"ab37f718-0d69-4960-9b90-8eb7ff437b53\" data-image-description=\"\" data-image-caption=\"\" data-large-file=\"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/ab37f718-0d69-4960-9b90-8eb7ff437b53.png?fit=1024%2C608&amp;ssl=1\" src=\"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/ab37f718-0d69-4960-9b90-8eb7ff437b53.png?resize=1024%2C608&#038;ssl=1\" alt=\"\" class=\"wp-image-28059\" srcset=\"https:\/\/blexin.com\/wp-content\/uploads\/2020\/12\/ab37f718-0d69-4960-9b90-8eb7ff437b53.png 1024w, https:\/\/blexin.com\/wp-content\/uploads\/2020\/12\/ab37f718-0d69-4960-9b90-8eb7ff437b53-980x582.png 980w, https:\/\/blexin.com\/wp-content\/uploads\/2020\/12\/ab37f718-0d69-4960-9b90-8eb7ff437b53-480x285.png 480w\" sizes=\"auto, (min-width: 0px) and (max-width: 480px) 480px, (min-width: 481px) and (max-width: 980px) 980px, (min-width: 981px) 1024px, 100vw\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">As part of our development activities, both for customers and internal projects, we have often faced the need to create reports containing data of different types. The format we usually use &#8211; which is also the most requested one- for these reports is definitely Office Open XML: it is read and processed by the spreadsheet software of the main office suites and ensures the quality and lightness of the document.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">In the&nbsp;<em>.NET<\/em>&nbsp;world, there are several third-party plugins allow us to create Office Open XML files. After tested some of them, we decided to opt for Open XML SDK, which seemed to us the best choice in terms of functionality, performance and configurability and, last but not least, because it natively allows the use of the Office Open XML format.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Some notes on Office Open XML<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">The Office Open XML format is a standard for text documents, presentations, and spreadsheets, and it can be implemented by multiple applications on different platforms. The main purpose of the Open XML format is to decouple the information from the software that creates it, without loss of data. An Open XML file is structured in a text file created with an XML markup, stored in a ZIP archive and consists of several parts, depending on the type of document.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">In the case of spreadsheets, the Open XML document can contain:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Parts of the document (mandatory)<\/li><li>One or more worksheets<\/li><li>Charts<\/li><li>Tables<\/li><li>Custom XML<\/li><\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">Open XML SDK<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Open XML SDK is an open-source library, released under the Apache 2.0 license by Microsoft for developers, which provides namespaces and members to support the most common office software, including &#8211; of course &#8211; Microsoft Office.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Official documentation is available at this link:&nbsp;<a href=\"https:\/\/docs.microsoft.com\/en-us\/office\/open-xml\/open-xml-sdk\" target=\"_blank\" rel=\"noreferrer noopener\">https:\/\/docs.microsoft.com\/en-us\/office\/open-xml\/open-xml-sdk<\/a><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Document creation<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">In the following example, we reported a real scenario concerning the creation of a product report of a store.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">We created the&nbsp;<em>ColumnAttribute<\/em>&nbsp;class, which inherits from&nbsp;<em>System.Attribute<\/em>&nbsp;and defines a set of attributes related to a single column. This annotation will be added to single properties of class\/classes on which the report is based.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\n\/\/\/ &lt;summary &gt;\n\/\/\/ ColumnAttribute:\n\/\/\/ Inherits from System.Attribute class\n\/\/\/ &lt;\/summary &gt;\npublic class ColumnAttribute : Attribute\n{\n\u00a0\u00a0\u00a0\u00a0\/\/ column name\n\u00a0\u00a0\u00a0\u00a0public string Name { get; set; }\n\u00a0\u00a0\u00a0\u00a0\/\/ is it a date?\n\u00a0\u00a0\u00a0\u00a0&#x5B;DefaultValue(false)]\n\u00a0\u00a0\u00a0\u00a0public bool IsDate { get; set; }\u00a0\u00a0 \n\u00a0\u00a0\u00a0\u00a0\/\/ is it a time?\n\u00a0\u00a0\u00a0\u00a0&#x5B;DefaultValue(false)]\n\u00a0\u00a0\u00a0\u00a0public bool IsTime { get; set; }\n\u00a0\u00a0\u00a0\u00a0\/\/ is it a currency?\n\u00a0\u00a0\u00a0\u00a0&#x5B;DefaultValue(false)]\n\u00a0\u00a0\u00a0\u00a0public bool IsCurrency { get; set; }\n\u00a0\u00a0\u00a0\u00a0\/\/ is it a percentage?\n\u00a0\u00a0\u00a0\u00a0&#x5B;DefaultValue(false)]\n\u00a0\u00a0\u00a0\u00a0public bool IsPercentage { get; set; }\n\u00a0\u00a0\u00a0\u00a0\/\/ has it a width based on content?\n\u00a0\u00a0\u00a0\u00a0&#x5B;DefaultValue(false)]\n\u00a0\u00a0\u00a0\u00a0public bool AutoSize { get; set; }\n\u00a0\u00a0\u00a0\u00a0\/\/ has it to be sorted?\n\u00a0\u00a0\u00a0\u00a0\/\/ Sort: -1 descending, 0 none, 1 ascending\n\u00a0\u00a0\u00a0\u00a0&#x5B;DefaultValue(0)]\n\u00a0\u00a0\u00a0\u00a0public int Sort { get; set; }\n\u00a0\u00a0\u00a0\u00a0\/\/ custom style index\n\u00a0\u00a0\u00a0\u00a0public uint StyleIndex { get; set; }\n}\n\u00a0\npublic class Product\n{\n\u00a0\u00a0\u00a0\u00a0&#x5B;Column(Name = &quot;Id&quot;)]\n\u00a0\u00a0\u00a0\u00a0public int Id { get; set; }\n\u00a0\u00a0\u00a0\u00a0&#x5B;Column(Name = &quot;Ean&quot;)]\n\u00a0\u00a0\u00a0\u00a0public string Ean { get; set; }\n\u00a0\u00a0\u00a0\u00a0&#x5B;Column(Name = &quot;Name&quot;, AutoSize = true, Sort = 1)]\n\u00a0\u00a0\u00a0\u00a0public string Name { get; set; }\n\u00a0\u00a0\u00a0\u00a0&#x5B;Column(Name = &quot;Description&quot;)]\n\u00a0\u00a0\u00a0\u00a0public string Description { get; set; }\n\u00a0\u00a0\u00a0\u00a0&#x5B;Column(Name = &quot;Brand&quot;, AutoSize = true)]\n\u00a0\u00a0\u00a0\u00a0public string Brand { get; set; }\n\u00a0\u00a0\u00a0\u00a0&#x5B;Column(Name = &quot;Category&quot;, AutoSize = true)]\n\u00a0\u00a0\u00a0\u00a0public string Category { get; set; }\n\u00a0\u00a0\u00a0\u00a0&#x5B;Column(Name = &quot;Price&quot;, IsCurrency = true)]\n\u00a0\u00a0\u00a0\u00a0public decimal Price { get; set; }\n\u00a0\u00a0\u00a0\u00a0&#x5B;Column(Name = &quot;Quantity&quot;)]\n\u00a0\u00a0\u00a0\u00a0public int Quantity { get; set; }\n\u00a0\u00a0\u00a0\u00a0&#x5B;Column(Name = &quot;Rating&quot;, IsPercentage = true)]\n\u00a0\u00a0\u00a0\u00a0public decimal Rating { get; set; }\n\u00a0\u00a0\u00a0\u00a0&#x5B;Column(Name = &quot;ReleaseDate&quot;, IsDate = true)]\n\u00a0\u00a0\u00a0\u00a0public DateTime ReleaseDate { get; set; }\n}\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">Fields without&nbsp;<strong>ColumnAttribute<\/strong>&nbsp;annotation will be ignored and not exported.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">In order to centralize the creation of Office Open XML spreadsheets, we have created the&nbsp;<em>OpenXMLProvider<\/em>&nbsp;class. It provides us a generic&nbsp;<strong>GenerateWorksheet<\/strong>&nbsp;method that allows us to take as input a list of elements, to exclude some fields and to define the name of the main sheet.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\npublic class OpenXMLProvider\n{\n\u00a0\u00a0\u00a0\u00a0public byte&#x5B;] File { get; private set; }\n\u00a0\n\u00a0\u00a0\u00a0\u00a0public void GenerateWorksheet&lt;T&gt; (IEnumerable&lt;T&gt; list, IEnumerable&lt;String&gt; fieldsToExclude = null, String name = &quot;Foglio 1&quot;)\n\u00a0\u00a0\u00a0\u00a0{\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0File = WorksheetUtilities.CreateGenericReport&lt;T&gt;(list, fieldsToExclude, name);\n\u00a0\u00a0\u00a0\u00a0}\n}\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">The core of our solution is certainly the<em>&nbsp;OpenXMLWorksheetBuilder<\/em>&nbsp;class, which allows us to create an Office Open XML spreadsheet by writing native XML code inside the sheet.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Before writing the list of our products in the file, we should define the styles of the file, using the&nbsp;<strong>GenerateWorkbookStylesPartContent<\/strong>&nbsp;method., At first glance, it may seem a bit mind-bending, but it allows us to create a list of styles and formats to be used in our spreadsheet.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\nprivate void GenerateWorkbookStylesPartContent(WorkbookStylesPart workbookStylesPart)\n{\n\u00a0\u00a0\u00a0\u00a0\/\/ Declaring stylesheet and main namespaces\n\u00a0\u00a0\u00a0\u00a0Stylesheet stylesheet = new Stylesheet() { MCAttributes = new MarkupCompatibilityAttributes() { Ignorable = &quot;x14ac&quot; } };\n\u00a0\u00a0\u00a0\u00a0stylesheet.AddNamespaceDeclaration(&quot;mc&quot;, &quot;http:\/\/schemas.openxmlformats.org\/markup-compatibility\/2006&quot;);\n\u00a0\u00a0\u00a0\u00a0stylesheet.AddNamespaceDeclaration(&quot;x14ac&quot;, &quot;http:\/\/schemas.microsoft.com\/office\/spreadsheetml\/2009\/9\/ac&quot;);\n\u00a0\n\u00a0\u00a0\u00a0\u00a0\/\/ Declaring customer number format:\n\u00a0\u00a0\u00a0\u00a0NumberingFormats numberingFormats = new NumberingFormats() { Count = 5U };\n\u00a0\u00a0\u00a0\u00a0NumberingFormat numberingFormatDateTime = new NumberingFormat() { NumberFormatId = 1U, FormatCode = &quot;dd\/mm\/yyyy\\\\ hh:mm;@&quot; };\n\u00a0\u00a0\u00a0\u00a0NumberingFormat numberingFormatCurrency = new NumberingFormat() { NumberFormatId = 2U, FormatCode = &quot;#,##0.00\\\\ \\&quot;\u20ac\\&quot;&quot; };\n\u00a0\u00a0\u00a0\u00a0NumberingFormat numberingFormatPercentage = new NumberingFormat() { NumberFormatId = 3U, FormatCode = &quot;###,000\\\\ \\&quot;%\\&quot;&quot; };\n\u00a0\u00a0\u00a0\u00a0NumberingFormat numberingFormatDate = new NumberingFormat() { NumberFormatId = 4U, FormatCode = &quot;dd\/mm\/yyyy;@&quot; };\n\u00a0\u00a0\u00a0\u00a0NumberingFormat numberingFormatTime = new NumberingFormat() { NumberFormatId = 5U, FormatCode = &quot;hh:mm;@&quot; };\n\u00a0\n\u00a0\u00a0\u00a0\u00a0numberingFormats.Append(numberingFormatDateTime);\n\u00a0\u00a0\u00a0\u00a0numberingFormats.Append(numberingFormatCurrency);\n\u00a0\u00a0\u00a0\u00a0numberingFormats.Append(numberingFormatPercentage);\n\u00a0\u00a0\u00a0\u00a0numberingFormats.Append(numberingFormatDate);\n\u00a0\u00a0\u00a0\u00a0numberingFormats.Append(numberingFormatTime);\n\u00a0\n\u00a0\u00a0\u00a0\u00a0\/\/ Declaring fonts:\n\u00a0\u00a0\u00a0\u00a0Fonts fonts = new Fonts() { Count = 2U, KnownFonts = true };\n\u00a0\n\u00a0\u00a0\u00a0\u00a0Font fontNormal = new Font(\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0new FontName() { Val = &quot;Calibri&quot; },\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0new FontSize() { Val = _fontWidth }\n\u00a0\u00a0\u00a0\u00a0);\n\u00a0\n\u00a0\u00a0\u00a0\u00a0Font fontWhiteBold = new Font(\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0new FontName() { Val = &quot;Calibri&quot; },\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0new FontSize() { Val = _fontWidth },\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0new Bold(),\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0new Color() { Rgb = HexBinaryConverter(System.Drawing.Color.White) }\n\u00a0\u00a0\u00a0\u00a0);\n\u00a0\n\u00a0\u00a0\u00a0\u00a0fonts.Append(fontNormal);\n\u00a0\u00a0\u00a0\u00a0fonts.Append(fontWhiteBold);\n\u00a0\n\u00a0\u00a0\u00a0\u00a0\/\/ Declaring cell filling:\n\u00a0\u00a0\u00a0\u00a0Fills fills = new Fills() { Count = 2U };\n\u00a0\n\u00a0\u00a0\u00a0\u00a0Fill fillNone = new Fill(new PatternFill() { PatternType = PatternValues.None });\n\u00a0\n\u00a0\u00a0\u00a0\u00a0Fill fillGray125 = new Fill(new PatternFill() { PatternType = PatternValues.Gray125 });\n\u00a0\n\u00a0\u00a0\u00a0\u00a0Fill fillDodgerBlue = new Fill(new PatternFill()\n\u00a0\u00a0\u00a0\u00a0{\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0PatternType = PatternValues.Solid,\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0ForegroundColor = new ForegroundColor() { Rgb = HexBinaryConverter(System.Drawing.Color.DodgerBlue) }\n\u00a0\u00a0\u00a0\u00a0});\n\u00a0\n\u00a0\u00a0\u00a0\u00a0fills.Append(fillNone);\n\u00a0\u00a0\u00a0\u00a0fills.Append(fillGray125);\n\u00a0\u00a0\u00a0\u00a0fills.Append(fillDodgerBlue);\n\u00a0\n\u00a0\u00a0\u00a0\u00a0\/\/ Declaring borders:\n\u00a0\u00a0\u00a0\u00a0Borders borders = new Borders() { Count = 2U };\n\u00a0\n\u00a0\u00a0\u00a0\u00a0Border borderNone = new Border();\n\u00a0\n\u00a0\u00a0\u00a0\u00a0Border borderFullThinGray = new Border(\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0new LeftBorder() { Style = BorderStyleValues.Thin, Color = new Color() { Rgb = HexBinaryConverter(System.Drawing.Color.Gray) } },\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0new RightBorder() { Style = BorderStyleValues.Thin, Color = new Color() { Rgb = HexBinaryConverter(System.Drawing.Color.Gray) } },\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0new TopBorder() { Style = BorderStyleValues.Thin, Color = new Color() { Rgb = HexBinaryConverter(System.Drawing.Color.Gray) } },\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0new BottomBorder() { Style = BorderStyleValues.Thin, Color = new Color() { Rgb = HexBinaryConverter(System.Drawing.Color.Gray) } }\n\u00a0\u00a0\u00a0\u00a0);\n\u00a0\n\u00a0\u00a0\u00a0\u00a0borders.Append(borderNone);\n\u00a0\u00a0\u00a0\u00a0borders.Append(borderFullThinGray);\n\u00a0\n\u00a0\u00a0\u00a0\u00a0\/\/ Declaring cell formats\n\u00a0\u00a0\u00a0\u00a0CellFormats cellFormats = new CellFormats() { Count = 7U };\n\u00a0\n\u00a0\u00a0\u00a0\u00a0CellFormat cellFormatBase = new CellFormat() { FontId = 0U, FillId = 0U, BorderId = 0U };\n\u00a0\u00a0\u00a0\u00a0CellFormat cellFormatNormal = new CellFormat() { FontId = 0U, FillId = 0U, BorderId = 1U, FormatId = 0U, ApplyBorder = true };\n\u00a0\u00a0\u00a0\u00a0CellFormat cellFormatHeader = new CellFormat() { FontId = 1U, FillId = 2U, BorderId = 1U, FormatId = 0U, ApplyFont = true, ApplyFill = true, ApplyBorder = true, ApplyAlignment = true, Alignment = new Alignment() { Horizontal = HorizontalAlignmentValues.Center } };\n\u00a0\u00a0\u00a0\u00a0CellFormat cellFormatDate = new CellFormat() { NumberFormatId = 4U, FontId = 0U, FillId = 0U, BorderId = 1U, FormatId = 0U, ApplyNumberFormat = true, ApplyBorder = true };\n\u00a0\u00a0\u00a0\u00a0CellFormat cellFormatTime = new CellFormat() { NumberFormatId = 5U, FontId = 0U, FillId = 0U, BorderId = 1U, FormatId = 0U, ApplyNumberFormat = true, ApplyBorder = true };\n\u00a0\u00a0\u00a0\u00a0CellFormat cellFormatDateTime = new CellFormat() { NumberFormatId = 1U, FontId = 0U, FillId = 0U, BorderId = 1U, FormatId = 0U, ApplyNumberFormat = true, ApplyBorder = true };\n\u00a0\u00a0\u00a0\u00a0CellFormat cellFormatCurrency = new CellFormat() { NumberFormatId = 2U, FontId = 0U, FillId = 0U, BorderId = 1U, FormatId = 0U, ApplyNumberFormat = true, ApplyBorder = true, ApplyAlignment = true };\n\u00a0\u00a0\u00a0\u00a0CellFormat cellFormatPercentage = new CellFormat() { NumberFormatId = 3U, FontId = 0U, FillId = 0U, BorderId = 1U, FormatId = 0U, ApplyNumberFormat = true, ApplyBorder = true, ApplyAlignment = true };\n\u00a0\n\u00a0\u00a0\u00a0\u00a0cellFormats.Append(cellFormatBase);\n\u00a0\u00a0\u00a0\u00a0cellFormats.Append(cellFormatNormal);\n\u00a0\u00a0\u00a0\u00a0cellFormats.Append(cellFormatHeader);\n\u00a0\u00a0\u00a0\u00a0cellFormats.Append(cellFormatDate);\n\u00a0\u00a0\u00a0\u00a0cellFormats.Append(cellFormatTime);\n\u00a0\u00a0\u00a0\u00a0cellFormats.Append(cellFormatDateTime);\n\u00a0\u00a0\u00a0\u00a0cellFormats.Append(cellFormatCurrency);\n\u00a0\u00a0\u00a0\u00a0cellFormats.Append(cellFormatPercentage);\n\u00a0\n\u00a0\u00a0\u00a0\u00a0\/\/ Append all defined styles to worksheet\n\u00a0\u00a0\u00a0\u00a0stylesheet.Append(numberingFormats);\n\u00a0\u00a0\u00a0\u00a0stylesheet.Append(fonts);\n\u00a0\u00a0\u00a0\u00a0stylesheet.Append(fills);\n\u00a0\u00a0\u00a0\u00a0stylesheet.Append(borders);\n\u00a0\u00a0\u00a0\u00a0stylesheet.Append(cellFormats);\n\u00a0\n\u00a0\u00a0\u00a0\u00a0workbookStylesPart.Stylesheet = stylesheet;\n}\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">In this method we defined, in order:<\/p>\n\n\n\n<ol class=\"wp-block-list\"><li>Spreadsheets and main namespaces<\/li><li>Numerical formats and dates<\/li><li>Fonts<\/li><li>Cell colors<\/li><li>Edges<\/li><li>Cell formats<\/li><\/ol>\n\n\n\n<p class=\"wp-block-paragraph\">The cell formats are those that will be used in formatting our cells. Depending on the order used to insert them, the formats take a progressive Uint Id, so the first will have id 0U, the second 1U, etc.<br>From our cell formats we can create a new enumeration type, so that we can use formatting styles more easily:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\npublic enum CustomStyles\n{\n\u00a0\u00a0\u00a0\u00a0Base = 0,\n\u00a0\u00a0\u00a0\u00a0Normal = 1,\n\u00a0\u00a0\u00a0\u00a0Header = 2,\n\u00a0\u00a0\u00a0\u00a0Date = 3,\n\u00a0\u00a0\u00a0\u00a0Time = 4,\n\u00a0\u00a0\u00a0\u00a0DateTime = 5,\n\u00a0\u00a0\u00a0\u00a0Currency = 6,\n\u00a0\u00a0\u00a0\u00a0Percentage = 7\n}\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">Once the styles of our sheet have been inserted, we can start writing data inside it. First, let&#8217;s start from the column headings, using the CreateHeaderCell method:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\nprivate Cell CreateHeaderCell(PropertyInfo propertyInfo)\n{\n\u00a0\u00a0\u00a0\u00a0\/\/ Get custom ColumnAttribute from PropertyInfo object\n\u00a0\u00a0\u00a0\u00a0var columnAttribute = propertyInfo.GetColumnAttribute();\n\u00a0\u00a0\u00a0\u00a0Cell cell = new Cell();\n\u00a0\u00a0\u00a0\u00a0cell.DataType = CellValues.String;\n\u00a0\u00a0\u00a0\u00a0cell.StyleIndex = columnAttribute.StyleIndex &gt; 0 ? columnAttribute.StyleIndex : (uint)CustomStyles.Header;\n\u00a0\u00a0\u00a0\u00a0cell.CellValue = new CellValue(columnAttribute.Name.ToUpperInvariant());\n\u00a0\u00a0\u00a0\u00a0return cell;\n}\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">We also write data cells by using following generic method called&nbsp;<strong>CreateContentCell<\/strong>:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\nprivate Cell CreateContentCell &lt;T &gt; (T element, PropertyInfo propertyInfo)\n{\n\u00a0\u00a0\u00a0\u00a0\/\/ Get custom ColumnAttribute from PropertyInfo object\n\u00a0\u00a0\u00a0\u00a0var columnAttribute = propertyInfo.GetColumnAttribute();\n\u00a0\u00a0\u00a0\u00a0var value = propertyInfo.GetValue(element, null);\n\u00a0\n\u00a0\u00a0\u00a0\u00a0Cell cell = new Cell();\n\u00a0\u00a0\u00a0\u00a0CellValues dataType = CellValues.String;\n\u00a0\u00a0\u00a0\u00a0String text = String.Empty;\n\u00a0\u00a0\u00a0\u00a0uint style = (uint)CustomStyles.Normal;\n\u00a0\u00a0\u00a0\u00a0if (value == null)\n\u00a0\u00a0\u00a0\u00a0{\n\u00a0\u00a0\u00a0\u00a0}\n\u00a0\u00a0\u00a0\u00a0else if (value is DateTime?)\n\u00a0\u00a0\u00a0\u00a0{\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0dataType = CellValues.Number;\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0text = (value as DateTime?).Value.ToOADate().ToString(CultureInfo.InvariantCulture);\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0if (columnAttribute.IsDate)\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0style = (uint)CustomStyles.Date;\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0else if (columnAttribute.IsTime)\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0style = (uint)CustomStyles.Time;\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0else\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0style = (uint)CustomStyles.DateTime;\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}\n\u00a0\u00a0\u00a0\u00a0}\n\u00a0\u00a0\u00a0\u00a0else if (value is decimal)\n\u00a0\u00a0\u00a0\u00a0{\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0dataType = CellValues.Number;\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0if (columnAttribute.IsCurrency)\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0text = (Math.Round((value as decimal?).Value, 3)).ToString(CultureInfo.InvariantCulture);\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0style = (uint)CustomStyles.Currency;\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0else if (columnAttribute.IsPercentage)\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0text = (Math.Round((value as decimal?).Value * 100, 3)).ToString(CultureInfo.InvariantCulture);\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0style = (uint)CustomStyles.Percentage;\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0else\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0text = (Math.Round((value as decimal?).Value \/ 100, 3)).ToString(CultureInfo.InvariantCulture);\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}\n\u00a0\u00a0\u00a0\u00a0}\n\u00a0\u00a0\u00a0\u00a0else if (value is int)\n\u00a0\u00a0\u00a0\u00a0{\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0dataType = CellValues.Number;\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0text = ((value as int?).Value).ToString(CultureInfo.InvariantCulture);\n\u00a0\u00a0\u00a0\u00a0}\n\u00a0\u00a0\u00a0\u00a0else if (value is double)\n\u00a0\u00a0\u00a0\u00a0{\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0dataType = CellValues.Number;\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0text = ((value as double?).Value).ToString(CultureInfo.InvariantCulture);\n\u00a0\u00a0\u00a0\u00a0}\n\u00a0\u00a0\u00a0\u00a0else if (value is bool?)\n\u00a0\u00a0\u00a0\u00a0{\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0text = ((value as bool?).Value ? &quot;SI&quot; : &quot;NO&quot;).ToString(CultureInfo.InvariantCulture);\n\u00a0\u00a0\u00a0\u00a0}\n\u00a0\u00a0\u00a0\u00a0else if (value is String)\n\u00a0\u00a0\u00a0\u00a0{\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0text = (value as String).Replace(&quot;\\0&quot;, String.Empty).ToString(CultureInfo.InvariantCulture);\n\u00a0\u00a0\u00a0\u00a0}\n\u00a0\n\u00a0\u00a0\u00a0\u00a0cell.DataType = dataType;\n\u00a0\u00a0\u00a0\u00a0cell.StyleIndex = style;\n\u00a0\u00a0\u00a0\u00a0cell.CellValue = new CellValue(text.ToUpperInvariant());\n\u00a0\u00a0\u00a0\u00a0return cell;\n}\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\"><strong>CreateContentCell<\/strong>&nbsp;processes the cell content and compares it with the attributes defined for the corresponding column, in order to choose the best formatting.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">In our case, for instance, the values of type decimal defined with the&nbsp;<em>IsCurrency<\/em>&nbsp;attribute are processed differently from those with the&nbsp;<em>IsPercentage<\/em>&nbsp;attribute, to obtain two different and congruous formatting for the same type.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The same goes for dates, which by default are complete (with date and time), but if necessary they can be formatted date only or time only, depending on the&nbsp;<em>IsDate<\/em>&nbsp;or&nbsp;<em>IsTime<\/em>&nbsp;attributes.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Then, we can add metadata to our file, using the&nbsp;<strong>SetDocumentMetadata<\/strong>&nbsp;method:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\nprivate void SetDocumentMetadata(OpenXmlPackage document)\n{\n\u00a0\u00a0\u00a0\u00a0document.PackageProperties.Title = &quot;Sample report&quot;;\n\u00a0\u00a0\u00a0\u00a0\/\/ for example: it retrieves &#039;Creator&#039; attribute from appsettings.json\n\u00a0\u00a0\u00a0\u00a0document.PackageProperties.Creator = _configuration.GetValue&lt;string&gt;(&quot;AppSettings:WorksheetAuthority&quot;);\n\u00a0\u00a0\u00a0\u00a0document.PackageProperties.Created = DateTime.Now;\n\u00a0\u00a0\u00a0\u00a0document.PackageProperties.Language = &quot;en-US&quot;;\n}\n&lt;\/string&gt;\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">here the&nbsp;<em>Creator<\/em>&nbsp;attributes is set by configuration file parameter.<br>All classes and methods introduced up to now are used by our generic method&nbsp;<strong>CreateReport<\/strong>:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\npublic byte&#x5B;] CreateReport &lt;T &gt;(IEnumerable &lt;T &gt; list, IEnumerableString&gt; fieldsToExclude, String name)\n{\n\u00a0\u00a0\u00a0\u00a0using (MemoryStream memoryStream = new MemoryStream())\n\u00a0\u00a0\u00a0\u00a0{\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0using (SpreadsheetDocument spreadsheetDocument = SpreadsheetDocument.Create(memoryStream, SpreadsheetDocumentType.Workbook))\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\/\/ Add a WorkbookPart\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0WorkbookPart workbookPart = spreadsheetDocument.AddWorkbookPart();\n\u00a0\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\/\/ Add a WorkbookStylesPart\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0WorkbookStylesPart workbookStylesPart = workbookPart.AddNewPart &lt;WorkbookStylesPart &gt;();\n\u00a0\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\/\/ Create and define workbook styles\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0GenerateWorkbookStylesPartContent(workbookStylesPart);\n\u00a0\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\/\/ Add a WorksheetPart\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0WorksheetPart worksheetPart = workbookPart.AddNewPart &lt;WorksheetPart &gt; ();\n\u00a0\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0OpenXmlWriter openXmlWriter = OpenXmlWriter.Create(worksheetPart);\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0openXmlWriter.WriteStartElement(new Worksheet());\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0openXmlWriter.WriteElement(new Columns());\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0openXmlWriter.WriteStartElement(new SheetData());\n\u00a0\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0var propertyInfos = GetColumnAttributePropertyInfos &lt;T &gt; (fieldsToExclude).ToList();\n\u00a0\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0List &lt;OpenXmlAttribute &gt; openXmlAttribute = new List &lt;OpenXmlAttribute &gt; ();\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0openXmlAttribute.Add(new OpenXmlAttribute(&quot;r&quot;, null, &quot;1&quot;));\n\u00a0\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0openXmlWriter.WriteStartElement(new Row(), openXmlAttribute);\n\u00a0\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\/\/ Create header row\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0foreach (var propertyInfo in propertyInfos)\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0openXmlWriter.WriteElement(CreateHeaderCell(propertyInfo));\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}\n\u00a0\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\/\/ end tag for header row\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0openXmlWriter.WriteEndElement();\n\u00a0\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0foreach (var (element, rowIndex) in list.Select((v, i) = &gt; (v, i)))\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0openXmlAttribute = new List &lt;OpenXmlAttribute &gt;();\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\/\/ this is the row index\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0openXmlAttribute.Add(new OpenXmlAttribute(&quot;r&quot;, null, (rowIndex + 2).ToString()));\n\u00a0\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0openXmlWriter.WriteStartElement(new Row(), openXmlAttribute);\n\u00a0\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0foreach (var (propertyInfo, columnIndex) in propertyInfos.Select((v, i) = &gt; (v, i)))\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0openXmlAttribute = new List &lt;OpenXmlAttribute &gt;();\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0openXmlAttribute.Add(new OpenXmlAttribute(&quot;t&quot;, null, (columnIndex + 1).ToString()));\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0openXmlWriter.WriteElement(CreateContentCell(element, propertyInfo));\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\/\/ end tag for Row\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0openXmlWriter.WriteEndElement();\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}\n\u00a0\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\/\/ end tag for SheetData\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0openXmlWriter.WriteEndElement();\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\/\/ end tag for Worksheet\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0openXmlWriter.WriteEndElement();\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0openXmlWriter.Close();\n\u00a0\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0openXmlWriter = OpenXmlWriter.Create(workbookPart);\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0openXmlWriter.WriteStartElement(new Workbook());\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0openXmlWriter.WriteStartElement(new Sheets());\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0openXmlWriter.WriteElement(new Sheet()\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0Name = name,\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0SheetId = 1U,\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0Id = spreadsheetDocument.WorkbookPart.\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0GetIdOfPart(worksheetPart)\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0});\n\u00a0\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\/\/ end tag for Sheets\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0openXmlWriter.WriteEndElement();\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\/\/ end tag for Workbook\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0openXmlWriter.WriteEndElement();\n\u00a0\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0openXmlWriter.Close();\n\u00a0\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\/\/ Set column widths\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0SetColumnWidths(worksheetPart.Worksheet, propertyInfos, list);\n\u00a0\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\/\/ Set filtering and sorting\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0SetAutoFilterAndSorting(worksheetPart, workbookPart.Workbook, name, propertyInfos, list.Count() + 1);\n\u00a0\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\/\/ Set metadata for document\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0SetDocumentMetadata(spreadsheetDocument);\n\u00a0\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0spreadsheetDocument.Close();\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0return memoryStream.ToArray();\n\u00a0\u00a0\u00a0\u00a0}\n}\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">In this method, after creating the workbook object and the styles, we proceed to write headers and data.<br>To write cells quickly and efficiently, we proceed in this way:<\/p>\n\n\n\n<ol class=\"wp-block-list\"><li>Opening external tag using&nbsp;<em>OpenXmlWriter.WriteStartElement<\/em><\/li><li>Possible adding of attributes using the&nbsp;<em>OpenXmlAttribute<\/em>class (we suggest to use them to have best readability in XML)<\/li><li>Writing cell value by using&nbsp;<em>OpenXmlWriter.WriteElement<\/em><\/li><li>Closing external tag with&nbsp;<em>OpenXmlWriter.WriteEndElement<\/em><\/li><\/ol>\n\n\n\n<p class=\"wp-block-paragraph\">Concerning the web side, API controller&nbsp;<em>ProductsController<\/em>&nbsp;has only one method,&nbsp;<strong>GetExport<\/strong>, that, in this case, takes as input the number of products to create and gives back a stream of data containing the Open XML file.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The product list will be dynamically generated by using&nbsp;<strong>Bogus<\/strong>&nbsp;library, that allows you to create fake objects and is useful for our purpose.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\n&#x5B;HttpGet(&quot;export\/{count}&quot;)]\npublic ActionResult GetExport(int count = 0)\n{\n\u00a0\u00a0\u00a0\u00a0\/\/ it defines a product template with fake data\n\u00a0\u00a0\u00a0\u00a0var productFaker = new Faker&lt;Product&gt; ()\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0.CustomInstantiator(f =&gt; new Product())\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0.RuleFor(p =&gt; p.Id, f =&gt; f.IndexFaker)\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0.RuleFor(p =&gt; p.Ean, f =&gt; f.Commerce.Ean13())\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0.RuleFor(p =&gt; p.Name, f =&gt; f.Commerce.ProductName())\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0.RuleFor(p =&gt; p.Description, f =&gt; f.Lorem.Sentence(f.Random.Int(5, 20)))\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0.RuleFor(p =&gt; p.Brand, f =&gt; f.Company.CompanyName())\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0.RuleFor(p =&gt; p.Category, f =&gt; f.Commerce.Categories(1).First())\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0.RuleFor(p =&gt; p.Price, f =&gt; f.Random.Decimal(1, 1000))\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0.RuleFor(p =&gt; p.Quantity, f =&gt; f.Random.Int(0, 1000))\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0.RuleFor(p =&gt; p.Rating, f =&gt; f.Random.Decimal(0, 1))\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0.RuleFor(p =&gt; p.ReleaseDate, f =&gt; f.Date.Past(2));\n\u00a0\n\u00a0\u00a0\u00a0\u00a0_openXMLProvider.GenerateWorksheet(productFaker.Generate(count), null, &quot;Sheet 1&quot;);\n\u00a0\n\u00a0\u00a0\u00a0\u00a0return File(_openXMLProvider.File, &quot;application\/octet-stream&quot;);\n}\n<\/pre><\/div>\n\n\n<h2 class=\"wp-block-heading\">Project execution<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">For example purpose, we make a simple GUI, in which you can insert the number of elements, and, after clicking on&nbsp;<strong>Download Report<\/strong>&nbsp;button, download the file.<br>Running the project, we can obtain this screen:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"371\" data-attachment-id=\"28066\" data-permalink=\"https:\/\/blexin.com\/en\/blog-en\/creating-reports-with-open-xml-sdk\/attachment\/image01-15-2\/\" data-orig-file=\"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/image01-15.png?fit=1819%2C659&amp;ssl=1\" data-orig-size=\"1819,659\" data-comments-opened=\"0\" data-image-meta=\"{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}\" data-image-title=\"image01-15\" data-image-description=\"\" data-image-caption=\"\" data-large-file=\"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/image01-15.png?fit=1024%2C371&amp;ssl=1\" src=\"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/image01-15.png?resize=1024%2C371&#038;ssl=1\" alt=\"\" class=\"wp-image-28066\" srcset=\"https:\/\/blexin.com\/wp-content\/uploads\/2020\/12\/image01-15-980x355.png 980w, https:\/\/blexin.com\/wp-content\/uploads\/2020\/12\/image01-15-480x174.png 480w\" sizes=\"auto, (min-width: 0px) and (max-width: 480px) 480px, (min-width: 481px) and (max-width: 980px) 980px, (min-width: 981px) 1024px, 100vw\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Once downloaded the file, we can open it and see the content:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"359\" data-attachment-id=\"28069\" data-permalink=\"https:\/\/blexin.com\/en\/blog-en\/creating-reports-with-open-xml-sdk\/attachment\/image02-14-2\/\" data-orig-file=\"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/image02-14.png?fit=1827%2C641&amp;ssl=1\" data-orig-size=\"1827,641\" data-comments-opened=\"0\" data-image-meta=\"{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}\" data-image-title=\"image02-14\" data-image-description=\"\" data-image-caption=\"\" data-large-file=\"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/image02-14.png?fit=1024%2C359&amp;ssl=1\" src=\"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/image02-14.png?resize=1024%2C359&#038;ssl=1\" alt=\"\" class=\"wp-image-28069\" srcset=\"https:\/\/blexin.com\/wp-content\/uploads\/2020\/12\/image02-14-980x344.png 980w, https:\/\/blexin.com\/wp-content\/uploads\/2020\/12\/image02-14-480x168.png 480w\" sizes=\"auto, (min-width: 0px) and (max-width: 480px) 480px, (min-width: 481px) and (max-width: 980px) 980px, (min-width: 981px) 1024px, 100vw\" \/><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Validating file with Open XML Productivity Tool<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">In generating more or less complex files, it can often happen that they are corrupt or even illegible. When we open the file, an unpleasant alert comes up,&nbsp;warning us that we cannot read our file and that it will try to recover it.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">To overcome this problem and know what is wrong in creating the file, there is Open XML Productivity Tool, which scans our file and checks its syntactical and semantic correctness.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The tool is easy to use: just open it, select a file, and after opening it, click Validate. In the column on the left, we are shown the Worksheet parts, and on the right, there are indicated warnings and errors. Usually, the warnings generate an alert for \u201cdamaged file\u201d, but still readable, which instead it does not happen for files with errors.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Scrolling down the section on the right, we can eventually verify the errors that will make us correct code that generates the report.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"559\" data-attachment-id=\"28071\" data-permalink=\"https:\/\/blexin.com\/en\/blog-en\/creating-reports-with-open-xml-sdk\/attachment\/image03-13-2\/\" data-orig-file=\"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/image03-13.png?fit=1627%2C888&amp;ssl=1\" data-orig-size=\"1627,888\" data-comments-opened=\"0\" data-image-meta=\"{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}\" data-image-title=\"image03-13\" data-image-description=\"\" data-image-caption=\"\" data-large-file=\"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/image03-13.png?fit=1024%2C559&amp;ssl=1\" src=\"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/image03-13.png?resize=1024%2C559&#038;ssl=1\" alt=\"\" class=\"wp-image-28071\" srcset=\"https:\/\/blexin.com\/wp-content\/uploads\/2020\/12\/image03-13-980x535.png 980w, https:\/\/blexin.com\/wp-content\/uploads\/2020\/12\/image03-13-480x262.png 480w\" sizes=\"auto, (min-width: 0px) and (max-width: 480px) 480px, (min-width: 481px) and (max-width: 980px) 980px, (min-width: 981px) 1024px, 100vw\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">The code used in this article is available&nbsp;<a rel=\"noreferrer noopener\" href=\"https:\/\/github.com\/enricobencivenga\/Reporting\" target=\"_blank\">here<\/a>.<\/p>\n\n\n\n\n","protected":false},"excerpt":{"rendered":"<p>Let\u2019s see how to create light and performing reports thanks to Open XML<\/p>\n","protected":false},"author":196716247,"featured_media":28059,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_et_pb_use_builder":"off","_et_pb_old_content":"","_et_gb_content_width":"","_coblocks_attr":"","_coblocks_dimensions":"","_coblocks_responsive_height":"","_coblocks_accordion_ie_support":"","_crdt_document":"","inline_featured_image":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_feature_clip_id":0,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2},"_wpas_customize_per_network":false,"jetpack_post_was_ever_published":false},"categories":[688637524],"tags":[688637384],"class_list":["post-28073","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-blog-en","tag-c-en"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.6 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Creating reports with Open XML SDK - Blexin<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/blexin.com\/en\/blog-en\/creating-reports-with-open-xml-sdk\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Creating reports with Open XML SDK - Blexin\" \/>\n<meta property=\"og:description\" content=\"Let\u2019s see how to create light and performing reports thanks to Open XML\" \/>\n<meta property=\"og:url\" content=\"https:\/\/blexin.com\/en\/blog-en\/creating-reports-with-open-xml-sdk\/\" \/>\n<meta property=\"og:site_name\" content=\"Blexin\" \/>\n<meta property=\"article:published_time\" content=\"2019-11-05T23:00:00+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2021-05-20T16:49:35+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/i2.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/ab37f718-0d69-4960-9b90-8eb7ff437b53.png?fit=1024%2C608&ssl=1\" \/>\n\t<meta property=\"og:image:width\" content=\"1024\" \/>\n\t<meta property=\"og:image:height\" content=\"608\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Enrico Bencivenga\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Enrico Bencivenga\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"13 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/blexin.com\\\/en\\\/blog-en\\\/creating-reports-with-open-xml-sdk\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/blexin.com\\\/en\\\/blog-en\\\/creating-reports-with-open-xml-sdk\\\/\"},\"author\":{\"name\":\"Enrico Bencivenga\",\"@id\":\"https:\\\/\\\/blexin.com\\\/en\\\/#\\\/schema\\\/person\\\/74e4443d1d7ad12d5b4a8db7f63f0194\"},\"headline\":\"Creating reports with Open XML SDK\",\"datePublished\":\"2019-11-05T23:00:00+00:00\",\"dateModified\":\"2021-05-20T16:49:35+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/blexin.com\\\/en\\\/blog-en\\\/creating-reports-with-open-xml-sdk\\\/\"},\"wordCount\":1137,\"image\":{\"@id\":\"https:\\\/\\\/blexin.com\\\/en\\\/blog-en\\\/creating-reports-with-open-xml-sdk\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/i0.wp.com\\\/blexin.com\\\/wp-content\\\/uploads\\\/2020\\\/12\\\/ab37f718-0d69-4960-9b90-8eb7ff437b53.png?fit=1024%2C608&ssl=1\",\"keywords\":[\"C#\"],\"articleSection\":[\"Blog\"],\"inLanguage\":\"en-US\"},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/blexin.com\\\/en\\\/blog-en\\\/creating-reports-with-open-xml-sdk\\\/\",\"url\":\"https:\\\/\\\/blexin.com\\\/en\\\/blog-en\\\/creating-reports-with-open-xml-sdk\\\/\",\"name\":\"Creating reports with Open XML SDK - Blexin\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/blexin.com\\\/en\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/blexin.com\\\/en\\\/blog-en\\\/creating-reports-with-open-xml-sdk\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/blexin.com\\\/en\\\/blog-en\\\/creating-reports-with-open-xml-sdk\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/i0.wp.com\\\/blexin.com\\\/wp-content\\\/uploads\\\/2020\\\/12\\\/ab37f718-0d69-4960-9b90-8eb7ff437b53.png?fit=1024%2C608&ssl=1\",\"datePublished\":\"2019-11-05T23:00:00+00:00\",\"dateModified\":\"2021-05-20T16:49:35+00:00\",\"author\":{\"@id\":\"https:\\\/\\\/blexin.com\\\/en\\\/#\\\/schema\\\/person\\\/74e4443d1d7ad12d5b4a8db7f63f0194\"},\"breadcrumb\":{\"@id\":\"https:\\\/\\\/blexin.com\\\/en\\\/blog-en\\\/creating-reports-with-open-xml-sdk\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/blexin.com\\\/en\\\/blog-en\\\/creating-reports-with-open-xml-sdk\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/blexin.com\\\/en\\\/blog-en\\\/creating-reports-with-open-xml-sdk\\\/#primaryimage\",\"url\":\"https:\\\/\\\/i0.wp.com\\\/blexin.com\\\/wp-content\\\/uploads\\\/2020\\\/12\\\/ab37f718-0d69-4960-9b90-8eb7ff437b53.png?fit=1024%2C608&ssl=1\",\"contentUrl\":\"https:\\\/\\\/i0.wp.com\\\/blexin.com\\\/wp-content\\\/uploads\\\/2020\\\/12\\\/ab37f718-0d69-4960-9b90-8eb7ff437b53.png?fit=1024%2C608&ssl=1\",\"width\":1024,\"height\":608},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/blexin.com\\\/en\\\/blog-en\\\/creating-reports-with-open-xml-sdk\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/blexin.com\\\/en\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Creating reports with Open XML SDK\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/blexin.com\\\/en\\\/#website\",\"url\":\"https:\\\/\\\/blexin.com\\\/en\\\/\",\"name\":\"Blexin\",\"description\":\"Con noi \u00e8 semplice\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/blexin.com\\\/en\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/blexin.com\\\/en\\\/#\\\/schema\\\/person\\\/74e4443d1d7ad12d5b4a8db7f63f0194\",\"name\":\"Enrico Bencivenga\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/4ea7187309674789d6f02c6b757e1f21c8cf800abb2419b4edaa8b09d4c99548?s=96&d=identicon&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/4ea7187309674789d6f02c6b757e1f21c8cf800abb2419b4edaa8b09d4c99548?s=96&d=identicon&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/4ea7187309674789d6f02c6b757e1f21c8cf800abb2419b4edaa8b09d4c99548?s=96&d=identicon&r=g\",\"caption\":\"Enrico Bencivenga\"},\"url\":\"https:\\\/\\\/blexin.com\\\/en\\\/author\\\/enrico-bencivengablexin-com\\\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Creating reports with Open XML SDK - Blexin","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/blexin.com\/en\/blog-en\/creating-reports-with-open-xml-sdk\/","og_locale":"en_US","og_type":"article","og_title":"Creating reports with Open XML SDK - Blexin","og_description":"Let\u2019s see how to create light and performing reports thanks to Open XML","og_url":"https:\/\/blexin.com\/en\/blog-en\/creating-reports-with-open-xml-sdk\/","og_site_name":"Blexin","article_published_time":"2019-11-05T23:00:00+00:00","article_modified_time":"2021-05-20T16:49:35+00:00","og_image":[{"width":1024,"height":608,"url":"https:\/\/i2.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/ab37f718-0d69-4960-9b90-8eb7ff437b53.png?fit=1024%2C608&ssl=1","type":"image\/png"}],"author":"Enrico Bencivenga","twitter_card":"summary_large_image","twitter_misc":{"Written by":"Enrico Bencivenga","Est. reading time":"13 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/blexin.com\/en\/blog-en\/creating-reports-with-open-xml-sdk\/#article","isPartOf":{"@id":"https:\/\/blexin.com\/en\/blog-en\/creating-reports-with-open-xml-sdk\/"},"author":{"name":"Enrico Bencivenga","@id":"https:\/\/blexin.com\/en\/#\/schema\/person\/74e4443d1d7ad12d5b4a8db7f63f0194"},"headline":"Creating reports with Open XML SDK","datePublished":"2019-11-05T23:00:00+00:00","dateModified":"2021-05-20T16:49:35+00:00","mainEntityOfPage":{"@id":"https:\/\/blexin.com\/en\/blog-en\/creating-reports-with-open-xml-sdk\/"},"wordCount":1137,"image":{"@id":"https:\/\/blexin.com\/en\/blog-en\/creating-reports-with-open-xml-sdk\/#primaryimage"},"thumbnailUrl":"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/ab37f718-0d69-4960-9b90-8eb7ff437b53.png?fit=1024%2C608&ssl=1","keywords":["C#"],"articleSection":["Blog"],"inLanguage":"en-US"},{"@type":"WebPage","@id":"https:\/\/blexin.com\/en\/blog-en\/creating-reports-with-open-xml-sdk\/","url":"https:\/\/blexin.com\/en\/blog-en\/creating-reports-with-open-xml-sdk\/","name":"Creating reports with Open XML SDK - Blexin","isPartOf":{"@id":"https:\/\/blexin.com\/en\/#website"},"primaryImageOfPage":{"@id":"https:\/\/blexin.com\/en\/blog-en\/creating-reports-with-open-xml-sdk\/#primaryimage"},"image":{"@id":"https:\/\/blexin.com\/en\/blog-en\/creating-reports-with-open-xml-sdk\/#primaryimage"},"thumbnailUrl":"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/ab37f718-0d69-4960-9b90-8eb7ff437b53.png?fit=1024%2C608&ssl=1","datePublished":"2019-11-05T23:00:00+00:00","dateModified":"2021-05-20T16:49:35+00:00","author":{"@id":"https:\/\/blexin.com\/en\/#\/schema\/person\/74e4443d1d7ad12d5b4a8db7f63f0194"},"breadcrumb":{"@id":"https:\/\/blexin.com\/en\/blog-en\/creating-reports-with-open-xml-sdk\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/blexin.com\/en\/blog-en\/creating-reports-with-open-xml-sdk\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/blexin.com\/en\/blog-en\/creating-reports-with-open-xml-sdk\/#primaryimage","url":"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/ab37f718-0d69-4960-9b90-8eb7ff437b53.png?fit=1024%2C608&ssl=1","contentUrl":"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/ab37f718-0d69-4960-9b90-8eb7ff437b53.png?fit=1024%2C608&ssl=1","width":1024,"height":608},{"@type":"BreadcrumbList","@id":"https:\/\/blexin.com\/en\/blog-en\/creating-reports-with-open-xml-sdk\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/blexin.com\/en\/"},{"@type":"ListItem","position":2,"name":"Creating reports with Open XML SDK"}]},{"@type":"WebSite","@id":"https:\/\/blexin.com\/en\/#website","url":"https:\/\/blexin.com\/en\/","name":"Blexin","description":"Con noi \u00e8 semplice","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/blexin.com\/en\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Person","@id":"https:\/\/blexin.com\/en\/#\/schema\/person\/74e4443d1d7ad12d5b4a8db7f63f0194","name":"Enrico Bencivenga","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/4ea7187309674789d6f02c6b757e1f21c8cf800abb2419b4edaa8b09d4c99548?s=96&d=identicon&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/4ea7187309674789d6f02c6b757e1f21c8cf800abb2419b4edaa8b09d4c99548?s=96&d=identicon&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/4ea7187309674789d6f02c6b757e1f21c8cf800abb2419b4edaa8b09d4c99548?s=96&d=identicon&r=g","caption":"Enrico Bencivenga"},"url":"https:\/\/blexin.com\/en\/author\/enrico-bencivengablexin-com\/"}]}},"jetpack_publicize_connections":[],"jetpack_featured_media_url":"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/ab37f718-0d69-4960-9b90-8eb7ff437b53.png?fit=1024%2C608&ssl=1","jetpack_shortlink":"https:\/\/wp.me\/pcyUBx-7iN","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/blexin.com\/en\/wp-json\/wp\/v2\/posts\/28073","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blexin.com\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blexin.com\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blexin.com\/en\/wp-json\/wp\/v2\/users\/196716247"}],"replies":[{"embeddable":true,"href":"https:\/\/blexin.com\/en\/wp-json\/wp\/v2\/comments?post=28073"}],"version-history":[{"count":5,"href":"https:\/\/blexin.com\/en\/wp-json\/wp\/v2\/posts\/28073\/revisions"}],"predecessor-version":[{"id":31178,"href":"https:\/\/blexin.com\/en\/wp-json\/wp\/v2\/posts\/28073\/revisions\/31178"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/blexin.com\/en\/wp-json\/wp\/v2\/media\/28059"}],"wp:attachment":[{"href":"https:\/\/blexin.com\/en\/wp-json\/wp\/v2\/media?parent=28073"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blexin.com\/en\/wp-json\/wp\/v2\/categories?post=28073"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blexin.com\/en\/wp-json\/wp\/v2\/tags?post=28073"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}