I populate values from my gridview in my table using this Code:
Table table = new Table();
// get gridlines from gridview
table.GridLines = GridView1.GridLines;
if (GridView1.HeaderRow != null)
{
table.Rows.Add(GridView1.HeaderRow);
}
foreach (GridViewRow row in GridView1.Rows)
{
table.Rows.Add(row);
}
if (GridView1.FooterRow != null)
{
table.Rows.Add(GridView1.FooterRow);
}
What I need is to read every data from the table which contains the values of the gridview into an Excel worksheet cell.
How can I achieve this?
PS: This is my worksheet obj in code-behind in C#.
Excel.Workbook xlWorkBook;
Excel.Worksheet xlWorkSheet;
Or Is there any other way to add the data from GridView to something else than, using table, which can be easily read?
public void ExportToExcel()
{
var Excel = new Microsoft.Office.Interop.Excel.Application();
XlReferenceStyle RefStyle = Excel.ReferenceStyle;
Excel.Visible = true;
Workbook wb = null;
string path = "yourpath";
try
{
wb = Excel.Workbooks.Add(path);
}
catch (System.Exception ex)
{
throw new Exception(ex.Message);
}
Worksheet ws = wb.Worksheets.get_Item(1) as Worksheet ;
for (int j = 0; j < GridView1.Columns.Count; ++j)
{
(ws.Cells[1, j + 1] as Range).Value2 = GridView1.Columns[j].HeaderText;
for (int i = 0; i < GridView1.Rows.Count; ++i)
{
object Val = GridView1.Rows[i].Cells[j].Value;
if (Val != null)
(ws.Cells[i + 2, j + 1] as Range).Value2 = Val.ToString();
}
}
Excel.ReferenceStyle = RefStyle;
Marshal.ReleaseComObject((object)Excel);
GC.GetTotalMemory(true);
}
Yes, there is a number of ways depending of what you gonna do. In your case the easiest one is CSV file (that would be work with Excel excellent). And there is no need to do somethins with DataGridView, if you have a DataSource
Related
trying to get a value from a data table, and output its contents to a textbox. seems im nearly there but for some reason studio doesnt like dt.rows[][];
ive seen multiple examples online in this format, but i get error CS002, cannot apply indexing with [] to an expression of type 'DataGridViewRow'.
im trying to locate the current row, and i can figure out the column either by putting an index number or by using the name of the column if that works better.
here is datatable_selectionChanged
private void dt_SelectionChanged(object sender, EventArgs e)
{
int row = dt.CurrentCell.RowIndex;
int col = dt.CurrentCell.ColumnIndex;
textBox1.Text = Convert.ToString(row);
textBox2.Text = Convert.ToString(col);
}
here is my mainform_load
private void mainForm_Load(object sender, EventArgs e)
{
string file = #"C:\Users\User\OneDrive - Motion Controls Robotics, Inc\Desktop\test inventory\TIS.xlsm"; //variable for the Excel File Location
DataTable dt = new DataTable(); //container for our excel data
DataRow row;
try
{
//Create Object for Microsoft.Office.Interop.Excel that will be use to read excel file
Microsoft.Office.Interop.Excel.Application excelApp = new Microsoft.Office.Interop.Excel.Application();
Microsoft.Office.Interop.Excel.Workbook excelWorkbook = excelApp.Workbooks.Open(file);
Microsoft.Office.Interop.Excel._Worksheet excelWorksheet = excelWorkbook.Sheets[1];
Microsoft.Office.Interop.Excel.Range excelRange = excelWorksheet.UsedRange;
int rowCount = excelRange.Rows.Count; //get row count of excel data
int colCount = excelRange.Columns.Count;//number of columns to display
//Get the first Column of excel file which is the Column Name
for (int i = 2; i <= rowCount;)
{
for (int j = 1; j <= colCount; j++)
{
dt.Columns.Add(excelRange.Cells[i, j].Value2.ToString());
}
break;
}
//Get Row Data of Excel
int rowCounter; //This variable is used for row index number
for (int i = 3; i <= rowCount; i++) //Loop for available row of excel data
{
row = dt.NewRow(); //assign new row to DataTable
rowCounter = 0;
for (int j = 1; j <= colCount; j++) //Loop for available column of excel data
{
//check if cell is empty
if (excelRange.Cells[i, j] != null && excelRange.Cells[i, j].Value2 != null)
{
row[rowCounter] = excelRange.Cells[i, j].Value2.ToString();
}
else
{
excelRange.Cells[i, j].value2 = "Empty";
//row[i] = "";
}
rowCounter++;
}
dt.Rows.Add(row); //add row to DataTable
}
this.dt.DataSource = dt; //assign DataTable as Datasource for DataGridview
//close and clean excel process
GC.Collect();
GC.WaitForPendingFinalizers();
Marshal.ReleaseComObject(excelRange);
Marshal.ReleaseComObject(excelWorksheet);
//quit apps
excelWorkbook.Close();
Marshal.ReleaseComObject(excelWorkbook);
excelApp.Quit();
Marshal.ReleaseComObject(excelApp);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
I'm Trying to read Excel to DataTable using NPOI.Every thing working fine but only issue is If we have any Column cell is empty in that row it is not reading .In Excel i have 4 row's with (each row have some empty values for cells).
Excel File Image : enter image description here
After Reading That Excel To data table :enter image description here
I want like this in data table
private DataTable GetDataTableFromExcel(String Path)
{
XSSFWorkbook wb;
XSSFSheet sh;
String Sheet_name;
using (var fs = new FileStream(Path, FileMode.Open, FileAccess.Read))
{
wb = new XSSFWorkbook(fs);
Sheet_name = wb.GetSheetAt(0).SheetName; //get first sheet name
}
DataTable DT = new DataTable();
DT.Rows.Clear();
DT.Columns.Clear();
// get sheet
sh = (XSSFSheet)wb.GetSheet(Sheet_name);
int i = 0;
while (sh.GetRow(i) != null)
{
// add neccessary columns
if (DT.Columns.Count < sh.GetRow(i).Cells.Count)
{
for (int j = 0; j < sh.GetRow(i).Cells.Count; j++)
{
DT.Columns.Add("", typeof(string));
}
}
// add row
DT.Rows.Add();
// write row value
for (int j = 0; j < sh.GetRow(i).Cells.Count; j++)
{
var cell = sh.GetRow(i).GetCell(j);
DT.Rows[i][j] = sh.GetRow(i).GetCell(j);
}
i++;
}
return DT;
}
Plese hlp me.
you may have to try something along this line. its workable code to read the excel using NPOI.
// read the current row data
XSSFRow headerRow = (XSSFRow)sheet.GetRow(0);
// LastCellNum is the number of cells of current rows
int cellCount = headerRow.LastCellNum;
// LastRowNum is the number of rows of current table
int rowCount = sheet.LastRowNum + 1;
bool isBlanKRow = false;
//Start reading data after first row(header row) of excel sheet.
for (int i = (sheet.FirstRowNum + 1); i < rowCount; i++)
{
XSSFRow row = (XSSFRow)sheet.GetRow(i);
DataRow dataRow = dt.NewRow();
isBlanKRow = true;
try
{
for (int j = row.FirstCellNum; j < cellCount; j++)
{
if (null != row.GetCell(j) && !string.IsNullOrEmpty(row.GetCell(j).ToString()) && !string.IsNullOrWhiteSpace(row.GetCell(j).ToString()))
{
dataRow[j] = row.GetCell(j).ToString();
isBlanKRow = false;
}
}
}
catch (Exception Ex)
{
}
if (!isBlanKRow)
{
dt.Rows.Add(dataRow);
}
}
I'm using csharp to insert data into excel sheet into 7 columns. The interface of this program will allow users to select 7 checkboxes. If they select all 7, all the 7 columns in spreadhseet will have data, if they select one checkbox then only one column will have data. I have got a for loop which will check if data is there, if no data exists, I want to remove that column in epplus. Here's a previous discussion on this topic
How can I delete a Column of XLSX file with EPPlus in web app
It's quiet old so I just wanna check if there's a way to do this.
Or, is there a way to cast epplus excel sheet to microsoft interop excel sheet and perform some operations.
Currently, I've code like this:
for(int j=1; j <= 9; j++) //looping through columns
{
int flag = 0;
for(int i = 3; i <= 10; i++) // looping through rows
{
if(worksheet.cells[i, j].Text != "")
{
flag ++;
}
}
if (flag == 0)
{
worksheet.column[j].hidden = true; // hiding the columns- want to remove it
}
}
Can we do something like:
Excel.Application xlApp = new Microsoft.Office.Interop.Excel.Application();
xlApp = worksheet; (where worksheet is epplus worksheet)
Are you using EPPlus 4? The ability to do column inserts and deletion was added with the new Cell store model they implemented. So you can now do something like this:
[TestMethod]
public void DeleteColumn_Test()
{
//http://stackoverflow.com/questions/28359165/how-to-remove-a-column-from-excel-sheet-in-epplus
var existingFile = new FileInfo(#"c:\temp\temp.xlsx");
if (existingFile.Exists)
existingFile.Delete();
//Throw in some data
var datatable = new DataTable("tblData");
datatable.Columns.Add(new DataColumn("Col1"));
datatable.Columns.Add(new DataColumn("Col2"));
datatable.Columns.Add(new DataColumn("Col3"));
for (var i = 0; i < 20; i++)
{
var row = datatable.NewRow();
row["Col1"] = "Col1 Row" + i;
row["Col2"] = "Col2 Row" + i;
row["Col3"] = "Col3 Row" + i;
datatable.Rows.Add(row);
}
using (var pack = new ExcelPackage(existingFile))
{
var ws = pack.Workbook.Worksheets.Add("Content");
ws.Cells.LoadFromDataTable(datatable, true);
ws.DeleteColumn(2);
pack.SaveAs(existingFile);
}
}
I have a datagridview in c# where i am showing records.Now as per my requirement i have to export this into excel.So i have written following method for this..
public static void ExportToExcel(DataGridView dgView)
{
Microsoft.Office.Interop.Excel.Application excelApp = null;
try
{
// instantiating the excel application class
object misValue = System.Reflection.Missing.Value;
excelApp = new Microsoft.Office.Interop.Excel.Application();
Microsoft.Office.Interop.Excel.Workbook currentWorkbook = excelApp.Workbooks.Add(Type.Missing);
Microsoft.Office.Interop.Excel.Worksheet currentWorksheet = (Microsoft.Office.Interop.Excel.Worksheet)currentWorkbook.ActiveSheet;
currentWorksheet.Columns.ColumnWidth = 18;
if (dgView.Rows.Count > 0)
{
currentWorksheet.Cells[1, 1] = DateTime.Now.ToString("s");
int i = 1;
foreach (DataGridViewColumn dgviewColumn in dgView.Columns)
{
// Excel work sheet indexing starts with 1
currentWorksheet.Cells[2, i] = dgviewColumn.Name;
++i;
}
Microsoft.Office.Interop.Excel.Range headerColumnRange = currentWorksheet.get_Range("A2", "G2");
headerColumnRange.Font.Bold = true;
headerColumnRange.Font.Color = 0xFF0000;
//headerColumnRange.EntireColumn.AutoFit();
int rowIndex = 0;
for (rowIndex = 0; rowIndex < dgView.Rows.Count; rowIndex++)
{
DataGridViewRow dgRow = dgView.Rows[rowIndex];
for (int cellIndex = 0; cellIndex < dgRow.Cells.Count; cellIndex++)
{
currentWorksheet.Cells[rowIndex + 3, cellIndex + 1] = dgRow.Cells[cellIndex].Value;
}
}
Microsoft.Office.Interop.Excel.Range fullTextRange = currentWorksheet.get_Range("A1", "G" + (rowIndex + 1).ToString());
fullTextRange.WrapText = true;
fullTextRange.HorizontalAlignment = Microsoft.Office.Interop.Excel.XlHAlign.xlHAlignLeft;
}
else
{
string timeStamp = DateTime.Now.ToString("s");
timeStamp = timeStamp.Replace(':', '-');
timeStamp = timeStamp.Replace("T", "__");
currentWorksheet.Cells[1, 1] = timeStamp;
currentWorksheet.Cells[1, 2] = "No error occured";
}
using (SaveFileDialog exportSaveFileDialog = new SaveFileDialog())
{
exportSaveFileDialog.Title = "Select Excel File";
exportSaveFileDialog.Filter = "Microsoft Office Excel Workbook(*.xlsx)|*.xlsx";
if (DialogResult.OK == exportSaveFileDialog.ShowDialog())
{
string fullFileName = exportSaveFileDialog.FileName;
currentWorkbook.SaveAs(fullFileName, Microsoft.Office.Interop.Excel.XlFileFormat.xlOpenXMLWorkbook, System.Reflection.Missing.Value, misValue, false, false, Microsoft.Office.Interop.Excel.XlSaveAsAccessMode.xlNoChange, Microsoft.Office.Interop.Excel.XlSaveConflictResolution.xlUserResolution, true, misValue, misValue, misValue);
currentWorkbook.Saved = true;
MessageBox.Show("Exported successfully", "Exported to Excel", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Exception", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
finally
{
if (excelApp != null)
{
excelApp.Quit();
}
}
}
Now one strange thing is happening when i am trying to get the excel report using my application i am not able to get that whereas if i am trying to get it by debugging my code i am getting but it too is taking hell lot of time.
On debugging the code This line ..
Microsoft.Office.Interop.Excel.Range fullTextRange = currentWorksheet.get_Range("A1", "G" + (rowIndex + 1).ToString());
is taking considerable lot of time ..
Please help me ..
Excel Interop is never going to be fast as you're remote controlling an instance of the Excel application. You might want to create a CSV file and then using Excel Interop to convert this to a .xls or .xlsx file.
Here's example on how to convert csv to xls
using Excel = Microsoft.Office.Interop.Excel;
Excel.Application excel = new Excel.Application();
Excel.Workbook workBook = excel.Workbooks.Add();
var inputFile = new FileInfo("Book1.csv");
var sheet = Spreadsheet.Read(inputFile);
workBook.ActiveSheet = sheet; // unsure about this part, but basically you need to transfer data.
workBook.SaveAs(#"C:\Temp\fromCsv.xls");
workBook.Close();
I think the below section slows down your code a lot
int rowIndex = 0;
for (rowIndex = 0; rowIndex < dgView.Rows.Count; rowIndex++)
{
DataGridViewRow dgRow = dgView.Rows[rowIndex];
for (int cellIndex = 0; cellIndex < dgRow.Cells.Count; cellIndex++)
{
currentWorksheet.Cells[rowIndex + 3, cellIndex + 1] = dgRow.Cells[cellIndex].Value;
}
}
I think it would be much faster to export DataGridView to an Excel spreadsheet by not looping through calling Cells each time because each call to Cells is quite expensive when using COM.
I suggest your convert your DataGridViewColumn to a 2D array and then export the entire DataGridView in one go like this:
object[,] toExport = new object[dgView.Rows.Count, dgView.Columns.Count];
for (int row = 0; row < dgView.Rows.Count; row++)
{
DataGridViewRow dgRow = dgView.Rows[row];
for (int column= 0; column < dgRow.Cells.Count; column++)
{
toExport[row, column] = dgRow.Cells[row].Value;
}
}
// export in one go instead of looping and accessing Cells each time
// use Excel.Application.Transpose(array) if needed
ws.get_Range("A3").set_Value(Type.Missing, toExport);
Additionally you may add an xlApp.ScreenUpdating = false; at the start and then switch it back to true when you're done modifying sheet.
I need to export a datgrid to an excel document, but i'm encountering an error when doing so. Below is the code i'm using to export, it opens up the Excel document, and the headers are in place, but where the values in each cell should be i'm seeing System.Data.DataRowView in the excel cell. What i need to do is take the values from hat row and insert them into the Excel workbook.
Any help is appreciated, or tutorial links.
Peter
Microsoft.Office.Interop.Excel.Application excel = null;
Microsoft.Office.Interop.Excel.Workbook wb = null;
object missing = Type.Missing;
Microsoft.Office.Interop.Excel.Worksheet ws = null;
Microsoft.Office.Interop.Excel.Range rng = null;
try
{
excel = new Microsoft.Office.Interop.Excel.Application();
wb = excel.Workbooks.Add();
ws = (Microsoft.Office.Interop.Excel.Worksheet)wb.ActiveSheet;
for (int Idx = 0; Idx < dataGrid1.Columns.Count; Idx++)
{
// Puts Column Header into excel work sheet
ws.Range["A1"].Offset[0, Idx].Value = dataGrid1.Columns[Idx].Header;
}
for (int Idx = 0; Idx < dataGrid1.Items.Count; Idx++)
{
ws.Range["A2"].Offset[Idx].Resize[1, dataGrid1.Columns.Count].Value =
dataGrid1.Items[Idx].ToString();
}
excel.Visible = true;
wb.
}
catch (COMException ex)
{
MessageBox.Show("Error accessing Excel: " + ex.ToString());
}
catch (Exception ex)
{
MessageBox.Show("Error: " + ex.ToString());
}
I found the solution, if anybody ever has the same problem.
To access the the values inside the row here's what you need to:
for (int columnIndex = 0; columnIndex < dataGrid1.Columns.Count; columnIndex++)
{
ws.Range["A2"].Offset[rowIndex, columnIndex].Value =
(dataGrid1.Items[rowIndex] as DataRowView).Row.ItemArray[columnIndex].ToString()
}
With the loop for (int Idx = 0; Idx < dataGrid1.Items.Count; Idx++) you are iterating over the items, i.e. the rows of the DataGrid. Each such item or row apparently is a DataRowView, and hence ToString gives you "System.Data.DataRowView".
You would also have to iterate over each item in a row, i.e. the cell:
for (int rowIndex = 0; rowIndex < dataGrid1.Items.Count; rowIndex++)
{
for (int columnIndex = 0; columnIndex < dataGrid1.Columns.Count; columnIndex++)
{
ws.Range["A2"].Offset[rowIndex, columnIndex].Value =
dataGrid1.Items[rowIndex][columnIndex].ToString();
}
}
Note that i haven't tested this and don't know anything about the Excel API, so i'm not really sure if the ws.Range["A2"].Offset[rowIndex, columnIndex] thing is correct.