I want to read xlsx elements and print them 4 by 4 till all element are printed but i have a problem because it prints me all elements of the file. Any idea how to print them 4 by 4
// Open the Excel file.
Excel.Workbook xlWorkbook = xlApp.Workbooks.Open(Path.GetFullPath(#"C:\Users\user\Documents\Book2.xlsx"));
// Get the first worksheet.
Excel.Worksheet xlWorksheet = (Excel.Worksheet)xlWorkbook.Sheets.get_Item(1);
// Get the range of cells which has data.
Excel.Range xlRange = xlWorksheet.UsedRange;
// Get an object array of all of the cells in the worksheet with their values.
object[,] valueArray = (object[,])xlRange.get_Value(
Excel.XlRangeValueDataType.xlRangeValueDefault);
for (int row = 1; row <= xlWorksheet.UsedRange.Rows.Count; ++row)
{
for (int col = 1; col <= xlWorksheet.UsedRange.Columns.Count; ++col)
{
Console.WriteLine(valueArray[row, col].ToString());
}
int y = xlWorksheet.UsedRange.Rows.Count / 4;
for() {
Console.WriteLine("4 addresat e para u printuan");
Console.WriteLine(" ");
}
}
Don't loop until you get to the end of columns/tows collection. Loop 1 through 4 (or 0 to 3)...
for (int row = 1; row <= 4; ++row)
{
for (int col = 1; col <= x4; ++col)
{
Console.WriteLine(valueArray[row, col].ToString());
}
}
Related
I have an excel file which has say 5 columns and 5 rows.
I am using EPPlus (.net core c#)to parse the contents of the file.
I have the below code to count the rows and columns and then parse contents of this excel file.
using (ExcelPackage package = new ExcelPackage(stream))
{
ExcelWorksheet worksheet = package.Workbook.Worksheets[1];
int rowCount = worksheet.Dimension.End.Row;
int colCount = worksheet.Dimension.End.Column;
for (int row = 1; row <= rowCount; row++)
{
for (int col = 1; col <= colCount; col++)
{
//Parse here
}
}
}
With 5 rows and 5 columns of data as mentioned this works fine.
If I update and save the same file, and delete say 3 rows and 3 columns.
Now if I read this file again it still shows 5 columns and rows. Not sure if there is another way to read actual rows and columns?
Am I missing something here.
Try this
using (ExcelPackage package = new ExcelPackage(stream))
{
string directoryServerPath = // your file saving path in server;
if (!Directory.Exists(directoryServerPath))
Directory.CreateDirectory(directoryServerPath);
System.IO.DirectoryInfo directoryFiles = new DirectoryInfo(directoryServerPath);
foreach (FileInfo file in directoryFiles.GetFiles())
{
file.IsReadOnly = false;
file.Delete();
}
ExcelWorksheet worksheet = package.Workbook.Worksheets[1];
int rowCount = worksheet.Dimension.Rows;
int colCount = worksheet.Dimension.Columns;
for (int row = 1; row <= rowCount; row++)
{
for (int col = 1; col <= colCount; col++)
{
//Parse here
}
}
package.SaveAs(new System.IO.FileInfo(directoryServerPath + fileName));
System.IO.File.SetAttributes(directoryServerPath + fileName, FileAttributes.ReadOnly);
}
How can I use a select statement on an Excel sheet without using any oledb Provider? This is what I got so far by using using Excel = Microsoft.Office.Interop.Excel;. Iterating through each cell using a nested for-loop feels wrong...
// Create excel application object by calling constructor
Excel.Application xlApp = new Excel.Application();
// Open excel file using excel object
Excel.Workbook xlWorkbook = xlApp.Workbooks.Open(#"D:\Temp\file.xls");
// Open first sheet within excel document (index start at 1, not 0)
Excel._Worksheet xlWorksheet = (Excel.Worksheet)xlWorkbook.Sheets["SheetName"];
// Get used sheet bounderies
Excel.Range xlRange = xlWorksheet.UsedRange;
// Get row count
int rowCount = xlRange.Rows.Count;
// Get column count
int colCount = xlRange.Columns.Count;
//iterate over the rows and columns and print to the console as it appears in the file
for (int i = 1; i <= rowCount; i++)
{
for (int j = 1; j <= colCount; j++)
{
//new line
if (j == 1)
Console.Write("\r\n");
//write the value to the console if cell value ends on 'd'
if (xlRange.Cells[i, j] != null && xlRange.Cells[i, j].Value2 != null && (xlRange.Cells[i, j].Value2.ToString()).EndsWith("d"))
Console.Write(xlRange.Cells[i, j].Value2.ToString() + "\t");
}
}
While you could use the items interface to a range to go over all the cells, you are outputting for each row and conditionally outputting across columns, for is the right approach.
However, you could tighten the code up a little:
var rowCount = xlRange.Rows.Count;
var colCount = xlRange.Columns.Count;
for (int row = 1; row <= rowCount; ++row) {
Console.WriteLine();
for (int col = 1; col <= colCount; ++col) {
//write the value to the console if cell value ends on 'd'
if (xlRange.Cells[row, col]?.Value2?.ToString().EndsWith("d") ?? false)
Console.Write(xlRange.Cells[row, col].Value2.ToString() + "\t");
}
}
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);
I have a [,] string array that is 40 rows by 40 column items. I am trying to write them into an excel sheet but the output keeps writing the same word on the first row of every column. What am I doing wrong?
public static void writeToFile(this string [,] result)
{
try
{
//open instance of excel
Microsoft.Office.Interop.Excel.Application app = null;
app = new Excel.Application();
app.Workbooks.Add();
Excel._Worksheet sheet = app.ActiveSheet;
sheet.Name = "Sheet 1";
int resultCount = result.Length;
for (int i = 0; i < 40; i++)
{
for (int j = 0; j < 40; j++ )
{
sheet.Cells[i].Value = result[i,j];
j++;
}
i++;
}
If you got an array with rows at first dimension and columns at second dimension, you can simply write:
sheet.Range[sheet.Cells[1,1], sheet.Cells[40,40]].Value = result;
string workbookPath = filePath;
Excel.Application xlApp;
Excel.Workbook xlWorkBook;
Excel.Worksheet xlWorkSheet;
Excel.Range range;
int rCnt = 0;
int cCnt = 0;
xlApp = new Excel.Application();
xlWorkBook = xlApp.Workbooks.Open(workbookPath, 0, true, 5, "", "", true, Microsoft.Office.Interop.Excel.XlPlatform.xlWindows, "\t", false, false, 0, true, 1, 0);
xlWorkSheet = (Excel.Worksheet)xlWorkBook.Worksheets.get_Item(1);
range = xlWorkSheet.UsedRange;
int rowCount = range.Rows.Count;
int columnCount = range.Columns.Count;
string[][] myArray = new string[rowCount][];
for (rCnt = 1; rCnt < rowCount; rCnt++)
{
myArray[rCnt] = new string[columnCount];
for (cCnt = 1; cCnt < columnCount; cCnt++)
{
object str = (range.Cells[rCnt, cCnt] as Excel.Range).get_Value();
-----> myArray[rCnt][cCnt] = str == null ? string.Empty : str.ToString();
}
}
xlWorkBook.Close(true, null, null);
xlApp.Quit();
return myArray;
Above is the code for uploading an excel file to a sql database.
Essentially when I pass over the rCnt and cCnt variables where the ----> is above... the row count goes up once everytime the column count goes up twice ... I want to the column count to go up to 3, or however many usable columns there are.
The reason it's doing this could be that in the first row of the excel csv - there is nothing in the cell - however, in the 4-5th row, there is data in the 3rd column.
Could anyone glance at what I am missing?
Any questions / help would be greatly appreciated.
My first guess is that your code string[][] myArray = new string[rowCount][]; and myArray[rCnt] = new string[columnCount]; is allowing you to return a jagged array and you're going beyond those bounds somehow. UsedRange can sometimes be finicky (especially if you've deleted data - the range doesn't shrink down to fit your current data).
This code works fine for me, I use it a bit at work. COM entry/release code not included, I can add that later if you want it.
public string[,] ReadArray(int SheetNumber)
{
worksheet = (Excel.Worksheet)sheets.get_Item(SheetNumber);
Excel.Range range = worksheet.UsedRange;
//Get array, use range values. Not always correct, esp if user has deleted data. Ignore null values
Object[,] arr = range.Cells.Value;
string[,] output = new string[arr.GetLength(0), arr.GetLength(1)];
for (int i = 0; i < arr.GetLength(0); i++)
{
for (int j = 0; j < arr.GetLength(1); j++)
{
//If nothing in the cell, write a blank
if (arr[i + 1, j + 1] == null)
{
output[i, j] = "";
continue;
}
//else, write the output
output[i, j] = arr[i + 1, j + 1].ToString();
}
}
if (range != null)
Marshal.ReleaseComObject(range);
if (worksheet != null)
Marshal.ReleaseComObject(worksheet);
return output;
}