Office open xml excel

In this example, let’s create a demo console project in Visual Studio by selecting File -> New -> Project. From the project window, select Console template and type name and select path for the project, as shown below.

Creating Excel File Using OpenXML

After creating the project, create a Model Class and give a name as TestModel, as shown below.

  1. public class TestModel  
  2.  {              
  3.      public int TestId { getset; }  
  4.      public string TestName { getset; }  
  5.      public string TestDesc { getset; }  
  6.      public DateTime TestDate { getset; }  
  7.  }  

Create one more class and give name as TestModelList.

  1. public class TestModelList  
  2. {  
  3.     public List<TestModel> testData { getset; }  
  4. }  

Let’s add some hard coded data into this model. For that, write the below code in the main method of Program.cs file.

  1. class Program  
  2. {  
  3.     static void Main(string[] args)  
  4.     {             
  5.           
  6.         TestModelList tmList = new TestModelList();  
  7.         tmList.testData = new List<TestModel>();  
  8.         TestModel tm = new TestModel();  
  9.         tm.TestId = 1;  
  10.         tm.TestName = «Test1»;  
  11.         tm.TestDesc = «Tested 1 time»;  
  12.         tm.TestDate = DateTime.Now.Date;  
  13.         tmList.testData.Add(tm);  
  14.   
  15.         TestModel tm1 = new TestModel();  
  16.         tm1.TestId = 2;  
  17.         tm1.TestName = «Test2»;  
  18.         tm1.TestDesc = «Tested 2 times»;  
  19.         tm1.TestDate = DateTime.Now.AddDays(-1);  
  20.         tmList.testData.Add(tm1);  
  21.   
  22.         TestModel tm2 = new TestModel();  
  23.         tm2.TestId = 3;  
  24.         tm2.TestName = «Test3»;  
  25.         tm2.TestDesc = «Tested 3 times»;  
  26.         tm2.TestDate = DateTime.Now.AddDays(-2);  
  27.         tmList.testData.Add(tm2);  
  28.   
  29.         TestModel tm3 = new TestModel();  
  30.         tm3.TestId = 4;  
  31.         tm3.TestName = «Test4»;  
  32.         tm3.TestDesc = «Tested 4 times»;  
  33.         tm3.TestDate = DateTime.Now.AddDays(-3);  
  34.         tmList.testData.Add(tm);   
  35.           
  36.     }  
  37. }   

Now, we have got a Model ready. So, let’s start writing functions for creating an Excel file using OpenXml. For this, add OpenXml from NuGet Packages by right-clicking the project and selecting «Manage NuGet Package» and search openxml. From the list, select DocumentFormat.OpenXml as shown below and install it.

Creating Excel File Using OpenXML

Next, create functions for creating an Excel package using OpenXml as shown below.

  • First, import OpenXml packages as shown below.

    1. using DocumentFormat.OpenXml;  
    2. using DocumentFormat.OpenXml.Packaging;  
    3. using DocumentFormat.OpenXml.Spreadsheet;  
    4. using X14 = DocumentFormat.OpenXml.Office2010.Excel;  
    5. using X15 = DocumentFormat.OpenXml.Office2013.Excel;  

    Then, add the below code for creating an Excel file into given path.

    1. public void CreateExcelFile(TestModelList data, string OutPutFileDirectory)  
    2. {  
    3.     var datetime = DateTime.Now.ToString().Replace(«/»«_»).Replace(«:»«_»);  
    4.    
    5.     string fileFullname = Path.Combine(OutPutFileDirectory, «Output.xlsx»);  
    6.    
    7.     if (File.Exists(fileFullname))  
    8.     {  
    9.         fileFullname = Path.Combine(OutPutFileDirectory, «Output_» + datetime + «.xlsx»);  
    10.     }  
    11.    
    12.     using (SpreadsheetDocument package = SpreadsheetDocument.Create(fileFullname, SpreadsheetDocumentType.Workbook))  
    13.     {  
    14.         CreatePartsForExcel(package, data);  
    15.     }  
    16. }  
  • Write functions for creating workbook and worksheet into Excel.

    1. private void CreatePartsForExcel(SpreadsheetDocument document, TestModelList data)  
    2. {  
    3.     SheetData partSheetData = GenerateSheetdataForDetails(data);  
    4.    
    5.     WorkbookPart workbookPart1 = document.AddWorkbookPart();  
    6.     GenerateWorkbookPartContent(workbookPart1);  
    7.    
    8.     WorkbookStylesPart workbookStylesPart1 = workbookPart1.AddNewPart<WorkbookStylesPart>(«rId3»);  
    9.     GenerateWorkbookStylesPartContent(workbookStylesPart1);  
    10.    
    11.     WorksheetPart worksheetPart1 = workbookPart1.AddNewPart<WorksheetPart>(«rId1»);  
    12.     GenerateWorksheetPartContent(worksheetPart1, partSheetData);  
    13. }  
  • Write functions for creating workbook and work sheet content in Excel, as shown below.

    1. private void GenerateWorkbookPartContent(WorkbookPart workbookPart1)  
    2. {  
    3.     Workbook workbook1 = new Workbook();  
    4.     Sheets sheets1 = new Sheets();  
    5.     Sheet sheet1 = new Sheet() { Name = «Sheet1», SheetId = (UInt32Value)1U, Id = «rId1» };  
    6.     sheets1.Append(sheet1);  
    7.     workbook1.Append(sheets1);  
    8.     workbookPart1.Workbook = workbook1;  
    9. }  
    10.   
    11. private void GenerateWorksheetPartContent(WorksheetPart worksheetPart1, SheetData sheetData1)  
    12. {  
    13.     Worksheet worksheet1 = new Worksheet() { MCAttributes = new MarkupCompatibilityAttributes() { Ignorable = «x14ac» } };  
    14.     worksheet1.AddNamespaceDeclaration(«r»«http://schemas.openxmlformats.org/officeDocument/2006/relationships»);  
    15.     worksheet1.AddNamespaceDeclaration(«mc»«http://schemas.openxmlformats.org/markup-compatibility/2006»);  
    16.     worksheet1.AddNamespaceDeclaration(«x14ac»«http://schemas.microsoft.com/office/spreadsheetml/2009/9/ac»);  
    17.     SheetDimension sheetDimension1 = new SheetDimension() { Reference = «A1» };  
    18.    
    19.     SheetViews sheetViews1 = new SheetViews();  
    20.    
    21.     SheetView sheetView1 = new SheetView() { TabSelected = true, WorkbookViewId = (UInt32Value)0U };  
    22.     Selection selection1 = new Selection() { ActiveCell = «A1», SequenceOfReferences = new ListValue<StringValue>() { InnerText = «A1» } };  
    23.    
    24.     sheetView1.Append(selection1);  
    25.    
    26.     sheetViews1.Append(sheetView1);  
    27.     SheetFormatProperties sheetFormatProperties1 = new SheetFormatProperties() { DefaultRowHeight = 15D, DyDescent = 0.25D };  
    28.    
    29.     PageMargins pageMargins1 = new PageMargins() { Left = 0.7D, Right = 0.7D, Top = 0.75D, Bottom = 0.75D, Header = 0.3D, Footer = 0.3D };  
    30.     worksheet1.Append(sheetDimension1);  
    31.     worksheet1.Append(sheetViews1);  
    32.     worksheet1.Append(sheetFormatProperties1);  
    33.     worksheet1.Append(sheetData1);  
    34.     worksheet1.Append(pageMargins1);  
    35.     worksheetPart1.Worksheet = worksheet1;  
    36. }  
  • Write code for workbook styles by giving your own font size, color, font name, border properties, cell style formats etc. as shown below.

    1. private void GenerateWorkbookStylesPartContent(WorkbookStylesPart workbookStylesPart1)  
    2. {  
    3.     Stylesheet stylesheet1 = new Stylesheet() { MCAttributes = new MarkupCompatibilityAttributes() { Ignorable = «x14ac» } };  
    4.     stylesheet1.AddNamespaceDeclaration(«mc»«http://schemas.openxmlformats.org/markup-compatibility/2006»);  
    5.     stylesheet1.AddNamespaceDeclaration(«x14ac»«http://schemas.microsoft.com/office/spreadsheetml/2009/9/ac»);  
    6.    
    7.     Fonts fonts1 = new Fonts() { Count = (UInt32Value)2U, KnownFonts = true };  
    8.    
    9.     Font font1 = new Font();  
    10.     FontSize fontSize1 = new FontSize() { Val = 11D };  
    11.     Color color1 = new Color() { Theme = (UInt32Value)1U };  
    12.     FontName fontName1 = new FontName() { Val = «Calibri» };  
    13.     FontFamilyNumbering fontFamilyNumbering1 = new FontFamilyNumbering() { Val = 2 };  
    14.     FontScheme fontScheme1 = new FontScheme() { Val = FontSchemeValues.Minor };  
    15.    
    16.     font1.Append(fontSize1);  
    17.     font1.Append(color1);  
    18.     font1.Append(fontName1);  
    19.     font1.Append(fontFamilyNumbering1);  
    20.     font1.Append(fontScheme1);  
    21.    
    22.     Font font2 = new Font();  
    23.     Bold bold1 = new Bold();  
    24.     FontSize fontSize2 = new FontSize() { Val = 11D };  
    25.     Color color2 = new Color() { Theme = (UInt32Value)1U };  
    26.     FontName fontName2 = new FontName() { Val = «Calibri» };  
    27.     FontFamilyNumbering fontFamilyNumbering2 = new FontFamilyNumbering() { Val = 2 };  
    28.     FontScheme fontScheme2 = new FontScheme() { Val = FontSchemeValues.Minor };  
    29.    
    30.     font2.Append(bold1);  
    31.     font2.Append(fontSize2);  
    32.     font2.Append(color2);  
    33.     font2.Append(fontName2);  
    34.     font2.Append(fontFamilyNumbering2);  
    35.     font2.Append(fontScheme2);  
    36.    
    37.     fonts1.Append(font1);  
    38.     fonts1.Append(font2);  
    39.    
    40.     Fills fills1 = new Fills() { Count = (UInt32Value)2U };  
    41.    
    42.     Fill fill1 = new Fill();  
    43.     PatternFill patternFill1 = new PatternFill() { PatternType = PatternValues.None };  
    44.    
    45.     fill1.Append(patternFill1);  
    46.    
    47.     Fill fill2 = new Fill();  
    48.     PatternFill patternFill2 = new PatternFill() { PatternType = PatternValues.Gray125 };  
    49.    
    50.     fill2.Append(patternFill2);  
    51.    
    52.     fills1.Append(fill1);  
    53.     fills1.Append(fill2);  
    54.    
    55.     Borders borders1 = new Borders() { Count = (UInt32Value)2U };  
    56.    
    57.     Border border1 = new Border();  
    58.     LeftBorder leftBorder1 = new LeftBorder();  
    59.     RightBorder rightBorder1 = new RightBorder();  
    60.     TopBorder topBorder1 = new TopBorder();  
    61.     BottomBorder bottomBorder1 = new BottomBorder();  
    62.     DiagonalBorder diagonalBorder1 = new DiagonalBorder();  
    63.    
    64.     border1.Append(leftBorder1);  
    65.     border1.Append(rightBorder1);  
    66.     border1.Append(topBorder1);  
    67.     border1.Append(bottomBorder1);  
    68.     border1.Append(diagonalBorder1);  
    69.    
    70.     Border border2 = new Border();  
    71.    
    72.     LeftBorder leftBorder2 = new LeftBorder() { Style = BorderStyleValues.Thin };  
    73.     Color color3 = new Color() { Indexed = (UInt32Value)64U };  
    74.    
    75.     leftBorder2.Append(color3);  
    76.    
    77.     RightBorder rightBorder2 = new RightBorder() { Style = BorderStyleValues.Thin };  
    78.     Color color4 = new Color() { Indexed = (UInt32Value)64U };  
    79.    
    80.     rightBorder2.Append(color4);  
    81.    
    82.     TopBorder topBorder2 = new TopBorder() { Style = BorderStyleValues.Thin };  
    83.     Color color5 = new Color() { Indexed = (UInt32Value)64U };  
    84.    
    85.     topBorder2.Append(color5);  
    86.    
    87.     BottomBorder bottomBorder2 = new BottomBorder() { Style = BorderStyleValues.Thin };  
    88.     Color color6 = new Color() { Indexed = (UInt32Value)64U };  
    89.    
    90.     bottomBorder2.Append(color6);  
    91.     DiagonalBorder diagonalBorder2 = new DiagonalBorder();  
    92.    
    93.     border2.Append(leftBorder2);  
    94.     border2.Append(rightBorder2);  
    95.     border2.Append(topBorder2);  
    96.     border2.Append(bottomBorder2);  
    97.     border2.Append(diagonalBorder2);  
    98.    
    99.     borders1.Append(border1);  
    100.     borders1.Append(border2);  
    101.    
    102.     CellStyleFormats cellStyleFormats1 = new CellStyleFormats() { Count = (UInt32Value)1U };  
    103.     CellFormat cellFormat1 = new CellFormat() { NumberFormatId = (UInt32Value)0U, FontId = (UInt32Value)0U, FillId = (UInt32Value)0U, BorderId = (UInt32Value)0U };  
    104.    
    105.     cellStyleFormats1.Append(cellFormat1);  
    106.    
    107.     CellFormats cellFormats1 = new CellFormats() { Count = (UInt32Value)3U };  
    108.     CellFormat cellFormat2 = new CellFormat() { NumberFormatId = (UInt32Value)0U, FontId = (UInt32Value)0U, FillId = (UInt32Value)0U, BorderId = (UInt32Value)0U, FormatId = (UInt32Value)0U };  
    109.     CellFormat cellFormat3 = new CellFormat() { NumberFormatId = (UInt32Value)0U, FontId = (UInt32Value)0U, FillId = (UInt32Value)0U, BorderId = (UInt32Value)1U, FormatId = (UInt32Value)0U, ApplyBorder = true };  
    110.            CellFormat cellFormat4 = new CellFormat() { NumberFormatId = (UInt32Value)0U, FontId = (UInt32Value)1U, FillId = (UInt32Value)0U, BorderId = (UInt32Value)1U, FormatId = (UInt32Value)0U, ApplyFont = true, ApplyBorder = true };  
    111.    
    112.     cellFormats1.Append(cellFormat2);  
    113.     cellFormats1.Append(cellFormat3);  
    114.     cellFormats1.Append(cellFormat4);  
    115.    
    116.     CellStyles cellStyles1 = new CellStyles() { Count = (UInt32Value)1U };  
    117.     CellStyle cellStyle1 = new CellStyle() { Name = «Normal», FormatId = (UInt32Value)0U, BuiltinId = (UInt32Value)0U };  
    118.    
    119.     cellStyles1.Append(cellStyle1);  
    120.     DifferentialFormats differentialFormats1 = new DifferentialFormats() { Count = (UInt32Value)0U };  
    121.    TableStyles tableStyles1 = new TableStyles() { Count = (UInt32Value)0U, DefaultTableStyle = «TableStyleMedium2», DefaultPivotStyle = «PivotStyleLight16» };  
    122.    
    123.     StylesheetExtensionList stylesheetExtensionList1 = new StylesheetExtensionList();  
    124.    
    125.     StylesheetExtension stylesheetExtension1 = new StylesheetExtension() { Uri = «{EB79DEF2-80B8-43e5-95BD-54CBDDF9020C}» };  
    126.     stylesheetExtension1.AddNamespaceDeclaration(«x14»«http://schemas.microsoft.com/office/spreadsheetml/2009/9/main»);  
    127.            X14.SlicerStyles slicerStyles1 = new X14.SlicerStyles() { DefaultSlicerStyle = «SlicerStyleLight1» };  
    128.    
    129.     stylesheetExtension1.Append(slicerStyles1);  
    130.    
    131.     StylesheetExtension stylesheetExtension2 = new StylesheetExtension() { Uri = «{9260A510-F301-46a8-8635-F512D64BE5F5}» };  
    132.     stylesheetExtension2.AddNamespaceDeclaration(«x15»«http://schemas.microsoft.com/office/spreadsheetml/2010/11/main»);  
    133.     X15.TimelineStyles timelineStyles1 = new X15.TimelineStyles() { DefaultTimelineStyle = «TimeSlicerStyleLight1» };  
    134.    
    135.     stylesheetExtension2.Append(timelineStyles1);  
    136.    
    137.     stylesheetExtensionList1.Append(stylesheetExtension1);  
    138.     stylesheetExtensionList1.Append(stylesheetExtension2);  
    139.    
    140.     stylesheet1.Append(fonts1);  
    141.     stylesheet1.Append(fills1);  
    142.     stylesheet1.Append(borders1);  
    143.     stylesheet1.Append(cellStyleFormats1);  
    144.     stylesheet1.Append(cellFormats1);  
    145.     stylesheet1.Append(cellStyles1);  
    146.     stylesheet1.Append(differentialFormats1);  
    147.     stylesheet1.Append(tableStyles1);  
    148.     stylesheet1.Append(stylesheetExtensionList1);  
    149.    
    150.     workbookStylesPart1.Stylesheet = stylesheet1;  
    151. }  
  • Write a function for generating workbook content, as shown below.

    1. private void GenerateWorkbookPartContent(WorkbookPart workbookPart1)  
    2. {  
    3.     Workbook workbook1 = new Workbook();  
    4.     Sheets sheets1 = new Sheets();  
    5.     Sheet sheet1 = new Sheet() { Name = «Sheet1», SheetId = (UInt32Value)1U, Id = «rId1» };  
    6.     sheets1.Append(sheet1);  
    7.     workbook1.Append(sheets1);  
    8.     workbookPart1.Workbook = workbook1;  
    9. }  
  • Write the below functions to add data into Excel.
    1. private SheetData GenerateSheetdataForDetails(TestModelList data)  
    2. {  
    3.     SheetData sheetData1 = new SheetData();  
    4.     sheetData1.Append(CreateHeaderRowForExcel());  
    5.   
    6.     foreach (TestModel testmodel in data.testData)  
    7.     {  
    8.         Row partsRows = GenerateRowForChildPartDetail(testmodel);  
    9.         sheetData1.Append(partsRows);  
    10.     }  
    11.     return sheetData1;  
    12. }  

    The below function is created for creating Header rows in Excel.

    1. private Row CreateHeaderRowForExcel()  
    2. {  
    3.     Row workRow = new Row();  
    4.     workRow.Append(CreateCell(«Test Id», 2U));  
    5.     workRow.Append(CreateCell(«Test Name», 2U));   
    6.     workRow.Append(CreateCell(«Test Description», 2U));  
    7.     workRow.Append(CreateCell(«Test Date», 2U));                   
    8.     return workRow;  

    Below function is used for generating child rows.

    1. private Row GenerateRowForChildPartDetail(TestModel testmodel)  
    2. {  
    3.     Row tRow = new Row();  
    4.     tRow.Append(CreateCell(testmodel.TestId.ToString()));  
    5.     tRow.Append(CreateCell(testmodel.TestName));  
    6.     tRow.Append(CreateCell(testmodel.TestDesc));  
    7.     tRow.Append(CreateCell(testmodel.TestDate.ToShortDateString()));  
    8.      
    9.     return tRow;  
    10. }  

    Below function is used for creating cell by passing only cell data and it adds default style.

    1. private Cell CreateCell(string text)  
    2. {  
    3.     Cell cell = new Cell();  
    4.     cell.StyleIndex = 1U;  
    5.     cell.DataType = ResolveCellDataTypeOnValue(text);  
    6.     cell.CellValue = new CellValue(text);  
    7.     return cell;  
    8. }  

    Below function is used for creating a cell by passing cell data and cell style.

    1. private Cell CreateCell(string text, uint styleIndex)  
    2. {  
    3.     Cell cell = new Cell();  
    4.     cell.StyleIndex = styleIndex;  
    5.     cell.DataType = ResolveCellDataTypeOnValue(text);  
    6.     cell.CellValue = new CellValue(text);  
    7.     return cell;  
    8. }  

    Below function is created for resolving the data type of numeric value in a cell.

    1. private EnumValue<CellValues> ResolveCellDataTypeOnValue(string text)  
    2. {  
    3.     int intVal;  
    4.     double doubleVal;  
    5.     if (int.TryParse(text, out intVal) || double.TryParse(text, out doubleVal))  
    6.     {  
    7.         return CellValues.Number;  
    8.     }  
    9.     else  
    10.     {  
    11.         return CellValues.String;  
    12.     }  
    13. }  

Now, let’s call the main function for generating Excel file into main method with passing our model into it.

  1. static void Main(string[] args)  
  2.  {  
  3.   
  4.      TestModelList tmList = new TestModelList();  
  5.      tmList.testData = new List<TestModel>();  
  6.      TestModel tm = new TestModel();  
  7.      tm.TestId = 1;  
  8.      tm.TestName = «Test1»;  
  9.      tm.TestDesc = «Tested 1 time»;  
  10.      tm.TestDate = DateTime.Now.Date;  
  11.      tmList.testData.Add(tm);  
  12.   
  13.      TestModel tm1 = new TestModel();  
  14.      tm1.TestId = 2;  
  15.      tm1.TestName = «Test2»;  
  16.      tm1.TestDesc = «Tested 2 times»;  
  17.      tm1.TestDate = DateTime.Now.AddDays(-1);  
  18.      tmList.testData.Add(tm1);  
  19.   
  20.      TestModel tm2 = new TestModel();  
  21.      tm2.TestId = 3;  
  22.      tm2.TestName = «Test3»;  
  23.      tm2.TestDesc = «Tested 3 times»;  
  24.      tm2.TestDate = DateTime.Now.AddDays(-2);  
  25.      tmList.testData.Add(tm2);  
  26.   
  27.      TestModel tm3 = new TestModel();  
  28.      tm3.TestId = 4;  
  29.      tm3.TestName = «Test4»;  
  30.      tm3.TestDesc = «Tested 4 times»;  
  31.      tm3.TestDate = DateTime.Now.AddDays(-3);  
  32.      tmList.testData.Add(tm);  
  33.   
  34.      Program p = new ExelConvertDemo.Program();  
  35.      p.CreateTaktExcelFile(tmList, «d:\»);  
  36.  }  

Output of the Excel file would be similar to the below image.

Creating Excel File Using OpenXML

  • Download ExcelOpenXMLBasics_CSharp.zip — 19.5 KB
  • Download ExcelOpenXMLBasics_VB.zip — 26.1 KB

Introduction

The purpose of this article is to describe how to create an Excel workbook using solely DocumentFormat.OpenXml.dll (namespace is DocumentFormat.OpenXml).

In order to test the samples you have to download and install the Open XML SDK 2.0 from Download Center. 

The demo is created for both C# and Visual Basic. 

When creating an Excel file with Open XML SDK, there’s no need to install Microsoft Office, so this library can be used without Excel installation. However, the demo project starts the xlsx document after it hsa been created so in order to view the file created, a program that can open xlsx files should be installed to view the file.

Little bit of explanation about Open XML 

Open XML is an open and standardized format for Office files. The standards used are:

  • ECMA-376   
  • ISO/IEC 29500-1:2008    

These standards define the structure and the elements for the Office files. The Office files (like xlsx for Excel) themselves are zipped files that contain a specific directory and file structure. The files that hold the content of a spreadsheet are xml files like any other xml files. 

In case of Excel files a basic xlsx file contains for example following files:

  • /[Content_Types].xml: Defines parts and extensions for the spreadsheet 
  • /xl/workbook.xml: For e xample sheets that are included in the workbook 
  • /xl/styles.xml: Styles used in the worksheets 
  • /xl/sharedStrings.xml: Strings that are shared among cells 
  • /xl/worksheets/sheet1.xml...: The actual worksheets 

The actual package contains more files but in the scope of this article these are the most interesting ones. The demo projects included show few operations that are done to produce and modify these files.   

About the project 

The project itself is very simple. It consists of two classes: MainWindow class and a static Excel Class. The Excel class is responsible of all the operations done against the Excel spreadsheet. It’s kinda utility class, but note that it’s nowhere near ready. It’s supposed to be used as a learning tool or a seed to an actual implementation. 

When writing this demo I found out that Excel is very picky on the XML files. One surprise was that the order of the elements in XML files is very important. For example elements in style sheet such as  fonts, fills, borders, cellStyleXfs, cellXfs etc must be in specific order. Otherwise the document is interpreted as corrupted.

Another observation was that the indexes of the elements are quite often used (for example the index of a shared string). However there is no support in the library to fetch the indexes so the collections have to be looped in order to calculate the index of a desired element.

So one of the best tools when building this was a utility to extract  data from the xlsx (=zip) file to see what is the actual content.

If you download the project, you’ll notice that fully qualified class names are used. In this article I have removed the namespaces before the classes in order to enhance readability. So if you are copying code from the code snippets, don’t forget to define using (in C#) or Imports (in VB) for the two namespaces:

  • DocumentFormat.OpenXml.Packaging
  • DocumentFormat.OpenXml.Spreadsheet 

To create the spreadsheet 

Now to the code. The first thing is to create the spreadsheet. This is actually the xlsx file. The spreadsheet is created in C# as follows

public static SpreadsheetDocument CreateWorkbook(string fileName) {
   SpreadsheetDocument spreadSheet = null;
   SharedStringTablePart sharedStringTablePart;
   WorkbookStylesPart workbookStylesPart;

   try {
      
      spreadSheet = SpreadsheetDocument.Create(fileName, SpreadsheetDocumentType.Workbook, false);

      
      
      spreadSheet.AddWorkbookPart();
      spreadSheet.WorkbookPart.Workbook = new Workbook();
      spreadSheet.WorkbookPart.Workbook.Save();

      
      sharedStringTablePart = spreadSheet.WorkbookPart.AddNewPart<SharedStringTablePart>();
      sharedStringTablePart.SharedStringTable = new SharedStringTable();
      sharedStringTablePart.SharedStringTable.Save();

      
      spreadSheet.WorkbookPart.Workbook.Sheets = new Sheets();
      spreadSheet.WorkbookPart.Workbook.Save();

      
      workbookStylesPart = spreadSheet.WorkbookPart.AddNewPart<WorkbookStylesPart>();
      workbookStylesPart.Stylesheet = new Stylesheet();
      workbookStylesPart.Stylesheet.Save();
   } catch (System.Exception exception) {
      System.Windows.MessageBox.Show(exception.Message, "Excel OpenXML basics", System.Windows.MessageBoxButton.OK, System.Windows.MessageBoxImage.Hand);
   }

   return spreadSheet;
} 

 And in Visual Basic 

Public Shared Function CreateWorkbook(fileName As String) As SpreadsheetDocument
    Dim spreadSheet As SpreadsheetDocument = Nothing
    Dim sharedStringTablePart As SharedStringTablePart
    Dim workbookStylesPart As WorkbookStylesPart

    Try
        
        spreadSheet = SpreadsheetDocument.Create(fileName, SpreadsheetDocumentType.Workbook, False)

        
        
        spreadSheet.AddWorkbookPart()
        spreadSheet.WorkbookPart.Workbook = New Workbook()
        spreadSheet.WorkbookPart.Workbook.Save()

        
        sharedStringTablePart = spreadSheet.WorkbookPart.AddNewPart(Of SharedStringTablePart)()
        sharedStringTablePart.SharedStringTable = New SharedStringTable()
        sharedStringTablePart.SharedStringTable.Save()

        
        spreadSheet.WorkbookPart.Workbook.Sheets = New DocumentFormat.OpenXml.Spreadsheet.Sheets()
        spreadSheet.WorkbookPart.Workbook.Save()

        
        workbookStylesPart = spreadSheet.WorkbookPart.AddNewPart(Of WorkbookStylesPart)()
        workbookStylesPart.Stylesheet = New Stylesheet()
        workbookStylesPart.Stylesheet.Save()
    Catch exception As System.Exception
        System.Windows.MessageBox.Show(exception.Message, "Excel OpenXML basics", System.Windows.MessageBoxButton.OK, System.Windows.MessageBoxImage.Hand)
    End Try

    Return spreadSheet
End Function   

After the spreadsheet document is created, four elemental parts common to all worksheets are added:  

  • Workbook: Contains definition of the workbook itself 
  • SharedStringTable: A table of strings that are shared among cells  
  • Sheets collection: Collection of sheets in the workbook 
  • Stylesheet: Style definitions for the cells. Such as borders, fonts etc.

When creating each of these, first a part is created and after that the object itself. Note that parts are found in DocumentFormat.OpenXml.Packaging namespace while Excel objects are in DocumentFormat.OpenXml.Spreadsheet namespace. So the parts describe the ‘storage’ while the objects from the Spreadsheet  namespace describe the content elements in the xml files.

Creating the styles

Creating using the code  

One way to create the style definitions is to create them from the code. In the demo, the following basic styles are created: 

  • Numbering format (in x:numFmts): This is used to properly format a currency value 
  • Font (in x:fonts): Calibri with font size 11 is used
  • Fill (in x:fills): A fill with no pattern is defined
  • Border (in x:borders): A border definition with no borders is defined 
  • Cell style format (in x:CellStyleXfs): A general cell style format definition is used
  • Cell formats (in x:CellXfs
    • General text
    • Date: NumberFormatId 22 
    • Currency: NumberFormatId 164, references the numbering format 
    • Percentage: NumberFormatId 10

The funny thing is that many of the numbering formats are predefined. So in order to use a correct formatting one has to discover the id’s. One way to do this is to find the information by creating an Excel file containing the desired format and to examine the contents of the xlsx file. 

Another thing is that, as mentioned before, the order of the style sheet elements is critical. If the order isn’t correct, Excel will very easily interpret the document as corrupted. 

An excerpt from the style creation is the creation of CellStyleFormats element and a CellFormat element inside the formats:

Stylesheet stylesheet = spreadsheet.WorkbookPart.WorkbookStylesPart.Stylesheet;


stylesheet.InsertAt<CellFormats>(new CellFormats(), 5);


stylesheet.GetFirstChild<CellFormats>().InsertAt<CellFormat>(
   new CellFormat() {
      FormatId = 0,
      NumberFormatId = 0
   }, 0);

And in Visual Basic

Dim stylesheet As Stylesheet = spreadsheet.WorkbookPart.WorkbookStylesPart.Stylesheet


stylesheet.InsertAt(Of CellFormats)(New CellFormats(), 5)


stylesheet.GetFirstChild(Of CellFormats)().InsertAt(Of CellFormat)(
   New CellFormat() With {
      .FormatId = 0,
      .NumberFormatId = 0
   }, 0

Using a predefined stylesheet 

Another way to define the styles is to use an existing XML file that holds the style definition. In the project theres a PredefinedStyles.xml file included in the build output. The contents of this file are read into a string which is then added to the empty stylesheet created previously.

The style definitions look as following (it’s actually the same that is also created using the code): 

<x:numFmts>
  <x:numFmt numFmtId="164" formatCode="#,##0.00 &quot;€&quot;" />
</x:numFmts>
<x:fonts>
  <x:font>
    <x:sz val="11" />
    <x:name val="Calibri" />
  </x:font>
</x:fonts>
<x:fills>
  <x:fill>
    <x:patternFill patternType="none" />
  </x:fill>
</x:fills>
<x:borders>
  <x:border>
    <x:left />
    <x:right />
    <x:top />
    <x:bottom />
    <x:diagonal />
  </x:border>
</x:borders>
<x:cellStyleXfs>
  <x:xf numFmtId="0" fontId="0" fillId="0" borderId="0" />
</x:cellStyleXfs>
<x:cellXfs>
  <x:xf numFmtId="0" xfId="0" />
  <x:xf numFmtId="22" fontId="0" fillId="0" borderId="0" xfId="0" applyNumberFormat="1" />
  <x:xf numFmtId="164" fontId="0" fillId="0" borderId="0" xfId="0" applyNumberFormat="1" />
  <x:xf numFmtId="10" fontId="0" fillId="0" borderId="0" xfId="0" applyNumberFormat="1" />
</x:cellXfs> 

And it’s added using the following method in C# 

                                          public static bool AddPredefinedStyles(SpreadsheetDocument spreadsheet, string xml) {
         spreadsheet.WorkbookPart.WorkbookStylesPart.Stylesheet.InnerXml = xml;
         spreadsheet.WorkbookPart.WorkbookStylesPart.Stylesheet.Save();

         return true;
      } 

And the function in Visual Basic

                            Public Shared Function AddPredefinedStyles(spreadsheet As SpreadsheetDocument, xml As String) As Boolean
        spreadsheet.WorkbookPart.WorkbookStylesPart.Stylesheet.InnerXml = xml
        spreadsheet.WorkbookPart.WorkbookStylesPart.Stylesheet.Save()

        Return True
    End Function 

As a matter of fact basically any element can be filled by just adding an XML into it. For example a worksheet can be filled by adding a proper XML as the inner text of the worksheet. 

Adding a worksheet 

Next step is to add a worksheet. Adding a worksheet is straight-forward. However, one gotcha is to remember to define the relation to the workbook. Otherwise the sheet isn’t included when the workbook is opened. 

The creation of the workbook looks as following in C#

public static bool AddWorksheet(SpreadsheetDocument spreadsheet, string name) {
  Sheets sheets = spreadsheet.WorkbookPart.Workbook.GetFirstChild<Sheets>();
  Sheet sheet;
  WorksheetPart worksheetPart;

  
  worksheetPart = spreadsheet.WorkbookPart.AddNewPart<WorksheetPart>();
  worksheetPart.Worksheet = new Worksheet(new SheetData());
  worksheetPart.Worksheet.Save();

  
  sheet = new DocumentFormat.OpenXml.Spreadsheet.Sheet() {
     Id = spreadsheet.WorkbookPart.GetIdOfPart(worksheetPart),
     SheetId = (uint)(spreadsheet.WorkbookPart.Workbook.Sheets.Count() + 1),
     Name = name
  };
  sheets.Append(sheet);
  spreadsheet.WorkbookPart.Workbook.Save();

  return true;
}   

And the Visual Basic equivalent function

Public Shared Function AddWorksheet(spreadsheet As SpreadsheetDocument, name As String) As Boolean
    Dim sheets As Sheets = spreadsheet.WorkbookPart.Workbook.GetFirstChild(Of Sheets)()
    Dim sheet As Sheet
    Dim worksheetPart As WorksheetPart

    
    worksheetPart = spreadsheet.WorkbookPart.AddNewPart(Of WorksheetPart)()
    worksheetPart.Worksheet = New Worksheet(New SheetData())
    worksheetPart.Worksheet.Save()

    
    sheet = New Sheet With {
       .Id = spreadsheet.WorkbookPart.GetIdOfPart(worksheetPart),
       .SheetId = (spreadsheet.WorkbookPart.Workbook.Sheets.Count() + 1),
       .Name = name}
    sheets.Append(sheet)
    spreadsheet.WorkbookPart.Workbook.Save()

    Return True
End Function

 Another thing is to remember to number the sheets correctly. Because of this the amount of sheets is queried when defining the SheetId

One more common thing, the shared strings 

A workbook contains a table of shared strings. The idea is that the worksheets can reference a shared string without actually storing the string value inside the worksheet.

As this sounds a good idea and is the proposed way, the effect on the file size isn’t very huge. When I tested this with 10,000 repetitions with a single (short) string the difference between using a shared string compared to repeating the string inside the worksheet was only few hundred bytes. Largely this is because of the compression algorithm compresses the strings quite nicely even if they are repeated. Of course the structure of the workbook and the location of the strings affect this quite much.

In order to add a shared string to the table I use the following method in C#

public static bool AddSharedString(SpreadsheetDocument spreadsheet, string stringItem, bool save = true) {
   SharedStringTable sharedStringTable = spreadsheet.WorkbookPart.SharedStringTablePart.SharedStringTable;

   if (0 == sharedStringTable.Where(item => item.InnerText == stringItem).Count()) {
      sharedStringTable.AppendChild(
         new DocumentFormat.OpenXml.Spreadsheet.SharedStringItem(
            new DocumentFormat.OpenXml.Spreadsheet.Text(stringItem)));

      
      if (save) {
         sharedStringTable.Save();
      }
   }

   return true;
}  

 And in Visual Basic

Public Shared Function AddSharedString(spreadsheet As SpreadsheetDocument, stringItem As String, Optional save As Boolean = True) As Boolean
    Dim sharedStringTable As SharedStringTable = spreadsheet.WorkbookPart.SharedStringTablePart.SharedStringTable

    Dim stringQuery = (From item In sharedStringTable
                      Where item.InnerText = stringItem
                      Select item).Count()

    If 0 = stringQuery Then
        sharedStringTable.AppendChild(
           New DocumentFormat.OpenXml.Spreadsheet.SharedStringItem(
              New DocumentFormat.OpenXml.Spreadsheet.Text(stringItem)))

        
        If save Then
            sharedStringTable.Save()
        End If
    End If

    Return True
End Function  

First, the existence of the string is checked and if it doesn’t exist, it’s added to the table.

In many methods, I have an optional save parameter. This is because saving the changes is quite slow so when the data is added for example in a loop, the saving is deferred. 

Now to the data 

The demo adds the following data to the worksheet

  • A shared string, 3 times
  • A decimal number
  • An integer number
  • A currency value
  • A date
  • A percentage
  • And a boolean value 

All the data is added through specific methods but they all use a common method to actually store the value inside the worksheet.

I wont list adding the cell value since it’s a bit bigger method but it contains the following operations:

  1. Check the existence of the defined row. If it isn’t found a row is created
  2. Check the existence of the defined cell (based on the column index). If it isn’t found a cell is created  
  3. Check if the column is defined in the columns collection. Added if necessary. Actually this isn’t mandatory but by defining the columns, their width can be set.
  4. And at last the value is added to the cell

Few important things:

  • Again, take care about the order. Rows and cells must be in correct order in the xml
  • The date data type isn’t used. This is because Office 2007 doesn’t support date type.  
  • The references in cells are defined as A1, B3 etc. This is quite cumbersome way from the code point of view. This is why I use indexes for both columns and rows. 

The column string is constructed as follows

public static string ColumnNameFromIndex(uint columnIndex) {
   uint remainder;
   string columnName = "";

   while (columnIndex > 0) {
      remainder = (columnIndex - 1) % 26;
      columnName = System.Convert.ToChar(65 + remainder).ToString() + columnName;
      columnIndex = (uint)((columnIndex - remainder) / 26);
   }

   return columnName;
}  

And in VB.Net

Public Shared Function ColumnNameFromIndex(columnIndex As UInt32) As String
    Dim remainder As UInt32
    Dim columnName As String = ""

    While (columnIndex > 0)
        remainder = (columnIndex - 1) Mod 26
        columnName = System.Convert.ToChar(65 + remainder).ToString() + columnName
        columnIndex = ((columnIndex - remainder) / 26)
    End While

    Return columnName
End Function 

Adding a string or a shared string 

As explained before a shared string uses just an index in the worksheet to point to a string in the shared strings table. What was quite amazing was that I didn’t find a mechanism to get the index of a string from the table directly. Instead I had to build a loop to calculate the index.

public static int IndexOfSharedString(SpreadsheetDocument spreadsheet, string stringItem) {
   SharedStringTable sharedStringTable = spreadsheet.WorkbookPart.SharedStringTablePart.SharedStringTable;
   bool found = false;
   int index = 0;

   foreach (SharedStringItem sharedString in sharedStringTable.Elements<SharedStringItem>()) {
      if (sharedString.InnerText == stringItem) {
         found = true;
         break; ;
      }
      index++;
   }

   return found ? index : -1;
} 

And in Visual Basic

Public Shared Function IndexOfSharedString(spreadsheet As SpreadsheetDocument, stringItem As String) As Int32
    Dim sharedStringTable As SharedStringTable = spreadsheet.WorkbookPart.SharedStringTablePart.SharedStringTable
    Dim found As Boolean = False
    Dim index As Int32 = 0

    For Each sharedString As SharedStringItem In sharedStringTable.Elements(Of SharedStringItem)()
        If sharedString.InnerText = stringItem Then
            found = True
            Exit For
        End If
        index = index + 1
    Next

    If found Then
        Return index
    Else
        Return -1
    End If
End Function 

The method for adding the string is quite simple. It gives the option of adding a shared string or a normal string.  

public static bool SetCellValue(SpreadsheetDocument spreadsheet, Worksheet worksheet, uint columnIndex, uint rowIndex, string stringValue, bool useSharedString, bool save = true) {
   string columnValue = stringValue;
   CellValues cellValueType;

   
   if (useSharedString) {
      if (Excel.IndexOfSharedString(spreadsheet, stringValue) == -1) {
         Excel.AddSharedString(spreadsheet, stringValue, true);
      }
      columnValue = Excel.IndexOfSharedString(spreadsheet, stringValue).ToString();
      cellValueType = CellValues.SharedString;
   } else {
      cellValueType = CellValues.String;
   }

   return SetCellValue(spreadsheet, worksheet, columnIndex, rowIndex, cellValueType, columnValue, null, save);
} 

And in VB.Net

Public Shared Function SetStringCellValue(spreadsheet As SpreadsheetDocument, worksheet As Worksheet, columnIndex As UInt32, rowIndex As UInt32, stringValue As String, useSharedString As Boolean, Optional save As Boolean = True) As Boolean
    Dim columnValue As String = stringValue
    Dim cellValueType As CellValues

    
    If (useSharedString) Then
        If (Excel.IndexOfSharedString(spreadsheet, stringValue) = -1) Then
            Excel.AddSharedString(spreadsheet, stringValue, True)
        End If
        columnValue = Excel.IndexOfSharedString(spreadsheet, stringValue).ToString()
        cellValueType = CellValues.SharedString
    Else
        cellValueType = CellValues.String
    End If

    Return SetCellValue(spreadsheet, worksheet, columnIndex, rowIndex, cellValueType, columnValue, Nothing, save)
End Function 

Adding a numeric value   

Adding a numeric value is much like adding a non-shared string value. The only concern is to use proper decimal separator (.) inside the xml so the decimal separator may need to be replaced. Another way is to set the current threads culture to en-US. If you compile the project with EN_US_CULTURE compilation symbol (default in the project) the threads UI culture will be set to local  culture, but the CurrentCulture of the thread will be replaced with en-US. This eliminates the need to reformat decimals. However, keep in mind that if you are getting for example regional settings like CurrencySymbol, it must be fetched from CurrentUICulture

The code looks like

public static bool SetCellValue(SpreadsheetDocument spreadsheet, Worksheet worksheet, uint columnIndex, uint rowIndex, double doubleValue, uint? styleIndex, bool save = true) {
#if EN_US_CULTURE
   string columnValue = doubleValue.ToString();
#else
   string columnValue = doubleValue.ToString().Replace(System.Globalization.CultureInfo.CurrentUICulture.NumberFormat.NumberDecimalSeparator, ".");
#endif

   return SetCellValue(spreadsheet, worksheet, columnIndex, rowIndex, CellValues.Number, columnValue, styleIndex, save);
}

The Visual Basic version is 

Public Shared Function SetDoubleCellValue(spreadsheet As SpreadsheetDocument, worksheet As Worksheet, columnIndex As UInt32, rowIndex As UInt32, doubleValue As Double, styleIndex As UInt32?, Optional save As Boolean = True) As Boolean
#If EN_US_CULTURE Then
    Dim columnValue As String = doubleValue.ToString()
#Else
    Dim columnValue As String = doubleValue.ToString().Replace(System.Globalization.CultureInfo.CurrentUICulture.NumberFormat.NumberDecimalSeparator, ".")
#End If

    Return SetCellValue(spreadsheet, worksheet, columnIndex, rowIndex, CellValues.Number, columnValue, styleIndex, save)
End Function<span style="font-size: 12px; white-space: pre;">
</span>

Adding a date value  

Date value is a bit more tricky. Things to keep in mind with dates:

  • A style needs to be specified. I’ve used a predefined format id 22 to format the date correctly
  • In the style definition ApplyNumberFormat has to be true.
  • The date is expressed as a double value 
  • Excel starts to count the dates from 1.1.1900. This is different from .Net so OLE automation date has to be used
  • The decimal separator may need to be corrected (depending on the culture settings). For example my decimal separator is , so it has to be replaced with . Or as explained earlier with numbers, en-US culture may be used. 

 The addition of a date value looks as following

public static bool SetCellValue(SpreadsheetDocument spreadsheet, Worksheet worksheet, uint columnIndex, uint rowIndex, System.DateTime datetimeValue, uint? styleIndex, bool save = true) {
#if EN_US_CULTURE
   string columnValue = datetimeValue.ToOADate().ToString();
#else
   string columnValue = datetimeValue.ToOADate().ToString().Replace(System.Globalization.CultureInfo.CurrentUICulture.NumberFormat.NumberDecimalSeparator, ".");
#endif

   return SetCellValue(spreadsheet, worksheet, columnIndex, rowIndex, CellValues.Date, columnValue, styleIndex, save);
} 

 And the Visual Basic equivalent

Public Shared Function SetDateCellValue(spreadsheet As SpreadsheetDocument, worksheet As Worksheet, columnIndex As UInt32, rowIndex As UInt32, datetimeValue As System.DateTime, styleIndex As UInt32?, Optional save As Boolean = True) As Boolean
#If EN_US_CULTURE Then
    Dim columnValue As String = datetimeValue.ToOADate().ToString()
#Else
    Dim columnValue As String = datetimeValue.ToOADate().ToString().Replace(System.Globalization.CultureInfo.CurrentUICulture.NumberFormat.NumberDecimalSeparator, ".")
#End If

    Return SetCellValue(spreadsheet, worksheet, columnIndex, rowIndex, CellValues.Date, columnValue, styleIndex, save)
End Function 

Currency, percentage and boolean values

The next methods for adding different value types look very much the same as the previous so I won’t  include them in the article. However, few things to keep in mind:

  • Percentage is like a decimal number but with different format. I’ve used format id 10. 
  • Currency is much like a percentage, but this time also a numFmt needs to be defined. 
  • Excel uses 0 and 1 for boolean values. If True or False is used they are interpreted as text. In Visual Basic the value of true (-1) needs to be changed to 1.

Last words 

Hopefully this article helps to work with Open XML Excel files. The best way to get to know the code is to debug it and make small changes to see what happens :) Have fun! 

History

  • 22th  April, 2012: Created  
  • 25th April, 2012: Readability modification, added alternative way to format numbers when writing to xlsx 

OpenXML — Пример создания Excel файла на C#

Язык программирования C#

В данной публикации приведен пример генерации Excel файла при помощи библиотеки OpenXML.
Отличие этой библиотеки OpenXML от Microsoft.Office.Interop.Excel в быстродействии которое на порядок выше.

Для работы с Excel документами необходимо установить расширение DocumentFormat.OpenXML из Nuget, оно позволит создавать Excel документы для версии Microsoft Office не ниже 2010.

Так-же для работы нам понадобится добавить в проект стандартную библиотеку WindowsBase, просто через Add References, без нее приложение не скомпилируется.

Ниже я приведу пример того, с чем работал сам, первоначальный вариант примера был найден где-то на просторах англоязычного интернета, переработан и теперь выглядит так — как выглядит, с моими комментариями и правками.

Пример демонстрирует формирование маленького Excel файла, который содержит тестовый текст в различных ячейках с применением разных стилей, как на изображении ниже:

OpenXML - C# - Excel

Исходный код примера консольного приложения формирующего Excel на изображении выше:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using DocumentFormat.OpenXml;
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Spreadsheet;
using System.Text.RegularExpressions;


namespace TestXlsx
{
    class Program
    {
        static void Main(string[] args)
        {
            //Создаем новый документ
            using (SpreadsheetDocument document = SpreadsheetDocument.Create("document.xlsx", SpreadsheetDocumentType.Workbook))
            {

                WorkbookPart workbookPart = document.AddWorkbookPart();
                workbookPart.Workbook = new Workbook();
                WorksheetPart worksheetPart = workbookPart.AddNewPart<WorksheetPart>();

                FileVersion fv = new FileVersion();
                fv.ApplicationName = "Microsoft Office Excel";
                worksheetPart.Worksheet = new Worksheet(new SheetData());
                WorkbookStylesPart wbsp = workbookPart.AddNewPart<WorkbookStylesPart>();

                // Добавляем в документ набор стилей
                wbsp.Stylesheet = GenerateStyleSheet();
                wbsp.Stylesheet.Save();



                // Задаем колонки и их ширину
                Columns lstColumns = worksheetPart.Worksheet.GetFirstChild<Columns>();
                Boolean needToInsertColumns = false;
                if (lstColumns == null)
                {
                    lstColumns = new Columns();
                    needToInsertColumns = true;
                }
                lstColumns.Append(new Column() { Min = 1, Max = 10, Width = 20, CustomWidth = true });
                lstColumns.Append(new Column() { Min = 2, Max = 10, Width = 20, CustomWidth = true });
                lstColumns.Append(new Column() { Min = 3, Max = 10, Width = 20, CustomWidth = true });
                lstColumns.Append(new Column() { Min = 4, Max = 10, Width = 20, CustomWidth = true });
                lstColumns.Append(new Column() { Min = 5, Max = 10, Width = 20, CustomWidth = true });
                lstColumns.Append(new Column() { Min = 6, Max = 10, Width = 20, CustomWidth = true });
                lstColumns.Append(new Column() { Min = 7, Max = 10, Width = 20, CustomWidth = true });
                if (needToInsertColumns)
                    worksheetPart.Worksheet.InsertAt(lstColumns, 0);


                //Создаем лист в книге
                Sheets sheets = workbookPart.Workbook.AppendChild(new Sheets());
                Sheet sheet = new Sheet() { Id = workbookPart.GetIdOfPart(worksheetPart), SheetId = 1, Name = "Отчет по входящим" };
                sheets.Append(sheet);

                SheetData sheetData = worksheetPart.Worksheet.GetFirstChild<SheetData>();
                
                //Добавим заголовки в первую строку
                Row row = new Row() { RowIndex = 1 };
                sheetData.Append(row);

                InsertCell(row, 1, "Стиль 1", CellValues.String, 5);
                InsertCell(row, 2, "Стиль 2", CellValues.String, 5);
                InsertCell(row, 3, "Стиль 3", CellValues.String, 5);
                InsertCell(row, 4, "Стиль 4", CellValues.String, 5);
                InsertCell(row, 5, "Стиль 5", CellValues.String, 5);
                InsertCell(row, 6, "Стиль 6", CellValues.String, 5);
                InsertCell(row, 7, "Стиль 7", CellValues.String, 5);

                // Добавляем в строку все стили подряд.
                    row = new Row() { RowIndex = 2 };
                    sheetData.Append(row);

                    InsertCell(row, 1, "1", CellValues.Number, 1);
                    InsertCell(row, 2, ReplaceHexadecimalSymbols("Тест"), CellValues.String, 2);
                    InsertCell(row, 3, ReplaceHexadecimalSymbols("Тест"), CellValues.String, 3);
                    InsertCell(row, 4, ReplaceHexadecimalSymbols("Тест"), CellValues.String, 4);
                    InsertCell(row, 5, ReplaceHexadecimalSymbols("Тест"), CellValues.String, 5);
                    InsertCell(row, 6, ReplaceHexadecimalSymbols("01.01.2017"), CellValues.String, 6);
                    InsertCell(row, 7, ReplaceHexadecimalSymbols("123"), CellValues.String, 7);
                    



                


                workbookPart.Workbook.Save();
                document.Close();
            }


        }

        //Добавление Ячейки в строку (На вход подаем: строку, номер колонки, тип значения, стиль)
        static void InsertCell(Row row, int cell_num, string val, CellValues type, uint styleIndex)
        {
            Cell refCell = null;
            Cell newCell = new Cell() { CellReference = cell_num.ToString() + ":" + row.RowIndex.ToString(), StyleIndex = styleIndex };
            row.InsertBefore(newCell, refCell);
            
            // Устанавливает тип значения.
            newCell.CellValue = new CellValue(val);
            newCell.DataType = new EnumValue<CellValues>(type);

        }

        //Важный метод, при вставки текстовых значений надо использовать.
        //Метод убирает из строки запрещенные спец символы.
        //Если не использовать, то при наличии в строке таких символов, вылетит ошибка.
        static string ReplaceHexadecimalSymbols(string txt)
        {
            string r = "[x00-x08x0Bx0Cx0E-x1Fx26]";
            return Regex.Replace(txt, r, "", RegexOptions.Compiled);
        }

        //Метод генерирует стили для ячеек (за основу взят код, найденный где-то в интернете)
        static Stylesheet GenerateStyleSheet()
        {
            return new Stylesheet(
                new Fonts(
                    new Font(                                                               // Стиль под номером 0 - Шрифт по умолчанию.
                        new FontSize() { Val = 11 },
                        new Color() { Rgb = new HexBinaryValue() { Value = "000000" } },
                        new FontName() { Val = "Calibri" }),
                    new Font(                                                               // Стиль под номером 1 - Жирный шрифт Times New Roman.
                        new Bold(),
                        new FontSize() { Val = 11 },
                        new Color() { Rgb = new HexBinaryValue() { Value = "000000" } },
                        new FontName() { Val = "Times New Roman" }),
                    new Font(                                                               // Стиль под номером 2 - Обычный шрифт Times New Roman.
                        new FontSize() { Val = 11 },
                        new Color() { Rgb = new HexBinaryValue() { Value = "000000" } },
                        new FontName() { Val = "Times New Roman" }),
                    new Font(                                                               // Стиль под номером 3 - Шрифт Times New Roman размером 14.
                        new FontSize() { Val = 14 },
                        new Color() { Rgb = new HexBinaryValue() { Value = "000000" } },
                        new FontName() { Val = "Times New Roman" })
                ),
                new Fills(
                    new Fill(                                                           // Стиль под номером 0 - Заполнение ячейки по умолчанию.
                        new PatternFill() { PatternType = PatternValues.None }),
                    new Fill(                                                           // Стиль под номером 1 - Заполнение ячейки серым цветом
                        new PatternFill(
                            new ForegroundColor() { Rgb = new HexBinaryValue() { Value = "FFAAAAAA" } }
                            )
                        { PatternType = PatternValues.Solid }),
                    new Fill(                                                           // Стиль под номером 2 - Заполнение ячейки красным.
                        new PatternFill(
                            new ForegroundColor() { Rgb = new HexBinaryValue() { Value = "FFFFAAAA" } }
                        )
                        { PatternType = PatternValues.Solid })
                )
                ,
                new Borders(
                    new Border(                                                         // Стиль под номером 0 - Грани.
                        new LeftBorder(),
                        new RightBorder(),
                        new TopBorder(),
                        new BottomBorder(),
                        new DiagonalBorder()),
                    new Border(                                                         // Стиль под номером 1 - Грани
                        new LeftBorder(
                            new Color() { Auto = true }
                        )
                        { Style = BorderStyleValues.Medium },
                        new RightBorder(
                            new Color() { Indexed = (UInt32Value)64U }
                        )
                        { Style = BorderStyleValues.Medium },
                        new TopBorder(
                            new Color() { Auto = true }
                        )
                        { Style = BorderStyleValues.Medium },
                        new BottomBorder(
                            new Color() { Indexed = (UInt32Value)64U }
                        )
                        { Style = BorderStyleValues.Medium },
                        new DiagonalBorder()),
                    new Border(                                                         // Стиль под номером 2 - Грани.
                        new LeftBorder(
                            new Color() { Auto = true }
                        )
                        { Style = BorderStyleValues.Thin },
                        new RightBorder(
                            new Color() { Indexed = (UInt32Value)64U }
                        )
                        { Style = BorderStyleValues.Thin },
                        new TopBorder(
                            new Color() { Auto = true }
                        )
                        { Style = BorderStyleValues.Thin },
                        new BottomBorder(
                            new Color() { Indexed = (UInt32Value)64U }
                        )
                        { Style = BorderStyleValues.Thin },
                        new DiagonalBorder())
                ),
                new CellFormats(
                    new CellFormat() { FontId = 0, FillId = 0, BorderId = 0 },                          // Стиль под номером 0 - The default cell style.  (по умолчанию)
                    new CellFormat(new Alignment() { Horizontal = HorizontalAlignmentValues.Center, Vertical = VerticalAlignmentValues.Center, WrapText = true }) { FontId = 1, FillId = 2, BorderId = 1, ApplyFont = true },       // Стиль под номером 1 - Bold 
                    new CellFormat(new Alignment() { Horizontal = HorizontalAlignmentValues.Center, Vertical = VerticalAlignmentValues.Center, WrapText = true }) { FontId = 2, FillId = 0, BorderId = 2, ApplyFont = true },       // Стиль под номером 2 - REgular
                    new CellFormat() { FontId = 3, FillId = 0, BorderId = 2, ApplyFont = true, NumberFormatId = 4 },       // Стиль под номером 3 - Times Roman
                    new CellFormat() { FontId = 0, FillId = 2, BorderId = 0, ApplyFill = true },       // Стиль под номером 4 - Yellow Fill
                    new CellFormat(                                                                   // Стиль под номером 5 - 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 },      // Стиль под номером 6 - Border
                    new CellFormat(new Alignment() { Horizontal = HorizontalAlignmentValues.Right, Vertical = VerticalAlignmentValues.Center, WrapText = true }) { FontId = 2, FillId = 0, BorderId = 2, ApplyFont = true, NumberFormatId = 4 }       // Стиль под номером 7 - Задает числовой формат полю.
                )
            ); // Выход
        }


    }
}

Вот и всё.
Надеюсь данный пример окажется кому-то полезен.


OpenXML
C#
Excel
пример
Example
Microsoft Office

Overview

This is the 1st part of OpenXML Spreadsheet Tutorial Series:

  • Part 1: Basic

There are two ways which .NET helps you create an Excel file in .NET:

Office Interop needs Excel driver to be installed on the machine which is using it. In this tutorial we use OpenXML to be independent from having Excel driver.

With OpenXML you are simply constructing an XML structure which represents an Excel file. You start with creating a SpreadsheetDocument which represents an Excel document. Then you need to add workbook and worksheet parts in order to construct the document body.

The following diagram demonstrates the components in a Spreadsheet Document and their hierarchy:

Don’t worry if you don’t understand this diagram at this moment. As we are going through the steps you will discover this hierarchy.

Sample: Constructing an Empty Excel File

Open XML 2.5, C#, and .NET 4.6 with Visual Studio 2015 is used in this tutorial. You can still follow with older versions.

In the following sample we will only create an empty excel file without any actual data. It is important to understand the basics of how a document constructed.

  • Open Visual Studio 2015 and create a new C# Console Application under: Installed, Templates, Visual C#

  • You need to add reference to the following libraries:

    • DocumentFormat.OpenXml

    • WindowsBase

  • Add a new class and name it “Report” and create a public method called “CreateExcelDoc”. We are going to create and save our Excel file in this method.

  • Import the following namespaces into the class:

using DocumentFormat.OpenXml;
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Spreadsheet;
  • Create a new SpreadsheetDocument and pass the file name and document as the parameters.

using (SpreadsheetDocument document = SpreadsheetDocument.Create(fileName, SpreadsheetDocumentType.Workbook))
{
}
  • A SpreadsheetDocument must have at least a WorkbookPart and a WorkSheetPart.

Add the following code within the using block.

// Add a WorkbookPart to the document.
WorkbookPart workbookPart = document.AddWorkbookPart();
workbookPart.Workbook = new Workbook();
// Add a WorksheetPart to the WorkbookPart.
WorksheetPart worksheetPart = workbookPart.AddNewPart<WorksheetPart>();
worksheetPart.Worksheet = new Worksheet(new SheetData());

All the spreadsheet elements will be related via parent/child relationship.

The Workbook will contain our spreadsheet sheets.

The Worksheet will contain SheetData and Columns. It is the Sheet data which the actual values goes in rows and cells. By initializing the Worksheet we can append a SheetData as its child by passing it as argument.

  • Append a “Sheets” to the Workbook. The Sheets will contain one or many Sheet which each associated with a WorksheetPart.


sheets = workbookPart.Workbook.AppendChild(new Sheets());

Then we can add one or many “Sheet” to the Sheets. These will be our Excelsheets. Take note that the sheet is associated to the WorksheetPart.

Sheet sheet = new Sheet() { Id = workbookPart.GetIdOfPart(worksheetPart), SheetId = 1, Name = "Test Sheet" };
sheets.Append(sheet);
  • At the end save the Workbook.

workbookPart.Workbook.Save();

  • In the Main method of the Program class, create an object of the Report class and call the CreateExcelDocument by passing the file path.

static void Main(string[] args)
{
    Report report = new Report();
    report.CreateExcelDoc(@"D:DispatcherTimerReport.xlsx");
}
  • Run the Project and check the generated Excel file:

Complete Code:

using DocumentFormat.OpenXml;
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Spreadsheet;
 
namespace OpenXMLSample
{
    public class Report
    {
        public void CreateExcelDoc(string fileName)
        {
            using (SpreadsheetDocument document = SpreadsheetDocument.Create(fileName, SpreadsheetDocumentType.Workbook))
            {
                WorkbookPart workbookPart = document.AddWorkbookPart();
                workbookPart.Workbook = new Workbook();
 
                WorksheetPart worksheetPart = workbookPart.AddNewPart<WorksheetPart>();
                worksheetPart.Worksheet = new Worksheet(new SheetData());
 
                Sheets sheets = workbookPart.Workbook.AppendChild(new Sheets());
 
                Sheet sheet = new Sheet() { Id = workbookPart.GetIdOfPart(worksheetPart), SheetId = 1, Name = "Test Sheet" };
 
                sheets.Append(sheet);
 
                workbookPart.Workbook.Save();
            }
        }
    }
}

Farther reading

Download

Download the source code

carlwils

carlwils

Posted on Apr 7, 2022

• Updated on Apr 22, 2022



 



 



 



 



 

 

Office OpenXML, also known as OpenXML or OOXML, is a zipped, XML-based format developed by Microsoft. It can include Word documents, Excel spreadsheets, PowerPoint presentations, and Charts, Diagrams, Shapes, etc. This article will share how to Convert Excel to Office Open XML and then convet it back using a free Java library named Free Spire.XLS for Java.

Install the free library (2 Method)

1# Download the free library and unzip it, then add the Spire.Xls.jar file to your project as dependency.
2# Directly add the jar dependency to maven project by adding the following configurations to the pom.xml.

<repositories>
    <repository>
        <id>com.e-iceblue</id>
        <name>e-iceblue</name>
        <url>http://repo.e iceblue.com/nexus/content/groups/public/</url>
    </repository>
</repositories>
<dependencies>
    <dependency>
        <groupId>e-iceblue</groupId>
        <artifactId>spire.xls.free</artifactId>
        <version>5.1.0</version>
    </dependency>
</dependencies>

Enter fullscreen mode

Exit fullscreen mode

Convert Excel to Office Open XML Using Java

Free Spire.XLS for Java offers the Workbook.saveAsXml() method to save the Excel file as Office Open XML.

import com.spire.xls.Workbook;

public class ExcelToOpenXML {
    public static void main(String []args){
        //Create a Workbook instance
        Workbook workbook = new Workbook();
        //Load an Excel file
        workbook.loadFromFile("Sales1.xlsx");

        //Save as Office Open XML file format
        workbook.saveAsXml("ToXML.xml");
    }
}

Enter fullscreen mode

Exit fullscreen mode

Convert Office Open XML to Excel in Java

Using the Workbook.saveToFile() method, you can save the Office Open XML file as Excel.

import com.spire.xls.ExcelVersion;
import com.spire.xls.Workbook;

public class OpenXmlToExcel {
    public static void main(String []args){
        //Create an instance of Workbook class
        Workbook workbook = new Workbook();
        //Load an Office Open XML file
        workbook.loadFromXml("ToXML.xml");

        //Save as Excel XLSX file format
        workbook.saveToFile("ToExcel.xlsx", ExcelVersion.Version2016);
    }
}

Enter fullscreen mode

Exit fullscreen mode

Image description

Понравилась статья? Поделить с друзьями:
  • Office online word яндекс
  • Office microsoft excel formulas
  • Office live com start excel aspx
  • Office interop excel workbook saveas
  • Office interop excel open workbook