Beispiel #1
0
        public static Row[] ParseRows(string sheetXml, WorkbookContext context)
        {
            var reader = XmlReader.Create(new StringReader(sheetXml));

            var(maxRow, maxColumn) = ParseDimension(reader);
            return(ParseCells(reader, maxRow, maxColumn, context));
        }
Beispiel #2
0
        static Row[] ParseCells(XmlReader reader, int maxRow, int maxColumn, WorkbookContext context)
        {
            var rows = new Row[maxRow];

            for (int i = 0; i < maxRow; i++)
            {
                rows[i] = new Row(new Cell[maxColumn]);
            }

            var usedMaxRow    = 0;
            var usedMaxColumn = 0;

            while (reader.ReadToFollowing("c"))
            {
                var    address = reader.GetAttribute("r");
                var    type    = reader.GetAttribute("t");
                var    style   = reader.GetAttribute("s");
                string value   = null;
                if (reader.ReadToDescendant("v") && !reader.IsEmptyElement)
                {
                    value = reader.ReadElementContentAsString();
                }
                var(row, column) = ParsingHelper.ParseAddress(address);
                if (row > usedMaxRow)
                {
                    usedMaxRow = row;
                }
                if (column > usedMaxColumn)
                {
                    usedMaxColumn = column;
                }

                var cellValue = CellParser.Parse(type, style, value, context);
                rows[row - 1][column - 1] = new Cell(cellValue);
            }

            if (usedMaxRow < maxRow || usedMaxColumn < maxColumn)
            {
                rows = TrimUnusedRange(rows, usedMaxRow, usedMaxColumn);
            }

            return(rows);
        }
Beispiel #3
0
        public static object Parse(string type, string style, string value, WorkbookContext context)
        {
            if (value == null)
            {
                return(null);
            }

            if (TryParseByAttribute(type, style, value, context, out var parsedValue))
            {
                return(parsedValue);
            }

            if (floatRE.IsMatch(value))
            {
                if (double.TryParse(value, NumberStyles.Any, CultureInfo.InvariantCulture, out var doubleValue))
                {
                    return(doubleValue == 0.0d ? doubleZero : doubleValue);
                }
                if (decimal.TryParse(value, NumberStyles.Any, CultureInfo.InvariantCulture, out var decimalValue))
                {
                    return(decimalValue == 0.0m ? decimalZero : decimalValue);
                }
                return(value);
            }

            if (intRE.IsMatch(value))
            {
                if (int.TryParse(value, NumberStyles.Any, CultureInfo.InvariantCulture, out var intValue))
                {
                    return(intValue == 0 ? intZero : intValue);
                }
                if (long.TryParse(value, NumberStyles.Any, CultureInfo.InvariantCulture, out var longValue))
                {
                    return(longValue == 0L ? longZero : longValue);
                }
                if (ulong.TryParse(value, NumberStyles.Any, CultureInfo.InvariantCulture, out var ulongValue))
                {
                    return(ulongValue == 0UL ? ulongZero : ulongValue);
                }
            }

            return(value);
        }
Beispiel #4
0
        static bool TryParseByAttribute(string type, string style, string value, WorkbookContext context, out object parsedValue)
        {
            parsedValue = null;
            if (!string.IsNullOrEmpty(type))
            {
                switch (type)
                {
                // t="s" 는 값 문자열이 공유 문자열 인덱스이다.
                case "s":
                    parsedValue = context.SharedStrings[int.Parse(value)];
                    return(true);

                // t="b" 는 값 문자열을 논리값으로 해석한다. (0: false, 1:true)
                case "b":
                    parsedValue = value != "0" ? trueValue : falseValue;
                    return(true);
                }
            }

            // s="1" 에서 숫자는 공유 스타일 인덱스이다.
            if (!string.IsNullOrEmpty(style))
            {
                var styleIndex = int.Parse(style);
                var styleObj   = context.Styles[styleIndex];
                switch (styleObj.NumberFormat)
                {
                // 스타일의 숫자형식(numFmtId)이 DateTime(14)인 것은 날짜로 해석한다.
                case NumberFormat.DateTime:
                {
                    var dateTimeValue = double.Parse(value);
                    parsedValue = DateTime.FromOADate(dateTimeValue);
                    return(true);
                }
                }
            }

            return(false);
        }
Beispiel #5
0
 internal Worksheet(int index, string name, WorkbookContext context)
 {
     Index        = index;
     Name         = name;
     this.context = context;
 }
Beispiel #6
0
 internal Workbook(WorkbookContext context)
 {
     this.context = context;
     worksheets   = context.SheetNames.Select((name, index) => new Worksheet(index, name, this.context)).ToArray();
 }