C# Export Data as XLSX

As I needed to export some data to an xlsx (Excel 2007+) file.
I first used the Microsoft OpenXML library called DocumentFormat.OpenXML.

At first it looked good but it had some major performance issued while using the object oriented style. I switched over to the OpenXMLWriter (SAX) but this introduced another class of problems like corrupted files. The Documentation is a pile of shit and a while I gave up and reimplemented my export with NPOI.

To have it a little simpler i wrote some helper functions to do the cell and row injection. The result is as follows.

using NPOI.SS.UserModel;
using NPOI.XSSF.UserModel;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;

namespace MyStuff
{
    public class XLSXExport
    {
        private Int32 SheetRowIndex = 0;
        private Int32 SheetCellIndex = 0;
        private ISheet Sheet { get; set; }
        private IRow SheetRow { get; set; }
        private IWorkbook WorkBook { get; set; }
        private ICreationHelper CreationHelper { get; set; }
        public CultureInfo ExportCulture { get; set; }

        public XLSXExport()
        {
            Data = new List<ExportCurveData>();
            ExportCulture = CultureInfo.InvariantCulture;
            WorkBook = new XSSFWorkbook();
            Sheet = WorkBook.CreateSheet("mySheet");
            CreationHelper = WorkBook.GetCreationHelper();
        }

        /// <summary>
        /// Writes and reads workbook to get a byte array
        /// </summary>
        /// <returns>byte[]</returns>
        public byte[] getContent()
        {
            Int32 rand = new Random().Next();

            String tempFileName = rand + DateTime.Now.Ticks.ToString("X16") + ".xlsx";
            String fp = Path.Combine(Path.GetTempPath(), tempFileName);

            try
            {
                using (FileStream FSXLSX = new FileStream(fp, FileMode.Create, FileAccess.Write))
                {
                    // create a row
                    CreateRow();

                    // insert a cell into the last created row
                    CreateCell("Header 1");

                    // insert another cell into the last created row
                    CreateCell("Header 2");

                    // write the data to the xlsx file
                    WorkBook.Write(FSXLSX);
                }
            }
            catch(Exception Ex)
            {
                Trace.WriteLine(Ex.StackTrace.ToString());
            }

            Byte[] data = File.ReadAllBytes(fp);
            File.Delete(fp);

            return data;
        }

        /// <summary>
        /// Creates a new Row in the current Sheet
        /// </summary>
        /// <param name="Data">Object to be formatted</param>
        private void CreateRow()
        {
            try
            {
                SheetRow = Sheet.CreateRow(SheetRowIndex);
                // increment row number
                SheetRowIndex++;
                // reset cell index
                SheetCellIndex = 0;
            }
            catch(Exception Ex)
            {
                Trace.WriteLine(Ex.StackTrace.ToString());
                throw Ex;
            }
        }


        /// <summary>
        /// Returns a new Cell
        /// </summary>
        /// <param name="Data">Object to be formatted</param>
        private void CreateCell(Object Data)
        {
            try
            {
                ICell Cell = SheetRow.CreateCell(SheetCellIndex);
                Cell.SetCellType(GetCellType(Data));            

                String ValueString = String.Empty;
                if(Data != null)
                {
                    if (Data is Single)
                    {
                        Single Value;
                        Single.TryParse(Data.ToString(), out Value);
                        Cell.SetCellValue(Value);
                        Cell.CellStyle = WorkBook.CreateCellStyle();
                        Cell.CellStyle.DataFormat = CreationHelper.CreateDataFormat().GetFormat("0.000");
                    }
                    else if (Data is Double)
                    {
                        Double Value;
                        Double.TryParse(Data.ToString(), out Value);
                        Cell.SetCellValue(Value);
                        Cell.CellStyle = WorkBook.CreateCellStyle();
                        Cell.CellStyle.DataFormat = CreationHelper.CreateDataFormat().GetFormat("0.000");
                    }
                    else if (Data is Decimal)
                    {
                        Decimal Value;
                        Decimal.TryParse(Data.ToString(), out Value);
                        Cell.SetCellValue(Convert.ToDouble(Value));
                        Cell.CellStyle = WorkBook.CreateCellStyle();
                        Cell.CellStyle.DataFormat = CreationHelper.CreateDataFormat().GetFormat("0.000");
                    }
                    else if (Data is Int16)
                    {
                        Int16 Value;
                        Int16.TryParse(Data.ToString(), out Value);
                        Cell.SetCellValue(Value);
                    }
                    else if (Data is Int32)
                    {
                        Int32 Value;
                        Int32.TryParse(Data.ToString(), out Value);
                        Cell.SetCellValue(Value);
                    }
                    else if (Data is Int64)
                    {
                        Int64 Value;
                        Int64.TryParse(Data.ToString(), out Value);
                        Cell.SetCellValue(ValueString);
                    }
                    else if (Data is UInt16)
                    {
                        UInt16 Value;
                        UInt16.TryParse(Data.ToString(), out Value);
                        Cell.SetCellValue(Value);
                    }
                    else if (Data is UInt32)
                    {
                        UInt32 Value;
                        UInt32.TryParse(Data.ToString(), out Value);
                        Cell.SetCellValue(Value);
                    }
                    else if (Data is UInt64)
                    {
                        UInt64 Value;
                        UInt64.TryParse(Data.ToString(), out Value);
                        Cell.SetCellValue(Value);
                    }
                    else if (Data is DateTime)
                    {
                        ValueString = String.Format(ExportCulture, "{0:s}", (DateTime) Data);
                        Cell.SetCellValue(ValueString);
                    }
                    else if (Data is Boolean)
                    {
                        ValueString = String.Format(ExportCulture, "{0}", (Boolean) Data ? "1" : "0");
                        Cell.SetCellValue(ValueString);
                    }
                    else
                    {
                        ValueString = String.Format(ExportCulture, "{0}", Data);
                        Cell.SetCellValue(ValueString);
                    }
                }
            
                SheetCellIndex++;
            }
            catch (Exception Ex)
            {
                Trace.WriteLine(Ex.StackTrace.ToString());
                throw Ex;
            }
        }

        /// <summary>
        /// Return a valid CellType for the given Object data
        /// </summary>
        /// <param name="Data"></param>
        /// <returns>CellValues</returns>
        private CellType GetCellType(Object Data)
        {
            if (Data is Single
                || Data is Double
                || Data is Decimal
                || Data is Int16
                || Data is Int32
                || Data is Int64
                || Data is UInt16
                || Data is UInt32
                || Data is UInt64
            ) {
                return CellType.Numeric;
            }
            else if(Data is Boolean)
            {
                return CellType.Boolean;
            }
            else if (Data is String)
            {
                if(String.IsNullOrWhiteSpace(Data as String))
                {
                    return CellType.Blank;
                }
                else
                {
                    return CellType.String;
                }                
            }
            else
            {
                return CellType.Unknown;
            }
        }
    }
}

 

 

Kommentar verfassen

Diese Website verwendet Akismet, um Spam zu reduzieren. Erfahre mehr darüber, wie deine Kommentardaten verarbeitet werden.