Skip to content

throw null exception when parse int arrays with only 1item in ExcelQueryClass #91

@lazism

Description

@lazism

Hello. I have been using ExcelParse temporarily since the api v3 version deprecated.

I found that ExcelQuery class throws null exception when there is only one item in the int array.

ExcelQuery.cs -> Line 272 - 288

    /// <summary>
    /// Convert type of cell value to its predefined type which is specified in the sheet's ScriptMachine setting file.
    /// </summary>
    protected object ConvertFrom(ICell cell, Type t)
    {
        object value = null;

        if (t == typeof(float) || t == typeof(double) || t == typeof(short) || t == typeof(int) || t == typeof(long))
        {
            if (cell.CellType == NPOI.SS.UserModel.CellType.Numeric)
            {
                value = cell.NumericCellValue;
            }
            else if (cell.CellType == NPOI.SS.UserModel.CellType.String)
            {
                //Get correct numeric value even the cell is string type but defined with a numeric type in a data class.
                if (t == typeof(float))
                    value = Convert.ToSingle(cell.StringCellValue);
                if (t == typeof(double))
                    value = Convert.ToDouble(cell.StringCellValue);
                if (t == typeof(short))
                    value = Convert.ToInt16(cell.StringCellValue);
                if (t == typeof(int))
                    value = Convert.ToInt32(cell.StringCellValue);
                if (t == typeof(long))
                    value = Convert.ToInt64(cell.StringCellValue);
            }
            else if (cell.CellType == NPOI.SS.UserModel.CellType.Formula)
            {
                // Get value even if cell is a formula
                if (t == typeof(float))
                    value = Convert.ToSingle(cell.NumericCellValue);
                if (t == typeof(double))
                    value = Convert.ToDouble(cell.NumericCellValue);
                if (t == typeof(short))
                    value = Convert.ToInt16(cell.NumericCellValue);
                if (t == typeof(int))
                    value = Convert.ToInt32(cell.NumericCellValue);
                if (t == typeof(long))
                    value = Convert.ToInt64(cell.NumericCellValue);
            }
        }
        else if (t == typeof(string) || t.IsArray)
        {
            // HACK: handles the case that a cell contains numeric value
            //       but a member field in a data class is defined as string type.
            //       e.g. string s = "123"
            if (cell.CellType == NPOI.SS.UserModel.CellType.Numeric)
                value = cell.NumericCellValue;
            else
                value = cell.StringCellValue;
        }
        else if (t == typeof(bool))
            value = cell.BooleanCellValue;

        if (t.IsGenericType && t.GetGenericTypeDefinition().Equals(typeof(Nullable<>)))
        {
            var nc = new NullableConverter(t);
            return nc.ConvertFrom(value);
        }

        if (t.IsEnum)
        {
            // for enum type, first get value by string then convert it to enum.
            value = cell.StringCellValue;
            return Enum.Parse(t, value.ToString(), true);
        }
        else if (t.IsArray)
        {
            if (t.GetElementType() == typeof(float))
                return ConvertExt.ToSingleArray((string)value);

            if (t.GetElementType() == typeof(double))
                return ConvertExt.ToDoubleArray((string)value);

            if (t.GetElementType() == typeof(short))
                return ConvertExt.ToInt16Array((string)value);

            if (t.GetElementType() == typeof(int))
                return ConvertExt.ToInt32Array((string)value);

            if (t.GetElementType() == typeof(long))
                return ConvertExt.ToInt64Array((string)value);

            if (t.GetElementType() == typeof(string))
                return ConvertExt.ToStringArray((string)value);
        }

        // for all other types, convert its corresponding type.
        return Convert.ChangeType(value, t);
    }
}

Forced (string)value conversion is not allowed in the code if there is only one item.
I temporarily modified the code to value.ToString() and now the code has not thrown NullException.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions