How to send details of excel data in Detailview - c#

I am developing an application that should extract excel data in a Gridview and show the details of individual data in a Detailsview. There is no use of SQL Server and sqlDataSource here. I am in dilemma though.
protected void btnViewDetail_Click(object sender, EventArgs e)
{
{
// What to write in here?
}
}
I have a button named 'View Detail' in GridView that should redirect me to Detailsview with the details of selected data.
Thanks.

Use this method for exporting datagridview to excel
parameters -> excel path, and grid name
public void exportExcel(string path, DataGridView dgv)
{
try
{
Microsoft.Office.Interop.Excel._Application ExcelApp = new Microsoft.Office.Interop.Excel.Application();
ExcelApp.Application.Workbooks.Add(Type.Missing);
ExcelApp.Columns.ColumnWidth = 10;
for (int j = 0; j < dgv.ColumnCount; j++)
{
ExcelApp.Cells[1, j + 1] = dgv.Columns[j].HeaderText;
}
Microsoft.Office.Interop.Excel.Range headerColumnRange = ExcelApp.get_Range("A1", "Z1");
headerColumnRange.Font.Bold = true;
headerColumnRange.Font.Color = 0xFF0000;
for (int i = 1; i < dgv.Rows.Count; i++)
{
//DataGridViewRow row = dataGridView1.Rows[i];
for (int j = 0; j < dgv.ColumnCount; j++)
{
ExcelApp.Cells[i + 1, j + 1] = dgv.Rows[i - 1].Cells[j].Value.ToString();
}
}
ExcelApp.ActiveWorkbook.SaveCopyAs(path);
ExcelApp.ActiveWorkbook.Saved = true;
ExcelApp.Quit();
}
catch { }
}

You can use EasyXLS Excel library to extract data from the Excel file. The Excel can be imported into a DataSet and no SQL Server is required.
// Create an instance of the class that imports Excel files
ExcelDocument xls = new ExcelDocument();
// Import Excel file to DataTable
DataSet ds = xls.easy_ReadXLSXActiveSheet_AsDataSet("Excel.xlsx");
DataTable dataTable = ds.Tables[0];
// Set the GridView data
gridView.DataSource = dataTable;
If you have more than one sheet into your Excel file, you may check for more details on import Excel to Dataset in C#.

Related

Referencing an Excel file, workbook, worksheet in C#

All,
I have been struggling to simply reference an Excel file so that I can extract its data into a new worksheet automatically.
I know this means to create a new Excel file and its items:
Excel.Application oXL;
Excel._Workbook oWB;
Excel._Worksheet oSheet;
Excel.Range oRng;
//Start Excel and get Application object.
oXL = new Excel.Application();
oXL.Visible = true;
//Get a new workbook.
oWB = (Excel._Workbook)(oXL.Workbooks.Add(Missing.Value));
oSheet = (Excel._Worksheet)oWB.ActiveSheet;
But this is where I am lost...I want the user to select another Excel file through a file dialog and then I want to copy data from said file into the new workbook above.
Ex: New file, user selects "MyExcel.csv". How would I reference this so that I can, say, copy Column A into the new worksheet? Whatever works with C#.
Maybe this helps:
Make sure your manage your Nugets and add the reference "Microsoft.Office.Interop.Excel" --> (References (Right click) --> Manage Nuget Packages --> Browse --> "Microsoft.Office.Interop.Excel" --> Install)
Note: This is is a copy paste into the same worksheet. To copy the data into another worksheet from another file just pass the "worksheet" as parameter to the method and paste it there.
public class Excel1
{
private readonly string excelSufix = ".xlsx";
private readonly string excelFilePrefix = "..."; //Where you excel file is located
private string getFilePath(string fileName)
{
return excelFilePrefix + fileName + excelSufix; //returns the file path by the given file name
}
public void CopyPaste(string fileName, int worksheet, string toCopyRange, string whereInsertRange)
{
//Range should look like = "A:C" or "D:F"
var excelApp = new Microsoft.Office.Interop.Excel.Application();
excelApp.Visible = true;
var workBook = excelApp.Workbooks.Open(getFilePath(fileName));
var workSheet = (Microsoft.Office.Interop.Excel.Worksheet)workBook.Sheets[worksheet];
var toCopy = workSheet.Range[toCopyRange];
var whereInsert = workSheet.Range[whereInsertRange];
whereInsert.Insert(Microsoft.Office.Interop.Excel.XlInsertShiftDirection.xlShiftToRight, toCopy.Cut());
}
}
Edit: You could add a constructor to the class where you pass the file Path and some class variables which reference the file, the worksheet etc etc... In this case, you will have independent objects for each file
Based on your description, you want to copy one column from the csv file and paste in the new excel file.
First, I convert the csv file to datatable.
Second, I select the specific column and convert one column to datatable.
Third, I convert the datatable to the new excel file.
You can try the following code.
using System;
using System.Data;
using Excel = Microsoft.Office.Interop.Excel;
class Program
{
static void Main(string[] args)
{
string path = "D:\\t.csv";
DataTable table = ReadCsv(path);
table= new DataView(table).ToTable(false, "Tests");
ExportToExcel(table, "D:\\t.xlsx");
}
public static DataTable ReadCsv(string path)
{
Microsoft.Office.Interop.Excel.Application objXL = null;
Microsoft.Office.Interop.Excel.Workbook objWB = null;
objXL = new Microsoft.Office.Interop.Excel.Application();
objWB = objXL.Workbooks.Open(path);
Microsoft.Office.Interop.Excel.Worksheet objSHT = objWB.Worksheets[1];
int rows = objSHT.UsedRange.Rows.Count;
int cols = objSHT.UsedRange.Columns.Count;
DataTable dt = new DataTable();
int noofrow = 1;
for (int c = 1; c <= cols; c++)
{
string colname = objSHT.Cells[1, c].Text;
dt.Columns.Add(colname);
noofrow = 2;
}
for (int r = noofrow; r <= rows; r++)
{
DataRow dr = dt.NewRow();
for (int c = 1; c <= cols; c++)
{
dr[c - 1] = objSHT.Cells[r, c].Text;
}
dt.Rows.Add(dr);
}
objWB.Close();
objXL.Quit();
return dt;
}
public static void ExportToExcel( DataTable tbl, string excelFilePath = null)
{
try
{
if (tbl == null || tbl.Columns.Count == 0)
throw new Exception("ExportToExcel: Null or empty input table!\n");
// load excel, and create a new workbook
var excelApp = new Excel.Application();
excelApp.Workbooks.Add();
// single worksheet
Excel._Worksheet workSheet = excelApp.ActiveSheet;
// column headings
for (var i = 0; i < tbl.Columns.Count; i++)
{
workSheet.Cells[1, i + 1] = tbl.Columns[i].ColumnName;
}
// rows
for (var i = 0; i < tbl.Rows.Count; i++)
{
// to do: format datetime values before printing
for (var j = 0; j < tbl.Columns.Count; j++)
{
workSheet.Cells[i + 2, j + 1] = tbl.Rows[i][j];
}
}
// check file path
if (!string.IsNullOrEmpty(excelFilePath))
{
try
{
workSheet.SaveAs(excelFilePath);
excelApp.Quit();
Console.WriteLine("Excel file saved!");
}
catch (Exception ex)
{
throw new Exception("ExportToExcel: Excel file could not be saved! Check filepath.\n"
+ ex.Message);
}
}
else
{ // no file path is given
excelApp.Visible = true;
}
}
catch (Exception ex)
{
throw new Exception("ExportToExcel: \n" + ex.Message);
}
}
}
Initial csv file.
The excel file:

Excel Exporting with Additional Worksheet

I'm exporting a DataSet to Excel (.xlsx) and for whatever reason, I'm getting an additional (unwanted) worksheet added to my workbook.
My dataTables are setup like so:
DataTable table1 = new DataTable();
table1 = CallReport("ReportName");
DataTable table2 = new DataTable();
table2 = CallReport("ReportName");
DataTable table3 = new DataTable();
table3 = CallReport("ReportName");
//add to DataSet
DataSet exportSet = new DataSet();
table3.TableName = "Combined";
exportSet.Tables.Add(table3);
table2.TableName = "Non-Services";
exportSet.Tables.Add(table2);
table1.TableName = "Services";
exportSet.Tables.Add(table1);
I'm then creating an Excel instance, then using foreach to loop through my DataSet and write the tables to the Excel workbook:
MSClass.CreateExcelFile();
foreach (DataTable table in exportSet.Tables)
{
MSClass.WriteToExcel(table, table.TableName);
}
MSClass.SaveExcelFile(exportPath);
Here is how I'm creating the Excel file, writing to it and saving it within my MSClass:
class MSClass
{
static Microsoft.Office.Interop.Excel.Application xl;
public static void CreateExcelFile()
{
//Creates new instance of Excel.Application()
xl = new Excel.Application();
//Adds new workbook to the application instance
xl.Workbooks.Add();
}
public static void SaveExcelFile(string filePath)
{
//Check to make sure the filePath isn't empty, and if it is, just show the file instance
if (filePath != null && filePath != "")
{
//in case there's an error
try
{
//Makes sure the sheet is in the active session
Excel._Worksheet sheet = xl.ActiveSheet;
//Stops from asking to overwrite the file.
//If I didn't want to overwrite I would be changing the file name everytime.
xl.DisplayAlerts = false;
//Saves the sheet to the file path
sheet.SaveAs(filePath);
//shows the final product
xl.Visible = true;
}
catch (Exception ex)
{
//throw up an Exception for any error and show the error message
throw new Exception("Export To Excel: Excel file could not be saved! Check filePath.\n" + ex.Message);
}
}
else //no file path is given
{
//Just show the current session of the Excel Application
xl.Visible = true;
}
}
public static void WriteToExcel(DataTable table, string sheetName)
{
//Adds new worksheet to workbook
Excel._Worksheet sheet = xl.ActiveWorkbook.Sheets[1];
//Gets count of columns within supplied DataTable
int colCount = table.Columns.Count;
//Creates object array for headers for each column
object[] header = new object[colCount];
//loop to add column names to header object array
for (int i = 0; i < colCount; i++)
{
//Adds column names to header object array
header[i] = table.Columns[i].ColumnName;
}
//Get range of headers
Excel.Range headerRange = sheet.get_Range((Excel.Range)(sheet.Cells[1, 1]), (Excel.Range)(sheet.Cells[1, colCount]));
//Applies the header to Excel file
headerRange.Value = header;
//Adds color to header to make more distinct
headerRange.Interior.Color = ColorTranslator.ToOle(Color.LightGray);
//Bolds the header
headerRange.Font.Bold = true;
//gets count of rows from DataTable
int rowCount = table.Rows.Count;
//Object multidimensional array for the cells within the dataTable
object[,] cells = new object[rowCount, colCount];
//Adds the cells from DataTable to cell Object array
for (int j = 0; j < rowCount; j++)
{
for (int i = 0; i < colCount; i++)
{
//Sets cell values to DataTable values
cells[j, i] = table.Rows[j][i];
}
}
//prints the cell values to Excel cell(s)
sheet.get_Range((Excel.Range)(sheet.Cells[2, 1]), (Excel.Range)(sheet.Cells[rowCount + 1, colCount])).Value = cells;
sheet.Name = sheetName;
sheet.Activate();
xl.Worksheets.Add(sheet);
}
}
I'm unsure what is currently causing the extra sheet to be exported. the sheets export in the order of: Sheet4 | Services | Non-Services | Combined
Where Sheet4 is completely blank, and the other sheets are exported in reversed order.
What is causing my extra (blank) sheet to be added to the workbook?

Extract values from a list and save it to an existing Excel sheet in c#

I have an existing Excel sheet which has headers. I get data from my server and place it in my WPF DataGrid and it looks like this:
On a click of a button, I need to place the values from my list to a particular sheet in my existing Excel workbook. I can actually get the values from a WINFORM DataGrid like this:
var xlApp = new Excel.Application();
Excel.Worksheet sheet = new Excel.Worksheet();
xlApp.Visible = true;
var path = #"D:\Reports\Tag_History.xlsx";
sheet = xlApp.Application.Workbooks.Open(path).Worksheets["Summary"];
var rowCount = dataGrid.Items.Count;
var rowColumn = dataGrid.Columns.Count;
for (int i = 0; i < rowCount - 1; i++)
{
for (int j = 0; j < 7; j++)
{
if (dataGrid[j, i].ValueType == typeof(string))
{
xlsht.Cells[i + 2, j + 1] = "'" + dataGrid[j, i].Value.ToString();
}
else
{
xlsht.Cells[i + 2, j + 1] = dataGrid[j, i].Value.ToString();
}
}
}
but since I am trying to do this in WPF, this code does not work anymore. This is by transferring dataGrid data to an existing excel file. Since I think that transferring list to an existing excel file is better, I have to try this. This is what I have so far:
var xlApp = new Excel.Application();
Excel.Worksheet sheet = new Excel.Worksheet();
xlApp.Visible = true;
var path = #"D:\Reports\Tag_History.xlsx";
sheet = xlApp.Application.Workbooks.Open(path).Worksheets["Summary"];
var range = sheet.Range["A2", "A2"];
foreach (var item in summaryList)
{
range.Value2 = item.TagNumber;
}
This code works but it is only updating a single cell of the excel file.
Can you please show me how to do this? Thank you.
Install Microsoft.Office.Interop.Excel Nuget package in your application. Right-click on your project -> "References" and choose "Manage NuGet Packages...", then just search for Excel. Otherwise, select Tools -> Nuget Package Manager -> Package Manager Console -> then install the Excel nuget (https://www.nuget.org/packages/Microsoft.Office.Interop.Excel/).
Bind the items in DataGrid and then export data to excel as like below,
private void btnExport_Click(object sender, RoutedEventArgs e)
{
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;
// collection of DataGrid Items
var dtExcelDataTable = ExcelTimeReport(txtFrmDte.Text, txtToDte.Text, strCondition);
excel = new Microsoft.Office.Interop.Excel.Application();
wb = excel.Workbooks.Add();
ws = (Microsoft.Office.Interop.Excel.Worksheet)wb.ActiveSheet;
ws.Columns.AutoFit();
ws.Columns.EntireColumn.ColumnWidth = 25;
// Header row
for (int Idx = 0; Idx < dtExcelDataTable.Columns.Count; Idx++)
{
ws.Range["A1"].Offset[0, Idx].Value = dtExcelDataTable.Columns[Idx].ColumnName;
}
// Data Rows
for (int Idx = 0; Idx < dtExcelDataTable.Rows.Count; Idx++)
{
ws.Range["A2"].Offset[Idx].Resize[1, dtExcelDataTable.Columns.Count].Value = dtExcelDataTable.Rows[Idx].ItemArray;
}
excel.Visible = true;
wb.Activate();
wb.SaveCopyAs("excel file location");
wb.Saved = true;
excel.Quit();
}

How to read Excel file in SSIS package with Enable Protected View for files originating from the internet

I have an SSRS reports form where in Export my results in Excel file. As Excel behavior is to Enable Protected View for files originating from the internet. it asks for Enable Editing button clicked or setting off for Excel.
i am using script task C# to read excel in SSIS. but to execute it, i need to click on enable editing on in Excel. is there any way to not to set the settings or open the file to make it writable. my script task works in development but fails in deploy mode. below is the code. please help me to figure out.
//pass that to workbook object
Microsoft.Office.Interop.Excel.Workbook workBook = oExcel.Workbooks.Open(workbookPath);
foreach (Worksheet worksheet in workBook.Worksheets)
{
if (worksheet.Name.Equals(sheetName, StringComparison.OrdinalIgnoreCase))
{
Microsoft.Office.Interop.Excel.Range xlRange = worksheet.UsedRange;
object[,] data = new object[xlRange.Rows.Count - 1, xlRange.Columns.Count];
System.Data.DataTable dt = new System.Data.DataTable();
for (int i = 1; i <= xlRange.Rows.Count - 1; i++)
{
for (int j = 1; j <= xlRange.Columns.Count; j++)
{
data[i - 1, j - 1] = (xlRange.Cells[i, j] as Microsoft.Office.Interop.Excel.Range).Value;
}
}
workBook.Close(true);
oExcel.Application.Quit();
oExcel.Quit();
Marshal.ReleaseComObject(workBook);
Marshal.ReleaseComObject(oExcel);
dt = ArraytoDatatable(data);
dt.TableName = tableName;
//BulkLoadDataTable(dt, connectionString);
}
else
{
FireError("Wrong Sheet name found. Please Rename the sheet name as:" + sheetName);
}
}
Dts.TaskResult = (int)ScriptResults.Success;

Create Excel VBA code and button programmatically from C#

I am in the middle of simple method, that saves my DataGridView into an Excel document (1 sheet only) and also adds VBA code and a button to run the VBA code.
public void SaveFile(string filePath)
{
Microsoft.Office.Interop.Excel.ApplicationClass ExcelApp = new Microsoft.Office.Interop.Excel.ApplicationClass();
ExcelApp.Application.Workbooks.Add(Type.Missing);
//Change Workbook-properties.
ExcelApp.Columns.ColumnWidth = 20;
// Storing header part in Excel.
for (int i = 1; i < gridData.Columns.Count + 1; i++)
{
ExcelApp.Cells[1, i] = gridData.Columns[i - 1].HeaderText;
}
//Storing Each row and column value to excel sheet
for (int row = 0; row < gridData.Rows.Count; row++)
{
gridData.Rows[row].Cells[0].Value = "Makro";
for (int column = 0; column < gridData.Columns.Count; column++)
{
ExcelApp.Cells[row + 2, column + 1] = gridData.Rows[row].Cells[column].Value.ToString();
}
}
ExcelApp.ActiveWorkbook.SaveCopyAs(filePath);
ExcelApp.ActiveWorkbook.Saved = true;
ExcelApp.Quit();
}
I only implemented DataGridView export.
EDIT: Thanks to Joel I could, with proper words, search again for the solution. I think that this may be helpful. Would you correct me or give a tip or two about what I should look for.
I just wrote a small example which adds a new button to an existing workbook and afterwards add a macro which will be called when the button is clicked.
using Excel = Microsoft.Office.Interop.Excel;
using VBIDE = Microsoft.Vbe.Interop;
...
private static void excelAddButtonWithVBA()
{
Excel.Application xlApp = new Excel.Application();
Excel.Workbook xlBook = xlApp.Workbooks.Open(#"PATH_TO_EXCEL_FILE");
Excel.Worksheet wrkSheet = xlBook.Worksheets[1];
Excel.Range range;
try
{
//set range for insert cell
range = wrkSheet.get_Range("A1:A1");
//insert the dropdown into the cell
Excel.Buttons xlButtons = wrkSheet.Buttons();
Excel.Button xlButton = xlButtons.Add((double)range.Left, (double)range.Top, (double)range.Width, (double)range.Height);
//set the name of the new button
xlButton.Name = "btnDoSomething";
xlButton.Text = "Click me!";
xlButton.OnAction = "btnDoSomething_Click";
buttonMacro(xlButton.Name, xlApp, xlBook, wrkSheet);
}
catch (Exception ex)
{
Debug.WriteLine(ex.Message);
}
xlApp.Visible = true;
}
And here we got the buttonMacro(..) method
private static void buttonMacro(string buttonName, Excel.Application xlApp, Excel.Workbook wrkBook, Excel.Worksheet wrkSheet)
{
StringBuilder sb;
VBIDE.VBComponent xlModule;
VBIDE.VBProject prj;
prj = wrkBook.VBProject;
sb = new StringBuilder();
// build string with module code
sb.Append("Sub " + buttonName + "_Click()" + "\n");
sb.Append("\t" + "msgbox \"" + buttonName + "\"\n"); // add your custom vba code here
sb.Append("End Sub");
// set an object for the new module to create
xlModule = wrkBook.VBProject.VBComponents.Add(VBIDE.vbext_ComponentType.vbext_ct_StdModule);
// add the macro to the spreadsheet
xlModule.CodeModule.AddFromString(sb.ToString());
}
Found this information within an KB article How To Create an Excel Macro by Using Automation from Visual C# .NET

Categories