C# MVC Amount of Rows in Excel? - c#

I have a piece of code below - which is looping through an Excel workbook adding the data to an SQL Database - However the forloop doesn't stop when the data runs out.
int rowCount = worksheet.Rows.Count -1;
for (int i = 3; i < rowCount; i++ )
{
Spreadsheet spreadsheetToSave = new Spreadsheet();
Estimate estimateToSave = new Estimate();
RAA raaToSave = new RAA();
spreadsheetToSave.Phases = worksheet.Cells[4, i].Value;
spreadsheetToSave.Deliverables = worksheet.Cells[5, i].Value;
if (worksheet.Cells[6,i].Value == "Y")
{
spreadsheetToSave.Scope = true;
}
else
{
spreadsheetToSave.Scope = false;
}
spreadsheetToSave.Description = worksheet.Cells[7, i].Value;
//estimateToSave.Estimate1 = Convert.ToDecimal(worksheet.Cells[8, i].Value);
//estimateToSave.Estimate2 = Convert.ToDecimal(worksheet.Cells[9, i].Value);
//estimateToSave.Estimate3 = Convert.ToDecimal(worksheet.Cells[10, i].Value);
estimateToSave.Estimate1 = 1;
estimateToSave.Estimate2 = 1;
estimateToSave.Estimate3 = 1;
spreadsheetToSave.Estimate = estimateToSave;
db.Spreadsheet.Add(spreadsheetToSave);
Can anyone help?
Thanks :)

Try replacing your first two lines of code with this:
int rowCount = worksheet.UsedRange.Rows.Count;
for (int i = 3; i <= rowCount; i++)
This loops from row 3 to the last filled row.
Also you should check the rest of your code: as far as is know in
worksheet.Cells[rowIndex, columnIndex]
the rowIndex comes first :)

Related

C# ReoGrid performance issue when binding datatable with formula

I have populated my data table with random values and formula like =SUM(A1:A2)
when there is 150 columns and 4000 rows in datatable then ReoGrid taking approx 20 minute to be populated.
when i am populating ReoGrid without formula then it takes few second to populate ReoGrid but the moment many SUM formulas are being assigned to cell dynamically then ReoGrid take long time to populated.
Here i am sharing my code. so my request please guys see my code logic and tell me is there any flaw when assigning formula to many cell of ReoGrid.
please tell me how could i simplify the logic to populate grid with formula. Is there way to increase the performance of my code with formula as a result ReoGrid can be populated with in few sec or few minute.
Looking for suggestion and guide line. ReoGrid is free component for winform application https://reogrid.net/.
Here is my code
private void btnBindTable_Click(object sender, EventArgs e)
{
Stopwatch stopwatch = new Stopwatch();
stopwatch.Start();
string strSum = "", strColName, strImmediateOneUp = "", strImmediateTwoUp = "";
int startsum = 0;
int currow = 0;
bool firstTimeSum = true;
int NumRows = 4000;
int NumColumns = 150;
var sheet = reoGrd.CurrentWorksheet;
sheet.Resize(NumRows, NumColumns); // resize
DataTable dt = new DataTable();
for (int col = 0; col < NumColumns; col++)
{
strColName = GenerateColumnText(col);
DataColumn datacol = new DataColumn(strColName, typeof(string));
dt.Columns.Add(datacol);
}
for (int row = 0; row < NumRows; row++)
{
dt.Rows.Add();
for (int col = 0; col < NumColumns; col++)
{
if (row < 2)
{
dt.Rows[row][col] = new Random().Next(1, NumRows).ToString("D2");
}
else
{
if (firstTimeSum)
{
if (row - currow == 2)
{
currow = row;
startsum = 0;
firstTimeSum = false;
}
else
{
startsum = 1;
}
}
else
{
if (row - currow == 3)
{
currow = row;
startsum = 0;
}
}
if (startsum == 0)
{
strColName = GenerateColumnText(col);
strImmediateOneUp = strColName + ((row + 1) - 1).ToString();
strImmediateTwoUp = strColName + ((row + 1) - 2).ToString();
dt.Rows[row][col] = strSum;
string cellname = GenerateColumnText(col) + (row + 1).ToString();
var cell = sheet.Cells[cellname];
cell.Style.BackColor = Color.LightGoldenrodYellow;
}
else
{
dt.Rows[row][col] = new Random().Next(1, NumRows).ToString("D2");
}
}
}
startsum = 1;
}
sheet["A1"] = dt;
stopwatch.Stop();
TimeSpan timeSpan = stopwatch.Elapsed;
MessageBox.Show(string.Format("Time elapsed: {0}h {1}m {2}s {3}ms", timeSpan.Hours, timeSpan.Minutes, timeSpan.Seconds, timeSpan.Milliseconds));
}

How to color specific row in excel table?

I create excel file using NPOI dll's.
I have this code that create excel table from List<someObjects> :
IWorkbook workbook = new XSSFWorkbook();
ISheet sheet1 = workbook.CreateSheet("Sheet 1");
IRow header = sheet1.CreateRow(0);
header.CreateCell(0).SetCellValue("Id");
header.CreateCell(1).SetCellValue("Name");
header.CreateCell(2).SetCellValue("E-Mail");
header.CreateCell(3).SetCellValue("PhoneNumber");
for (int i = 0; i < list.Count(); i++)
{
IRow row = sheet1.CreateRow(i + 1);
row.CreateCell(0).SetCellValue(list[i].id);
row.CreateCell(1).SetCellValue(list[i].name);
row.CreateCell(2).SetCellValue(list[i].email);
row.CreateCell(3).SetCellValue(list[i].phoneNumber);
}
Then I make each cell bordered in the table created above.
Here is the code:
public void setBorderExcel()
{
XSSFCellStyle myStyle = (XSSFCellStyle)workbook.CreateCellStyle();
myStyle.BorderBottom = BorderStyle.Medium;
myStyle.BorderTop = BorderStyle.Medium;
myStyle.BorderLeft = BorderStyle.Medium;
myStyle.BorderRight = BorderStyle.Medium;
for (int i = 0; i < 7; i++)
{
for (int j = 0; j < 4; j++)
{
workbook.GetSheetAt(0).GetRow(i).GetCell(j).CellStyle = myStyle;
}
}
}
Then I make each odd row in the table created above colored.
Here is the code:
public void setColorExcel()
{
for (int i = 0; i < 7; i++)
{
for (int j = 0; j < 4; j++)
{
if (i % 2 == 0) continue;
workbook.GetSheetAt(0).GetRow(i).GetCell(j).CellStyle.FillForegroundColor = HSSFColor.Grey25Percent.Index;
workbook.GetSheetAt(0).GetRow(i).GetCell(j).CellStyle.FillPattern = FillPattern.SolidForeground;
}
}
}
And here is the result that I get:
As you can see the color applied to all rows in the table while, I wanted to color only the odd rows.
My question is why I get colored all rows? And how can I make colored only specific rows?
I think I understand it. You have applied the same XSSFCellStyle instance to all cells' Style property in (setBorderExcel). So, now they all have the same instance, so when you change a property on the CellStyle of one of the cells, it's changing the CellStyle instance which is associated with all cells.
You'll most likely need two XSSFCellStyle instances. One for odd rows and another for even rows.
I tried it out, and although I'm not sure why your way doesn't work, there is an easier way with less lines (simply declare another CellStyle with grey background, and use that instead of myStyle):
XSSFCellStyle myStyle = (XSSFCellStyle)workbook.CreateCellStyle();
myStyle.BorderBottom = BorderStyle.Medium;
myStyle.BorderTop = BorderStyle.Medium;
myStyle.BorderLeft = BorderStyle.Medium;
myStyle.BorderRight = BorderStyle.Medium;
XSSFCellStyle myStyleGrey = (XSSFCellStyle)workbook.CreateCellStyle();
myStyleGrey.BorderBottom = BorderStyle.Medium;
myStyleGrey.BorderTop = BorderStyle.Medium;
myStyleGrey.BorderLeft = BorderStyle.Medium;
myStyleGrey.BorderRight = BorderStyle.Medium;
myStyleGrey.FillForegroundColor = HSSFColor.Grey25Percent.Index;
myStyleGrey.FillPattern = FillPattern.SolidForeground;
for (int i = 0; i < 7; i++)
{
for (int j = 0; j < 4; j++)
{
if (i % 2 == 0)
workbook.GetSheetAt(0).GetRow(i).GetCell(j).CellStyle = myStyle;
else
workbook.GetSheetAt(0).GetRow(i).GetCell(j).CellStyle = myStyleGrey;
}
}
You can remove your code for setColorExcel() and it should work as expected, setting odd rows to grey.

DataGridview Cells are not filled

for (int i = 0; i <= x; i++)
{
for (int k = 0; k <= TimeSub; k++)
{
dataGridView1.Rows.Add(FromDate); // hour
dataGridView1.Rows[k].Cells[1].Value = FromTime;
FromTime = FromTime + 1;
}
FromDate=FromDate.AddDays(1);
}
While I am executing this statement all the rows are filled correctly but the cells are not. Kindly help on this.
You are always looping from the first row in the second loop.
Rows.Add retruns the new row index.
Try this instead:
var rowIndex = dataGridView1.Rows.Add(FromDate); // hour
dataGridView1.Rows[rowIndex].Cells[1].Value = FromTime;

How to merge first 3 columns for rows with same value in PDF

I'm using itextSharp to export a DataTable to a pdf table. I can export the data to a pdf table using the sample code i have posted below. The DataTable contains close to 21 columns.
The first column in the pdf (DataTable) might contain similar values for any number of rows. If the data values in first column for a group of rows is similar, i want to merge the first 3 columns of those rows as one cell.
I'm having trouble modifying the code below to achieve this.
public iTextSharp.text.Table GetItextTable(DataTable dtChartData, string reportType)
{
int intCols = dtChartData.Columns.Count; //Total number of columns
int intRows = dtChartData.Rows.Count; //Total number of rows
iTextSharp.text.Table pdfTable = new iTextSharp.text.Table(intCols, intRows);
try
{
pdfTable.BorderWidth = 1;
pdfTable.Width = 100;
pdfTable.Padding = 1;
pdfTable.Spacing = 1;
/*creating table headers */
for (int i = 0; i < intCols; i++)
{
iTextSharp.text.Cell cellCols = new iTextSharp.text.Cell();
iTextSharp.text.Font ColFont = iTextSharp.text.FontFactory.GetFont("Tahoma", 07,
iTextSharp.text.Font.BOLD);
for (int l = 0; l < dtChartData.Columns.Count; l++)
{
if (dtChartData.Columns[l].ColumnName.Contains("_"))
{
dtChartData.Columns[l].ColumnName = dtChartData.Columns[l].ColumnName.Replace("_", " ");
}
}
iTextSharp.text.Chunk chunkCols = new iTextSharp.text.Chunk(dtChartData.Columns[i].ColumnName,ColFont);
cellCols.HorizontalAlignment = iTextSharp.text.Element.ALIGN_CENTER;
if ((chunkCols.ToString().ToLower() == "ReportDetails"))
{
cellCols.HorizontalAlignment = iTextSharp.text.Element.ALIGN_CENTER;
}
}
/* loop that take values from every row in datatable and insert in itextsharp table */
for (int k = 0; k < intRows; k++)
{
for (int j = 0; j < intCols; j++)
{
iTextSharp.text.Cell cellRows = new iTextSharp.text.Cell();
iTextSharp.text.Font RowFont = iTextSharp.text.FontFactory.GetFont("Tahoma", 07);
iTextSharp.text.Chunk chunkRows = new iTextSharp.text.Chunk(dtChartData.Rows[k][j].ToString(),RowFont);
cellRows.HorizontalAlignment = iTextSharp.text.Element.ALIGN_CENTER;
cellRows.Add(chunkRows);
pdfTable.AddCell(cellRows);
}
}
}
catch (Exception ex)
{
//error handling code here removed
}
return pdfTable;
}
Have you tried to change the Colspan?
iTextSharp.text.Cell cell = new iTextSharp.text.Cell();
cell.AddElement(new Paragraph("colspan 3"));
cell.Colspan = 3;
table.AddCell(cell);
In this case, cell will span three columns.
try this. i just edited your code, not checked
here i have edited 1 line of your code and added a new line (total 2 lines of change only).
dont forget to combine headding row like this, if you need
/* loop that take values from every row in datatable and insert in itextsharp table */
for (int k = 0; k < intRows; k++)
{
for (int j = 2; j < intCols; j++)// EDIT: if all first 3 cols are same, then starts with 2
{
iTextSharp.text.Cell cellRows = new iTextSharp.text.Cell();
if(j == 2) cellRows.Colspan = 3;// ADD: it'll gives a 3 times long cell
iTextSharp.text.Font RowFont = iTextSharp.text.FontFactory.GetFont("Tahoma", 07);
iTextSharp.text.Chunk chunkRows = new iTextSharp.text.Chunk(dtChartData.Rows[k][j].ToString(),RowFont);
cellRows.HorizontalAlignment = iTextSharp.text.Element.ALIGN_CENTER;
cellRows.Add(chunkRows);
pdfTable.AddCell(cellRows);
}
}

Dynamic DataGridView creation columns and rows not coming in winform using c#

i am trying to create a 8*8 gridview but the columns & rows aren't coming .. my code is like this ..
public static DataGridView[] grid = new DataGridView[30];
public DataGridViewImageColumn col;
grid[i] = new DataGridView();
grid[i].Visible = true;
grid[i].AllowUserToAddRows = false;
grid[i].AllowUserToDeleteRows = false;
grid[i].AllowUserToOrderColumns = false;
grid[i].AllowUserToResizeRows = false;
grid[i].AllowUserToResizeColumns = false;
grid[i].ColumnHeadersVisible = false;
grid[i].RowHeadersVisible = false;
grid[i].Location = new System.Drawing.Point(120,5);
grid[i].Size = new System.Drawing.Size(128, 128);
grid[i].BackgroundColor = Color.SeaShell;
grid[i].GridColor = Color.Green;
grid[i].ClipboardCopyMode = DataGridViewClipboardCopyMode.EnableWithoutHeaderText;
grid[i].CellBorderStyle = DataGridViewCellBorderStyle.Single;
for (j = 1; j <= 8; j++)
{
col = new DataGridViewImageColumn();
col.Width = 2;
col.ImageLayout = DataGridViewImageCellLayout.Normal;
grid[i].Columns.Add(col);
}
for (k = 1; k <= 8; k++)
{
grid[i].Rows.Add();
}
epnl[i].Controls.Add(grid[i]);
here epnl is a panel. i am trying to set the height of every cell as 2 and width as 2 as well but the cells are not coming .. i am only getting an empty datagridview pls help
This is basically because your not adding anything.
You need to create Row object :-
DataGridViewRow row = new DataGridViewRow();
for (k = 1; k <= 8; k++)
{
grid[i].Rows.Add(row);
}
I think this should help.

Categories

Resources