I am trying to read date cell from Excel file:
private string GetDateValueFromRowOrNull(ISheet worksheet, int row, int column, StringBuilder exceptionMessage, CellType? cellType = null)
{
var cell = worksheet.GetRow(row).GetCell(column);
if (cell == null)
{
return string.Empty;
}
if (cellType != null)
{
cell.SetCellType(cellType.Value);
}
var cellValue = worksheet.GetRow(row).GetCell(column).DateCellValue;
if (cellValue != null)
{
return cellValue;
}
return String.Empty;
}
But I am getting an error while trying to return the cellValue:
Can not implicitly convert type System.DateTime to string
if (cellValue != null)
{
return cellValue;
}
I am using NPOI for the Excel functions.
You can read the datetime value as string from excel then convert it to a DateTime object.
Sample converter code:
public static DateTime GetDateTime(string day, string month, string year)
{
try
{
return Convert.ToDateTime(string.Format("{0} {1}, {2}", (object)day, (object)month, (object)year));
}
catch (Exception ex)
{
throw ex;
}
}
If you require a DateTime to be returned from your method you need to change the method signature to return DateTime instead of string. Given the possibility of a null value, I also suggest you actually return a nullable date and make sure callers of this method handle nulls the same way you were expecting them to handle empty string:
private DateTime? GetDateValueFromRowOrNull(ISheet worksheet, int row, int column, StringBuilder exceptionMessage, CellType? cellType = null)
{
var cell = worksheet.GetRow(row).GetCell(column);
if (cell == null)
{
return null;
}
if (cellType != null)
{
cell.SetCellType(cellType.Value);
}
var cellValue = worksheet.GetRow(row).GetCell(column).DateCellValue;
if (cellValue != null)
{
return cellValue;
}
return null;
}
I have sorted it. #Fredy’s comment was right.
var cellValue = worksheet.GetRow(row).GetCell(column).DateCellValue;
if (cellValue != null)
{
return cellValue.ToString();
}
Related
I have a fixed length string ABCDEFGHIJK, is there a way to convert this into AB-CDEFGHIJ-K using string format?
var s = "ABCDEFGHIJK";
Console.WriteLine($"{s[..2]}-{s[2..10]}-{s[^1..]}");
I have a fixed length string ABCDEFGHIJK, is there a way to convert
this into AB-CDEFGHIJ-K using string format?
Focusing on the "string format" part, we can implement IFormatProvider. This will format the string if it is EXACTLY eleven characters long, otherwise it just returns the same string back. Following the example, the "H" format stands for "hypenated":
private void button1_Click_2(object sender, EventArgs e)
{
string input = "ABCDEFGHIJK";
string output = String.Format(new MyStringFormat(), "Formatted: {0:H}", input);
Console.WriteLine(input);
Console.WriteLine(output);
}
public class MyStringFormat : IFormatProvider, ICustomFormatter
{
object IFormatProvider.GetFormat(Type formatType)
{
if (formatType == typeof(ICustomFormatter))
{
return this;
}
else
{
return null;
}
}
string ICustomFormatter.Format(string format, object arg, IFormatProvider formatProvider)
{
if (arg.GetType() != typeof(String))
{
try
{
return HandleOtherFormats(format, arg);
}
catch (FormatException e)
{
throw new FormatException(String.Format("The format of '{0}' is invalid.", format), e);
}
}
string ufmt = format.ToUpper(CultureInfo.InvariantCulture);
if (ufmt != "H")
{
try
{
return HandleOtherFormats(format, arg);
}
catch (FormatException e)
{
throw new FormatException(String.Format("The format of '{0}' is invalid.", format), e);
}
}
string result = arg.ToString();
if (result.Length != 11)
return result;
else
return result.Insert(2, "-").Insert(11, "-"); // see comment by Hans Passant!
}
private string HandleOtherFormats(string format, object arg)
{
if (arg is IFormattable)
return ((IFormattable)arg).ToString(format, CultureInfo.CurrentCulture);
else if (arg != null)
return arg.ToString();
else
return String.Empty;
}
}
howabout
var newstring = String.format("{0}-{1}-{2}", s.Substring(0,2), s.Substring(3,7), s.Substring(10,1))
you could also use interpolation and the new range stuff
var f = Regex.Replace("ABCDEFGHIJK", "^(..)(.*)(.)$", "$1-$2-$3");
...yeah, I know.
Also, dropping the {2}, etc. was inspired by Yuriy's answer here.
The Rube Goldberg way perhaps:
static void Main(string[] args)
{
string code = "ABCDEFGHIJK";
string mask = "##-########-#";
Console.WriteLine(code.Format(mask));
// AB-CDEFGHIJ-K
}
public static string Format(this string code, string mask, char token = '#')
{
StringBuilder sb = new StringBuilder(mask.Length);
int index = 0;
foreach (var item in mask)
{
if (item==token)
{
sb.Append(code[index++]);
}
else
{
sb.Append(item);
}
}
return sb.ToString();
}
Edit 1
replaced the space ' ' character placeholder with the pound sign '#' for better clarity.
I have method to convertDatefromExcelToSQL which take date value from excel file and convert it to exact format "yyyy-MM-dd"
the problem occured when date format in the PC different from the formate i declared
I want to modify my method to detect date format and convert it to exact format "yyyy-MM-dd"
public static string convertDatefromExcelToSQL(string excelDate)
{
string sdat = "";
DateTime dat;
sdat = ((string.IsNullOrEmpty(excelDate)) ? sdat : excelDate);
if (MIB.IsDouble(sdat))
{
dat = DateTime.FromOADate(double.Parse(sdat));
}
else
{
if (sdat.Contains(":"))
{
sdat = sdat.Split(' ')[0];
}
dat = DateTime.ParseExact(sdat, "dd/MM/yyyy", CultureInfo.InvariantCulture);
}
return dat.ToString("yyyy-MM-dd");
}
public static bool IsDouble(string text)
{
Double num = 0;
bool isDouble = false;
// Check for empty string.
if (string.IsNullOrEmpty(text))
{
return false;
}
isDouble = Double.TryParse(text, out num);
return isDouble;
}
public static string CDtStr(object v)
{
string lReturnValue = string.Empty;
DateTime lOutDateTime = new DateTime();
if (v != null)
{
if (v != DBNull.Value)
{
if (DateTime.TryParse(v.ToString(), out lOutDateTime))
lReturnValue = lOutDateTime.ToString("yyyy-MM-dd");
}
}
return lReturnValue;
}
protected void gv_card_RowUpdating(object sender, GridViewUpdateEventArgs e)
{
int result = 0;
CreditCard prod = new CreditCard();
GridViewRow row = gv_card.Rows[e.RowIndex];
string id = gv_card.DataKeys[e.RowIndex].Value.ToString();
string tid = ((TextBox)row.Cells[0].Controls[0]).Text;
string tnumber = ((TextBox)row.Cells[1].Controls[0]).Text;
string texpirydate = ((TextBox)row.Cells[2].Controls[0]).Text;
string tcvv = ((TextBox)row.Cells[3].Controls[0]).Text;
string tcardtype = ((TextBox)row.Cells[4].Controls[0]).Text;
string tholdername = ((TextBox)row.Cells[5].Controls[0]).Text;
result = prod.CardUpdate(int.Parse(tid), tholdername, tnumber,texpirydate, int.Parse(tcvv), tcardtype );
if (result > 0)
{
Response.Write("<script>alert('Product updated successfully');</script>");
}
else
{
Response.Write("<script>alert('Product NOT updated');</script>");
}
gv_card.EditIndex = -1;
bind();
}
}
Above is my Code but it just cant seem to update my gridview
That message is likely coming from your call to int.Parse(string), which expects the string to be a valid integer. To handle this, you can instead use int.TryParse(string, out int), which will return true or false if it is able to parse the string. If it's successful, the out parameter will contain the parsed integer value.
So you would first try to parse the integer fields. If that fails you could return an error message, and if it succeeds then you can use the integers directly in your call to CardUpdate:
int tidValue;
int tcvvValue;
if (!int.TryParse(tid, out tidValue))
{
Response.Write("<script>alert('The value specified for TID is not an integer.');</script>");
}
else if (!int.TryParse(tcvv, out tcvvValue))
{
Response.Write("<script>alert('The value specified for TCVV is not an integer.');</script>");
}
else
{
result = prod.CardUpdate(tidValue, tholdername, tnumber, texpirydate, tcvvValue, tcardtype);
if (result > 0)
{
Response.Write("<script>alert('Product updated successfully');</script>");
}
else
{
Response.Write("<script>alert('Product NOT updated');</script>");
}
}
Using NPOI, is there any buildin possibility to format a cell value (especially numeric and date values) as it has been formatted by Excel?
If not what would be the best way to implement it? I thought of a formatstring converter from Excel-formatstrings to C#-formatstrings?
The following example assumes the Excel-formatstring and the C#-formatstring are the same. So it works for some basic formatstrings like: "#,##0.00"
using NPOI.SS.UserModel;
ICell cell = workbook.GetSheet("table1").GetRow(0).GetCell(0);
string value = null;
if(cell.CellType == CellType.String) {
value = cell.StringCellValue;
} else if(cell.CellType == CellType.Numeric) {
string formatString = cell.CellStyle.GetDataFormatString();
if(DateUtil.IsCellDateFormatted(cell)) {
value = cell.DateCellValue.ToString(formatString);
} else {
value = cell.NumericCellValue.ToString(formatString);
}
} else [...]
Found the NPOI built in possibility. However some formats like "Sunday, September 18, 1983" are evaluated like "EEEE, September 18, 1983".
using NPOI.SS.UserModel;
DataFormatter dataFormatter = new DataFormatter(CultureInfo.CurrentCulture);
ICell cell = workbook.GetSheet("table1").GetRow(0).GetCell(0);
string value = dataFormatter.FormatCellValue(cell);
private static CellValue EvaluateFormulaCellValue(XSSFWorkbook wb, ICell cell)
{
WorkbookEvaluator _bookEvaluator = null;
_bookEvaluator = new WorkbookEvaluator(XSSFEvaluationWorkbook.Create(wb), null, null);
// XSSFFormulaEvaluator.EvaluateAllFormulaCells(wb);
ValueEval eval = _bookEvaluator.Evaluate(new XSSFEvaluationCell((XSSFCell)cell));
if (eval is NumberEval)
{
NumberEval ne = (NumberEval)eval;
return new NPOI.SS.UserModel.CellValue(ne.NumberValue);
}
if (eval is BoolEval)
{
BoolEval be = (BoolEval)eval;
return NPOI.SS.UserModel.CellValue.ValueOf(be.BooleanValue);
}
if (eval is StringEval)
{
StringEval ne = (StringEval)eval;
return new NPOI.SS.UserModel.CellValue(ne.StringValue);
}
if (eval is ErrorEval)
{
return NPOI.SS.UserModel.CellValue.GetError(((ErrorEval)eval).ErrorCode);
}
throw new InvalidOperationException("Unexpected eval class (" + eval.GetType().Name + ")");
}
I am having a DataGridView and an Add New Entry button. Each time I add a new entry to the database, I want the program to select the row of the new entry in the DataGridView. After clicking on the Add New Entry button, the below function will be called, with parameters of studentName and date passed to the function. The name of the DataGridView is dvgPontengHistory.
But there is an exception thrown:
Object reference not set to an instance of an object.
on this line:
if(r.Cells["student_name"].Value.ToString().Contains(studentName))
Below is the code:
private void selectRow(string studentName, string date)
{
int i = 0;
foreach (DataGridViewRow r in dgvPontengHistory.Rows)
{
if(r.Cells["student_name"].Value.ToString().Contains(studentName)) // error in this line
{
if (r.Cells["date"].Value.ToString().Contains(date))
{
dgvPontengHistory.Rows[i].Selected = true;
return;
}
}
i++;
}
}
Any tips on resolving this problem? Thanks.
Probably the case that student_name was null in on of the rows in the result set. That would cause ToString() to fail.
My guess is your update statement is putting null into your table.
Here is how you test:
(set breakpoints on the throw lines).
private void selectRow(string studentName, string date)
{
int i = 0;
foreach (DataGridViewRow r in dgvPontengHistory.Rows)
{
if (r.Cells["student_name"] == null) { throw("can't find cell"); }
if(r.Cells["student_name"].Value == null) { throw("cell has no value"); }
if(r.Cells["student_name"].Value.ToString().Contains(studentName)) // error in this line
{
if (r.Cells["date"].Value.ToString().Contains(date))
{
dgvPontengHistory.Rows[i].Selected = true;
return;
}
}
i++;
}
}
private void selectRow(string studentName, string date)
{
int i = 0;
foreach (DataGridViewRow r in dgvPontengHistory.Rows)
{
if(r.Cells["student_name"].Value == null) return;
if(r.Cells["student_name"].Value.ToString().Contains(studentName)) // error in this line
{
if (r.Cells["date"].Value.ToString().Contains(date))
{
dgvPontengHistory.Rows[i].Selected = true;
return;
}
}
i++;
}
}