private void WriteCell(MiniExcelStreamWriter writer, int rowIndex, int cellIndex, object value, ExcelColumnInfo p) { var v = string.Empty; var t = "str"; var s = "2"; if (value == null) { v = ""; } else if (value is string str) { v = ExcelOpenXmlUtils.EncodeXML(str); } else if (p?.ExcelFormat != null && value is IFormattable formattableValue) { var formattedStr = formattableValue.ToString(p.ExcelFormat, _configuration.Culture); v = ExcelOpenXmlUtils.EncodeXML(formattedStr); } else { Type type = null; if (p == null || p.Key != null) { // TODO: need to optimize // Dictionary need to check type every time, so it's slow.. type = value.GetType(); type = Nullable.GetUnderlyingType(type) ?? type; } else { type = p.ExcludeNullableType; //sometime it doesn't need to re-get type like prop } if (type.IsEnum) { t = "str"; var description = CustomPropertyHelper.DescriptionAttr(type, value); //TODO: need to optimze if (description != null) { v = description; } else { v = value.ToString(); } } else if (TypeHelper.IsNumericType(type)) { if (_configuration.Culture != CultureInfo.InvariantCulture) { t = "str"; //TODO: add style format } else { t = "n"; } if (type.IsAssignableFrom(typeof(decimal))) { v = ((decimal)value).ToString(_configuration.Culture); } else if (type.IsAssignableFrom(typeof(Int32))) { v = ((Int32)value).ToString(_configuration.Culture); } else if (type.IsAssignableFrom(typeof(Double))) { v = ((Double)value).ToString(_configuration.Culture); } else if (type.IsAssignableFrom(typeof(Int64))) { v = ((Int64)value).ToString(_configuration.Culture); } else if (type.IsAssignableFrom(typeof(UInt32))) { v = ((UInt32)value).ToString(_configuration.Culture); } else if (type.IsAssignableFrom(typeof(UInt16))) { v = ((UInt16)value).ToString(_configuration.Culture); } else if (type.IsAssignableFrom(typeof(UInt64))) { v = ((UInt64)value).ToString(_configuration.Culture); } else if (type.IsAssignableFrom(typeof(Int16))) { v = ((Int16)value).ToString(_configuration.Culture); } else if (type.IsAssignableFrom(typeof(Single))) { v = ((Single)value).ToString(_configuration.Culture); } else if (type.IsAssignableFrom(typeof(Single))) { v = ((Single)value).ToString(_configuration.Culture); } else { v = (decimal.Parse(value.ToString())).ToString(_configuration.Culture); } } else if (type == typeof(bool)) { t = "b"; v = (bool)value ? "1" : "0"; } else if (type == typeof(byte[]) && _configuration.EnableConvertByteArray) { var bytes = (byte[])value; if (bytes != null) { // TODO: Setting configuration because it might have high cost? var format = ImageHelper.GetImageFormat(bytes); //it can't insert to zip first to avoid cache image to memory //because sheet xml is opening.. https://github.com/shps951023/MiniExcel/issues/304#issuecomment-1017031691 //int rowIndex, int cellIndex var file = new FileDto() { Byte = bytes, RowIndex = rowIndex, CellIndex = cellIndex, SheetId = currentSheetIndex }; if (format != ImageFormat.unknown) { file.Extension = format.ToString(); file.IsImage = true; } else { file.Extension = "bin"; } _files.Add(file); //TODO:Convert to base64 var base64 = $"@@@fileid@@@,{file.Path}"; v = ExcelOpenXmlUtils.EncodeXML(base64); s = "4"; } } else if (type == typeof(DateTime)) { if (_configuration.Culture != CultureInfo.InvariantCulture) { t = "str"; v = ((DateTime)value).ToString(_configuration.Culture); } else if (p == null || p.ExcelFormat == null) { t = null; s = "3"; v = ((DateTime)value).ToOADate().ToString(CultureInfo.InvariantCulture); } else { // TODO: now it'll lose date type information t = "str"; v = ((DateTime)value).ToString(p.ExcelFormat, _configuration.Culture); } } else { //TODO: _configuration.Culture v = ExcelOpenXmlUtils.EncodeXML(value.ToString()); } } var columname = ExcelOpenXmlUtils.ConvertXyToCell(cellIndex, rowIndex); if (v != null && (v.StartsWith(" ", StringComparison.Ordinal) || v.EndsWith(" ", StringComparison.Ordinal))) /*Prefix and suffix blank space will lost after SaveAs #294*/ { writer.Write($"<x:c r=\"{columname}\" {(t == null ? "" : $"t =\"{t}\"")} s=\"{s}\" xml:space=\"preserve\"><x:v>{v}</x:v></x:c>");