jueves, 10 de marzo de 2011

Lectura de Archivos XLSx con C#, extrae el contenido como colecciones de rows o de entidades o bien de DataTables

Lectura de archivos XLSx, con C#, conversión del contenido en Listas de entidades o en DataTables.


Es importante agregar una referencia a Windows Base.









La clase para lectura de XLSx utiliza tambien esta clase que tiene algunos metodos utiles para hacer uso de las facilidades de Reflection en .NET



using System;

using System.Collections.Generic;
using System.Linq;
using System.Data;
using System.Data.Common;
using System.Reflection;

namespace F.Runtime.Reflection
{
    /// <summary>
    /// Descripción breve de Reflecter.
    /// </summary>
    public sealed class Reflecter
    {
        /// <summary>
        /// Get a DataType from a string Value, this will try to find the best fit
        /// </summary>
        /// <param name="value">value</param>
        /// <returns></returns>
        public static Type GetClosestDataType(string value)
        {
            Type result = value.GetType();


            int v1;
            double v2;
            Single v3;
            DateTime v4;
            bool v5;
            float v6;
               
               
               
            if (int.TryParse(value, out v1)) {
                result = v1.GetType();
            }
            else
                if (double.TryParse (value , out v2)){
                    result = v2.GetType ();
                }
                else
                    if(Single.TryParse (value, out v3)){
                        result = v3.GetType();
                    }
                    else
                        if (DateTime.TryParse(value.ToString (), out v4))
                        {
                            result = v4.GetType();
                        }
                        else
                            if (bool.TryParse(value, out v5))
                            {
                                result = v5.GetType();
                            }
                            else
                                if (float.TryParse(value, out v6))
                                {
                                    result = v6.GetType();
                                }
                                else
                                    {
                                        result = typeof (string);
                                    }
           
            return result;
        }
        /// <summary>
        ///
        /// </summary>
        /// <param name="obj"></param>
        /// <param name="Property"></param>
        /// <returns></returns>
        public static object GetPropertyValue(object obj, string Property)
        {
            try
            {
                PropertyInfo pr =
                obj.GetType().GetProperty(Property);
                if (pr != null)
                {
                    return pr.GetValue (obj, null);
                }
            }
            catch (Exception)
            {

            }
            return null;
        }
        /// <summary>
        /// Coloca un valor a una propiedad
        /// </summary>
        /// <param name="obj"></param>
        /// <param name="Property"></param>
        /// <param name="value"></param>
        public static void SetPropertyValue(object obj, string Property, object value)
        {
            try
            {
                PropertyInfo pr =
                obj.GetType().GetProperty(Property) ;
                if (pr!=null){                   
                    pr.SetValue(obj, value, null);
                }
            }
            catch (Exception) {
           
            }
        }

        /// <summary>
        /// Represents an object into XML file
        /// </summary>
        /// <param name="obj"></param>
        /// <param name="path"></param>
        /// <returns></returns>
        public static string ObjectToXML(object obj, string path)
        {
            System.IO.StreamWriter S = new System.IO.StreamWriter(path);
            System.Xml.Serialization.XmlSerializer X = new System.Xml.Serialization.XmlSerializer(obj.GetType());
            X.Serialize(S, obj);
            return S.ToString();
        }
        /// <summary>
        ///
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="dr"></param>
        /// <param name="l"></param>
        /// <param name="instance"></param>
        public static void DataReaderToList<T>(System.Data.Common.DbDataReader  dr, List<T> l, T instance)
        {
            if (dr != null)
            {
                if (!dr.IsClosed && dr.HasRows )
                {
                    if (l == null)
                        l = new List<T>();

                    while (dr.Read ())
                    {
                        object objT = new object();
                        objT = instance.GetType().Assembly.CreateInstance(instance.GetType().FullName);
                        BindColumns(objT, dr);
                        l.Add((T)objT);
                    }
                }
            }
        }

        /// <summary>
        /// Bild a List of Objects From
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="dt"></param>
        /// <param name="l"></param>
        /// <param name="instance"></param>
        public static void DataTableToList<T>(DataTable dt, List<T> l, T instance)
        {
            if (dt!=null)
            {
                if (dt.Rows.Count > 0)
                {
                    if (l == null)
                        l = new List<T>();

                    foreach (DataRow r in dt.Rows)
                    {
                        object objT = new object();
                        objT = instance.GetType().Assembly.CreateInstance(instance.GetType().FullName);
                        BindColumns(objT, r);
                        l.Add((T)objT);
                    }
                }
            }
        }

       /// <summary>
       /// Copy Properties from One object to other object
       /// </summary>
       /// <param name="targetObj"></param>
       /// <param name="sourceObj"></param>
        public static void BindColumns(object targetObj, object sourceObj)
        {
            if (targetObj != null)
            {
                PropertyInfo[] targetprops = targetObj.GetType().GetProperties();
                Dictionary<string, PropertyInfo> sourceprops = new Dictionary<string, PropertyInfo>();

                foreach (PropertyInfo P in sourceObj.GetType().GetProperties()) {
                    if (!sourceprops.ContainsKey (P.Name.ToLower () )){
                        sourceprops.Add(P.Name.ToLower (), P);
                    }
                }

                foreach (PropertyInfo P in targetprops )
                {

                    try
                    {
                        if (sourceprops.ContainsKey (P.Name.ToLower () ))                
                        {
                            if (sourceprops[P.Name.ToLower () ].PropertyType.Equals (P.PropertyType )||(P.PropertyType.Name.StartsWith ("Nullable") && P.PropertyType.IsValueType && P.PropertyType.IsGenericType ))
                            {
                                P.SetValue(targetObj, sourceprops[P.Name.ToLower ()].GetValue (sourceObj,null), null);
                            }
                        }
                    }
                    catch
                    {

                    }
                }
            }

        }
       
        /// <summary>
        /// Bind columns method to set columns of a DataRow into properties of an object
        /// </summary>
        /// <param name="obj">Object to be setted</param>
        /// <param name="r">DataRow to be mapped</param>
        public static void BindColumns(object obj, DataRow r)
        {
            if (obj != null)
            {

                foreach (PropertyInfo P in obj.GetType().GetProperties())
                {

                    try
                    {
                        if (r.Table.Columns.Contains(P.Name))
                        {
                            if (!DBNull.Value.Equals(r[P.Name]) && r[P.Name] != null)
                            {
                                if (P.PropertyType.Name.StartsWith("Nullable") && P.PropertyType.IsValueType && P.PropertyType.IsGenericType)
                                {
                                    obj.GetType().GetProperty(P.Name).SetValue(obj, r[P.Name], null);
                                }
                                else{
                                    obj.GetType().GetProperty(P.Name).SetValue(obj, Convert.ChangeType(r[P.Name], P.PropertyType), null);
                                   
                                }

                            }
                        }
                    }
                    catch
                    {

                    }
                }
            }

        }

        /// <summary>
        /// Bind columns method to set columns of a DataRow into properties of an object
        /// </summary>
        /// <param name="obj">Object to be setted</param>
        /// <param name="r">DataRow to be mapped</param>
        public static void BindColumns(object obj, DbDataReader  r)
        {
            if (obj != null)
            {

                foreach (PropertyInfo P in obj.GetType().GetProperties())
                {

                    try
                    {
                        if (r.GetSchemaTable ().Columns.Contains(P.Name))
                        {
                            if (!DBNull.Value.Equals(r[P.Name]) && r[P.Name] != null)
                            {
                                if (P.PropertyType.Name.StartsWith("Nullable") && P.PropertyType.IsValueType && P.PropertyType.IsGenericType)
                                {
                                    obj.GetType().GetProperty(P.Name).SetValue(obj, r[P.Name], null);
                                }
                                else
                                {
                                    obj.GetType().GetProperty(P.Name).SetValue(obj, Convert.ChangeType(r[P.Name], P.PropertyType), null);

                                }

                            }
                        }
                    }
                    catch
                    {

                    }
                }
            }

        }

        /// <summary>
        /// Clone object method, clones only the
        /// </summary>
        /// <param name="obj">Object to be cloned</param>
        /// <returns></returns>
        public static object Clone(object obj)
        {

            object obj2 = obj.GetType().Assembly.CreateInstance(obj.GetType().FullName);

           
                foreach (FieldInfo f in obj.GetType().GetFields())
                {
                    try
                    {
                        obj2.GetType().GetField(f.Name).SetValue(obj2, f.GetValue(obj));
                    }
                    catch {
                   
                    }
                }

                foreach (PropertyInfo P in obj.GetType().GetProperties())
                {
                    try
                    {
                        obj2.GetType().GetField(P.Name).SetValue(obj2, P.GetValue(obj, null));
                    }
                    catch {
                   
                    }
                }
           
            return obj2;

        }
        /// <summary>
        /// Converts object properties into array of values
        /// </summary>
        /// <param name="obj"></param>
        /// <param name="T"></param>
        /// <returns></returns>
        public static object[] ToArray(object obj)
        {
            int i = 0;
            object val;
            object[] values = new object[obj.GetType().GetFields().Length];

            foreach (FieldInfo f in obj.GetType().GetFields())
            {
                try
                {
                    val = f.GetValue(obj);
                    values[i] = val;
                }
                catch
                {
                    values[i] = null;
                }
                i++;
            }
            return values;
        }
        /// <summary>
        /// Converts object properties into array of values
        /// </summary>
        /// <param name="obj"></param>
        /// <param name="T"></param>
        /// <returns></returns>
        public static Dictionary<string, object> PropertiesToDictionary(object obj)
        {
            int i = 0;
           
            Dictionary<string, object> values = new Dictionary<string, object>();

            foreach (PropertyInfo p in obj.GetType().GetProperties())
            {
                try
                {
                    values.Add(p.Name, p.GetValue(obj, null));
                }
                catch
                {
                }
                i++;
            }
            return values;
        }

        /// <summary>
        /// Discover the property names from one object
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public static string[] PropertiesNames(object obj)
        {
            int i = 0;

            string[] names = new string[obj.GetType().GetProperties().Length];

            foreach (PropertyInfo p in obj.GetType().GetProperties())
            {
                try
                {

                    names[i] = p.Name;
                }
                catch
                {
                    names[i] = null;
                }
                i++;
            }
            return names;
        }
        /// <summary>
        /// Converts object properties into array of values
        /// </summary>
        /// <param name="obj"></param>
        /// <param name="T"></param>
        /// <returns></returns>
        public static object[] PropertiesToArray(object obj)
        {
            int i = 0;
            object val;
            object[] values = new object[obj.GetType().GetProperties().Length];

            foreach (PropertyInfo p in obj.GetType().GetProperties())
            {
                try
                {
                    val = p.GetValue(obj, null);
                    values[i] = val;
                }
                catch
                {
                    values[i] = null;
                }
                i++;
            }
            return values;
        }
        /// <summary>
        /// Build a DataTable Definition from an object properties definition
        /// </summary>
        /// <param name="obj">Object</param>
        /// <returns></returns>
        public static DataTable BuildDataTable(object obj)
        {
            DataTable T = new DataTable();
            if (obj != null)
            {
                foreach (FieldInfo f in obj.GetType().GetFields())
                {
                    T.Columns.Add(f.Name, f.FieldType);
                }
            }
            return T;
        }
        /// <summary>
        /// Build a Data table from one Object
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public static DataTable BuildDataTableByProperties(object obj)
        {
            DataTable T = new DataTable();
            if (obj != null)
            {
                foreach (PropertyInfo f in obj.GetType().GetProperties())
                {
                    T.Columns.Add(f.Name, f.PropertyType);
                }
            }
            return T;
        }
        /// <summary>
        /// Add a DataRow to a DataTable taking as parameter an object
        /// </summary>
        /// <param name="obj"></param>       
        public static void AddRow(object obj, DataTable T)
        {
            T.Rows.Add(ToArray(obj));
        }
        /// <summary>
        /// Add a DataRow to a DataTable taking as parameter an object
        /// </summary>
        /// <param name="obj"></param>       
        public static void AddRowByProperties(object obj, DataTable T)
        {
            T.Rows.Add(PropertiesToArray(obj));
        }
        /// <summary>
        /// Convert an object into a DataRow
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public static DataRow ToDataRow(object obj)
        {
            DataRow Dr;
            DataTable T = BuildDataTable(obj);
            Dr = T.NewRow();
            Dr.ItemArray = ToArray(obj);
            return Dr;
        }
        /// <summary>
        /// Convert an object collection into a DataTable
        /// </summary>
        /// <param name="Collection"></param>
        /// <returns></returns>
        public static DataTable ToDataTable(object[] Collection)
        {
            DataTable T = null;

            if (Collection != null)
            {
                if (Collection.Length > 0)
                {
                    T = BuildDataTable(Collection[0]);
                    foreach (object obj in Collection)
                    {
                        AddRow(obj, T);
                    }
                }
            }

            return T;
        }
        /// <summary>
        /// Converts an object array into a datatable using the object properties
        /// </summary>
        /// <param name="Collection">collection of objects</param>
        /// <returns></returns>
        public static DataTable ToDataTableByProperties(object[] Collection)
        {
            DataTable T = null;

            if (Collection != null)
            {
                if (Collection.Length > 0)
                {
                    T = BuildDataTableByProperties(Collection[0]);
                    foreach (object obj in Collection)
                    {
                        AddRowByProperties(obj, T);
                    }
                }
            }

            return T;
        }
    }

}



Clase para leer archivos XLSx



using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Linq;
using System.Xml;
using System.IO;
using System.IO.Packaging;

namespace F.Text.Excel
{
    /// <summary>
    /// Excel formating namespaces
    /// </summary>
    internal static class ExcelNamespaces
    {
        internal static XNamespace excelNamespace = XNamespace.Get("http://schemas.openxmlformats.org/spreadsheetml/2006/main");
        internal static XNamespace excelRelationshipsNamepace = XNamespace.Get("http://schemas.openxmlformats.org/officeDocument/2006/relationships");
    }
    /// <summary>
    /// Cell object, that represent a Cell in a Worksheet
    /// </summary>
    public class Cell
    {
        #region Properties
        /// <summary>
        /// Column in the Worksheet (A,B,C,...)
        /// </summary>
        public string Column { get; set; }
        /// <summary>
        /// To be calculated
        /// </summary>
        public int ColumnNumber { get; set; }
        /// <summary>
        /// Row number 1,2,3... N
        /// </summary>
        public int Row { get; set; }
        /// <summary>
        /// Cell content
        /// </summary>
        public string Data { get; set; }
        /// <summary>
        /// Cell content datatype
        /// </summary>
        public string DataType { get; set; }

        #endregion

        #region Constructors
        /// <summary>
        /// Default constructor
        /// </summary>
        public Cell() {
       
        }
        /// <summary>
        /// Constructor with all the initializers
        /// </summary>
        /// <param name="columnNumber">Column number</param>
        /// <param name="column">Column Name</param>
        /// <param name="row">Row Number</param>
        /// <param name="data">Cell content</param>
        public Cell(int columnNumber,string column, int row, string data)
        {
            this.Column = column;
            this.Row = row;
            this.Data = data;
            this.ColumnNumber = ColumnNumber;
        }
        /// <summary>
        /// Constructor with file reading initializers
        /// </summary>       
        /// <param name="column">Column Name</param>
        /// <param name="row">Row Number</param>
        /// <param name="data">Cell content</param>
        public Cell(string column, int row, string data)
        {
            this.Column = column;
            this.Row = row;
            this.Data = data;
        }
        #endregion

        #region Public Methods
        /// <summary>
        /// Overrides the ToString() Object method, in order to expose object content
        /// </summary>
        /// <returns></returns>
        public override string ToString()
        {
            return string.Format("{0}:{1} - {2}", Row, Column, Data);
        }
        #endregion


    }
    /// <summary>
    /// Row Object that represent a row in a Worksheet and contains a collection of cells
    /// </summary>
    public class Row
    {
        #region Properties
        public int RowNumber { get; set; }
        public List<Cell> Cells { get; set; }
        #endregion

        #region Constructors
        public Row(int row, List<Cell> cells) {
            RowNumber = row;
            Cells = cells;
        }
        /// <summary>
        /// Default constructor
        /// </summary>
        public Row() {

        }

        #endregion

        #region Public Methods
        /// <summary>
        /// Overrides the ToString() Object method, in order to expose object content
        /// </summary>
        /// <returns></returns>
        public override string ToString()
        {
            string result = string.Empty;

            if (Cells != null && Cells.Count > 0) {
                foreach (Cell c in Cells) {
                    result += "{" +
                    c.ToString() + "};";
                }
            }

            return result;
        }
        #endregion
    }

    /// <summary>
    /// XLSx Utility Class, for Reading and writting purposes
    /// </summary>
    public class Xlsx
    {
        #region Properties
        /// <summary>
        ///
        /// </summary>
        public bool FirstRowAsColumnsNames
        {
            get;
            set;
        }
        private static string sheetsPath = "/xl/worksheets/sheet{0}.xml";
        /// <summary>
        /// Path in XLSx File to find the sheets, remembering that a XLSx is a packed file
        /// </summary>
        public static string SheetsPath
        {
            get {
                return sheetsPath;
            }
            set{
                sheetsPath = value;
            }
        }
        public static string sharedStringsContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sharedStrings+xml";
        /// <summary>
        /// XLSx content type to find the shared strings (Excel sheets content)
        /// </summary>
        public static string SharedStringsContentType
        {
            get {
                return sharedStringsContentType;
            }

            set {
                sharedStringsContentType = value;
            }
        }
        #endregion

        #region Prvate Methods
        /// <summary>
        /// Get the shared strings where we can find the Cells data
        /// </summary>
        /// <param name="SharedStringsElement">Shared strings element</param>
        /// <param name="sharedStrings">Shared string indexed output dictionary</param>
        private static void GetSharedStrings(XElement SharedStringsElement, Dictionary<int, string> sharedStrings)
        {
            IEnumerable<XElement> sharedStringsElements = from s in SharedStringsElement.Descendants(ExcelNamespaces.excelNamespace + "t")
                                                          select s;

            int Counter = 0;
            foreach (XElement sharedString in sharedStringsElements)
            {
                sharedStrings.Add(Counter, sharedString.Value);
                Counter++;
            }
        }
        /// <summary>
        /// Obtains the worksheet part of the worksheet number
        /// </summary>
        /// <param name="worksheetID">Workheet ID (number of the sheet)</param>
        /// <param name="allParts">Parts of the file, where we can find the worksheet part</param>
        /// <returns></returns>
        private static XElement GetWorksheet(int worksheetID, PackagePartCollection allParts)
        {
            PackagePart worksheetPart = (from part in allParts
                                         where part.Uri.OriginalString.Equals(String.Format(sheetsPath, worksheetID))
                                         select part).Single();

            return XElement.Load(XmlReader.Create(worksheetPart.GetStream()));
        }
        /// <summary>
        /// Get the index number for a value in the sharedstrings
        /// </summary>
        /// <param name="value">value</param>
        /// <returns></returns>
        private static int IndexOfNumber(string value)
        {
            for (int counter = 0; counter < value.Length; counter++)
            {
                if (char.IsNumber(value[counter]))
                {
                    return counter;
                }
            }

            return 0;
        }
        #endregion

        #region Public Methods
        /// <summary>
        /// Read a XLSx Worksheet into a Entity Collection
        /// </summary>
        /// <typeparam name="T">Entity Type</typeparam>
        /// <param name="instance"></param>
        /// <param name="fileName"></param>
        /// <param name="sheetNumber"></param>
        /// <returns></returns>
        public List<T> ToCollection<T>(T instance, string fileName, int sheetNumber) {
           
            List<T> result=new List<T> ();
            List<Row> rows = ReadSheet(fileName, sheetNumber);
            if (rows != null && rows.Count> 0)
            {
                Row header = rows[0];
               
                for (int r=1;r<rows.Count ;r++)
                {
                    T itm = (T)instance.GetType().Assembly.CreateInstance(instance.GetType().FullName);

                    for (int c = 0; c < header.Cells.Count; c++ )
                    {
                        try
                        {
                            Cell CELL = rows[r].Cells.Find(Cl => Cl.Column == header.Cells[c].Column);

                            if (CELL != null)
                            {
                                F.Runtime.Reflection.Reflecter.SetPropertyValue(
                                    itm,
                                    header.Cells[c].Data,
                                    Convert.ChangeType(
                                        CELL.Data,
                                        itm.GetType().GetProperty(header.Cells[c].Data).PropertyType
                                    )
                                );
                            }
                        }
                        catch (Exception ex) {
                           
                        }
                    }
                    result.Add (itm);
                }

            }
           

            return result;
        }
        /// <summary>
        /// Read a XLSx Worksheet into a DataTable
        /// </summary>
        /// <param name="fileName">XLSx File Path</param>
        /// <param name="sheetNumber">Number of the Worksheet to read</param>
        /// <returns></returns>
        public System.Data.DataTable ToDataTable(string fileName, int sheetNumber) {
            System.Data.DataTable dt = new System.Data.DataTable();

            List<Row> result= ReadSheet(fileName, sheetNumber);

            if (FirstRowAsColumnsNames)
            {

                if (result != null && result.Count > 1)
                {

                    Row header = result[0];
                    Row firstRow = result[1];

                    if (header.Cells != null && header.Cells.Count > 0
                        && firstRow.Cells != null && firstRow.Cells.Count > 0
                        )
                    {
                        foreach (Cell c in header.Cells)
                        {

                            Cell CELL = firstRow.Cells.Find(Cl => Cl.Column == c.Column);

                            if (CELL != null)
                            {
                                dt.Columns.Add(new System.Data.DataColumn()
                                                {
                                                    ColumnName = c.Data,
                                                    DataType = F.Runtime.Reflection.Reflecter.GetClosestDataType(CELL.Data)
                                                }
                                );

                            }
                        }

                        for (int r = 1; r < result.Count; r++)
                        {
                            var Values = new object[header.Cells.Count];
                            for (int c = 0; c < header.Cells.Count; c++)
                            {

                                Cell CELL = result[r].Cells.Find(Cl => Cl.Column == header.Cells[c].Column);

                                if (CELL != null)
                                {
                                    Values[c] = Convert.ChangeType(
                                        CELL.Data,
                                        dt.Columns[header.Cells[c].Data].DataType
                                        );
                                }
                                else
                                {
                                    Values[c] = null;
                                }

                            }
                            dt.Rows.Add(Values);
                        }
                    }
                }
                else
                    throw new Exception("The ResultSet is not Valid to Build a DataTable. It must have at least two rows.");

            }
            else {


                Row header = result[0];
              

                if (header.Cells != null && header.Cells.Count > 0
                  
                    )
                {
                    for (int c = 0; c < header.Cells.Count;c++ )
                    {
                        dt.Columns.Add(new System.Data.DataColumn()
                        {
                            ColumnName = "Column" + (c+1).ToString (),
                            DataType = F.Runtime.Reflection.Reflecter.GetClosestDataType(header.Cells [c].Data )
                        }
                        );
                    }

                    for (int r = 0; r < result.Count; r++)
                    {
                        var Values = new object[header.Cells.Count];
                        for (int c = 0; c < header.Cells.Count; c++)
                        {
                            Cell CELL = result[r].Cells.Find(Cl => Cl.Column == header.Cells[c].Column);

                            if (CELL != null)
                            {
                                Values[c] = Convert.ChangeType(
                                    CELL.Data,
                                    dt.Columns["Column"+(c+1).ToString ()].DataType
                                    );
                            }
                            else
                            {
                                Values[c] = null;
                            }


                        }
                        dt.Rows.Add(Values);
                    }
                }


            }




            return dt;
        }
        /// <summary>
        /// Reads a XLSX Worksheet getting a Row Collection
        /// </summary>
        /// <param name="fileName">XLSx File Path</param>
        /// <param name="sheetNumber">Number of the Worksheet to read</param>
        /// <returns></returns>
        public List<Row > ReadSheet(string fileName, int sheetNumber)
        {
            List<Row> result = new List<Row>();
            List<Cell> sheetCells = new List<Cell>();
           
            Package xlsxPackage = Package.Open(fileName, FileMode.Open, FileAccess.ReadWrite);
            try
            {
                #region Get File Parts
                PackagePartCollection allParts = xlsxPackage.GetParts();

                PackagePart sharedStringsPart = (from part in allParts
                                                 where part.ContentType.Equals(sharedStringsContentType)
                                                 select part).Single();
                
                XElement sharedStringsElement = XElement.Load(XmlReader.Create(sharedStringsPart.GetStream()));

                Dictionary<int, string> sharedStrings = new Dictionary<int, string>();
                GetSharedStrings(sharedStringsElement, sharedStrings);

                #endregion

                #region Read Sheet
                XElement worksheetElement = GetWorksheet(sheetNumber, allParts);

                IEnumerable<XElement> cells = from c in worksheetElement.Descendants(ExcelNamespaces.excelNamespace + "c")
                                              select c;


                string cellPosition = string.Empty ;
                int index = 0;
                string column = string.Empty ;
                int row = 0;

                #region Parse Cells
                foreach (XElement cell in cells)
                {
                    cellPosition = cell.Attribute("r").Value;
                    index = IndexOfNumber(cellPosition);
                    column = cellPosition.Substring(0, index);
                   
                    row = Convert.ToInt32(cellPosition.Substring(index, cellPosition.Length - index));

                    if (cell.HasElements)
                    {

                        if (cell.Attribute("t") != null && cell.Attribute("t").Value == "s")
                        {
                            // Shared value
                            int valueIndex = Convert.ToInt32(cell.Descendants(ExcelNamespaces.excelNamespace + "v").Single().Value);
                            sheetCells.Add(new Cell(column, row, sharedStrings[valueIndex]));
                        }
                        else
                        {
                            string value = cell.Descendants(ExcelNamespaces.excelNamespace + "v").Single().Value;
                            sheetCells.Add(new Cell(column, row, value));
                        }
                    }
                    else
                    {
                        sheetCells.Add(new Cell(column, row, ""));
                    }

                }
                #endregion

              

                #endregion

            }
            finally
            {
                try
                {
                    xlsxPackage.Close();
                }
                finally  {

                    #region Transform parsed Cells into rows
                    if (sheetCells != null && sheetCells.Count > 0)
                    {


                        int rows = sheetCells.Max(m => m.Row);
                        for (int r = 1; r <= rows; r++)
                        {

                            Row R = new Row(r, sheetCells.FindAll(p => p.Row == r));
                            result.Add(R);
                        }


                    }
                    #endregion
                }

             
            }

            return result  ;
        }
        #endregion

    }
}


Transacciones Fiori

  /UI2/CACHE Register service for UI2 cache use /UI2/CACHE_DEL Delete cache entries /UI2/CHIP Chip Registration /UI2/CUST Customizing of UI ...