I have a listbox and I manage to bind the Excel worksheet to the list box (after hours of researching on the Internet).
Now I need to read the values from the sheet into the listbox, but unable to locate any suitable solution.
This is what I have done so far:-
private void LoadExcelSheet(string path, int sheet){
_Application excel = new Excel.Application();
Workbook wb;
Worksheet ws;
int row = 0;
int col = 0;
wb = excel.Workbooks.Open(path);
ws = wb.Worksheets[sheet];
for (row = 1; row < 10; row++){
for (col = 1; col < 6; col++){
listBox1.Items.Add(ws.Cells[row, col].Value2);
}
}
}
//------------------ end of LoadExcelSheet---------------------------
this only display 1 row with each item of data on top of each other eg:-
aaaaaaaa
bbbbbbbb
cccccccc
dddddddd
instead of: aaaaaaaa bbbbbbbb cccccccc dddddddd
Thanks in advance..
The issue is with your for loops, try this:
for (var row = 1; row < 10; row++)
{
string r = "";
for (var col = 1; col < 6; col++)
{
r += " " + ws.Cells[row, col].Value2;
}
listBox1.Items.Add(r.Trim());
}
You are populating the list box inside a loop containing the columns, try something like
for (row = 1; row < 10; row++){
string a = "";
for (col = 1; col < 6; col++){
a += ws.Cells[row, col].Value2+" ";
}
listBox1.Items.Add(a);
}
Let's split the problem
Data collection
Collected data representation
Data collection (with a help of Linq):
using System.Linq;
...
string[] data = Enumerable
.Range(1, 9) // 9 rows, starting from 1
.Select(row => string.Join(" ", Enumerable // cols are joined with space
.Range(1, 5) // 5 columns in each row
.Select(col => ws.Cells[row, col].Value2)))
.ToArray();
And data representation (as ListBox items):
listBox1.Items.AddRange(data);
Related
I have a table in Excel
col1 col2
2 4
1 5
5 3
8 7
I need to compare 2 columns, col1 & col2. If the values from column col2>col1 then fill in the cell in the column col2 in red color. If the values from column col2
I wrote an example method, but I do not know how to fix it further.
private static void BackroundColor(string filePathNameExcel)
{
int i = 1;
using (XLWorkbook wb = new XLWorkbook(filePathNameExcel))
{
IXLWorksheet ws = wb.Worksheet("sheetMy");
int col = 1;
for (int j = 1; j <= col; j++)
{
if (j == 3)
{
for (int irow = 1; irow <= i; irow++)
{
if (ws.Cell(irow, 3).GetString() == "2")
{
string dat = ws.Cell(irow, 3).GetString();
ws.Cell(irow, 1).Style.Fill.BackgroundColor = XLColor.Red;
}
}
}
}
wb.SaveAs(filePathNameExcel, true);
}
}
I'm not able to fully understand your codes logic without seeing more of your data format so I made a few assumptions and simplified it for this example.
Starting Data
Code
private static void BackroundColor(string filePathNameExcel)
{
using (XLWorkbook wb = new XLWorkbook(filePathNameExcel))
{
IXLWorksheet ws = wb.Worksheet("sheetMy");
int lastRow = ws.LastRowUsed().RowNumber();
// Loop each row
for (int irow = 1; irow <= lastRow; irow++)
{
// Check if column 1 row value is less then column 2 row value
if ((double)ws.Cell(irow, 1).Value < (double)ws.Cell(irow,2).Value)
{
ws.Cell(irow, 2).Style.Fill.BackgroundColor = XLColor.Red;
}
}
wb.SaveAs(filePathNameExcel, true);
}
}
Result
I am using EPPlus library in my .net core web api. In the said method I want to validate he uploaded excel. I want to find out if my entire row is empty. I have the following code:
using (ExcelPackage package = new ExcelPackage(file.OpenReadStream()))
{
ExcelWorksheet worksheet = package.Workbook.Worksheets[1];
int rowCount = worksheet.Dimension.End.Row;
int colCount = worksheet.Dimension.End.Column;
//loop through rows and columns
for (int row = 1; row <= rowCount; row++)
{
for (int col = 1; col <= ColCount; col++)
{
var rowValue = worksheet.Cells[row, col].Value;
//Want to find here if the entire row is empty
}
}
}
rowValue above would give me if the particular cell if empty or not. Is it possible to check for the entire row and proceed to next row if empty.
you can check the row cell range value with linq:
var startRow = 1;
var endRow = 1;
var columnStart = 1;
var columnEnd = worksheet.Cells.End.Column;
var cellRange = worksheet.Cells[startRow, columnStart , endRow, columnEnd];
var isRowEmpty = cellRange.All(c => c.Value == null)
If you do not know the number of columns to check you can take advantage of the fact that the Worksheet.Cells collection only contains entries for cells that actually have values:
[TestMethod]
public void EmptyRowsTest()
{
//Throw in some data
var datatable = new DataTable("tblData");
datatable.Columns.AddRange(new[] { new DataColumn("Col1", typeof(int)), new DataColumn("Col2", typeof(int)), new DataColumn("Col3", typeof(object)) });
//Only fille every other row
for (var i = 0; i < 10; i++)
{
var row = datatable.NewRow();
if (i % 2 > 0)
{
row[0] = i;
row[1] = i * 10;
row[2] = Path.GetRandomFileName();
}
datatable.Rows.Add(row);
}
//Create a test file
var existingFile = new FileInfo(#"c:\temp\EmptyRowsTest.xlsx");
if (existingFile.Exists)
existingFile.Delete();
using (var pck = new ExcelPackage(existingFile))
{
var worksheet = pck.Workbook.Worksheets.Add("Sheet1");
worksheet.Cells.LoadFromDataTable(datatable, true);
pck.Save();
}
//Load from file
using (var pck = new ExcelPackage(existingFile))
{
var worksheet = pck.Workbook.Worksheets["Sheet1"];
//Cells only contains references to cells with actual data
var cells = worksheet.Cells;
var rowIndicies = cells
.Select(c => c.Start.Row)
.Distinct()
.ToList();
//Skip the header row which was added by LoadFromDataTable
for (var i = 1; i <= 10; i++)
Console.WriteLine($"Row {i} is empty: {rowIndicies.Contains(i)}");
}
}
Gives this in the output (Row 0 is the column headers):
Row 1 is empty: True
Row 2 is empty: False
Row 3 is empty: True
Row 4 is empty: False
Row 5 is empty: True
Row 6 is empty: False
Row 7 is empty: True
Row 8 is empty: False
Row 9 is empty: True
Row 10 is empty: False
You can set a bool in the for loop at row level. Then loop all the cells and change the bool when a cell is not empty.
//loop through rows and columns
for (int row = 1; row <= rowCount; row++)
{
//create a bool
bool RowIsEmpty = true;
for (int col = 1; col <= colCount; col++)
{
//check if the cell is empty or not
if (worksheet.Cells[row, col].Value != null)
{
RowIsEmpty = false;
}
}
//display result
if (RowIsEmpty)
{
Label1.Text += "Row " + row + " is empty.<br>";
}
}
You can use the worksheet.Cells[row, col].count() method for this.
If the row is empty then this method will return 0.
How can I query an Excel file where the rows and columns are reversed / rotated 90 degrees?
Can it be done with a SELECT query, or do I need to recurse the cells programmatically?
It's for a .NET app, so linq or other suggestions are welcome.
Transpose a Datatable with a code like this:
private DataTable GenerateTransposedTable(DataTable inputTable)
{
DataTable outputTable = new DataTable(inputTable.TableName);
outputTable.Columns.Add(inputTable.Columns[0].ColumnName);
foreach (DataRow inRow in inputTable.Rows)
{
string newColName = inRow[0].ToString();
outputTable.Columns.Add(newColName);
}
for (int rCount = 1; rCount <= inputTable.Columns.Count - 1; rCount++)
{
DataRow newRow = outputTable.NewRow();
newRow[0] = inputTable.Columns[rCount].ColumnName;
for (int cCount = 0; cCount <= inputTable.Rows.Count - 1; cCount++)
{
string colValue = inputTable.Rows[cCount][rCount].ToString();
newRow[cCount + 1] = colValue;
}
outputTable.Rows.Add(newRow);
}
return outputTable;
}
.NET does not include a method to transpose data tables. You have to make your own. This website Link has a tutorial on an example transpose method. I will copy and paste the code snippet below:
private DataTable Transpose(DataTable dt)
{
DataTable dtNew = new DataTable();
//adding columns
for(int i=0; i<=dt.Rows.Count; i++)
{
dtNew.Columns.Add(i.ToString());
}
//Changing Column Captions:
dtNew.Columns[0].ColumnName = " ";
for(int i=0; i<dt.Rows.Count; i++)
{
//For dateTime columns use like below
dtNew.Columns[i+1].ColumnName =Convert.ToDateTime(dt.Rows[i].ItemArray[0].ToString()).ToString("MM/dd/yyyy");
//Else just assign the ItermArry[0] to the columnName prooperty
}
//Adding Row Data
for(int k=1; k<dt.Columns.Count; k++)
{
DataRow r = dtNew.NewRow();
r[0] = dt.Columns[k].ToString();
for(int j=1; j<=dt.Rows.Count; j++)
r[j] = dt.Rows[j-1][k];
dtNew.Rows.Add(r);
}
return dtNew;
}
The problem is that I need to insert data into Excel from the collection several times using a single template for the entire collection.
using (var pckg = new ExcelPackage(new FileInfo(association.TemplatePath)))
{
var workSheet = pckg.Workbook.Worksheets[1];
var dataTable = WorksheetToDataTable(workSheet);
/*Some stuff*/
FindAndReplaceValue(workSheet, dictionary, row);
}
private DataTable WorksheetToDataTable(ExcelWorksheet oSheet)
{
int totalRows = oSheet.Dimension.End.Row;
int totalCols = oSheet.Dimension.End.Column;
DataTable dt = new DataTable(oSheet.Name);
DataRow dr = null;
for (int i = 1; i <= totalRows; i++)
{
if (i > 1) dr = dt.Rows.Add();
for (int j = 1; j <= totalCols; j++)
{
if (i == 1)
dt.Columns.Add((oSheet.Cells[i, j].Value ?? "").ToString());
else
dr[j - 1] = (oSheet.Cells[i, j].Value ?? "").ToString();
}
}
return dt;
}
First picture - My template. Second - First element of collection (with data, style, merging). Third - Other elements has only data
I just made copies of rows
for (int i = 0; i < invoiceList.Count; i++)
{
workSheet.Cells[1, 1, totalRows, totalCols].Copy(workSheet.Cells[i * totalRows + 1, 1]);
}
If you want to copy range just use :
workSheet.Cells["A1:I1"].Copy(workSheet.Cells["A4:I4"]);
I have an Excel file with 2 columns [file in my pc]? Now iam getting 2 columns with 8 rows with below code.but continuously i should get 5*2=10 more of same columns with 8 rows in datagridview.
I have written the code which gives result only 2 columns but I should get 10 more columns with 8 rows.below is my code
for (int Cnum = 1; Cnum <= ShtRange.Columns.Count; Cnum++)
{
dt.Columns.Add((ShtRange.Cells[1, Cnum] as Excel.Range).Value2.ToString());
}
for (int Rnum = 2; Rnum <= 9; Rnum++)
{
dt.Rows.Add((ShtRange.Cells[Rnum, 1] as Excel.Range).Value2.ToString(),
(ShtRange.Cells[Rnum, 1] as Excel.Range).Value2.ToString());
}
}
for (int i = 0; i < 13; i++)
{
DataGridViewTextBoxCell txtbx = new DataGridViewTextBoxCell();
DataGridViewColumn txcol = new DataGridViewColumn();
txcol.CellTemplate = txtbx;
txcol.HeaderText = "column" + i.ToString();
dg1.Columns.Add(txcol);
}
dg1.Rows.Add(8);
int dgRw, dgCol;
dgRw = dgCol = 0;
foreach (DataRow dr in dt.Rows)
{
dg1[dgCol, dgRw].Value = dr[0].ToString();
dgRw++;
if (dgRw == 8)
{
dgCol++;
dgRw = 0;
}