Quickly read data from Excel - c#

I have the code below reading data from an Excel worksheet and converting it to a pipe delimited text file. It works. The problem is it's quite slow as I have to read 1 cell at a time in order to add in the pipe.
I wondered if there was a better way to do this i.e. read the data into memory/array in one step and act on it there.
public string Process(string filename)
{
Excel.Application xlApp;
Excel.Workbook xlWorkBook;
Excel.Worksheet xlWorkSheet;
Excel.Range range;
string str = "";
int rCnt = 0;
int cCnt = 0;
object misValue = System.Reflection.Missing.Value;
xlApp = new Excel.Application();
xlWorkBook = xlApp.Workbooks.Open(filename, 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); //Use the 1st worksheet
StreamWriter sw = new StreamWriter(destpath);
range = xlWorkSheet.UsedRange;
for (rCnt = 1; rCnt <= range.Rows.Count; rCnt++)
{
if ((rCnt % 1000) == 0)
{
txtProgress.Text = "Rows processed: "+ rCnt;
}
for (cCnt = 1; cCnt <= range.Columns.Count; cCnt++)
{
str = str + ToStr((range.Cells[rCnt, cCnt] as Excel.Range).Value2) + "|";
}
sw.WriteLine(str);
str = "";
}
xlWorkBook.Close(true, null, null);
xlApp.Quit();
sw.Close();
releaseObject(xlWorkSheet);
releaseObject(xlWorkBook);
releaseObject(xlApp);
MessageBox.Show("Complete","Status");
return "Success";
}
public static string ToStr(object readField)
{
if ((readField != null))
{
if (readField.GetType() != typeof(System.DBNull))
{
return Convert.ToString(readField);
}
else
{
return "";
}
}
else
{
return "";
}
}
private void releaseObject(object obj)
{
try
{
System.Runtime.InteropServices.Marshal.ReleaseComObject(obj);
obj = null;
}
catch (Exception ex)
{
obj = null;
MessageBox.Show("Unable to release the Object " + ex.ToString());
}
finally
{
GC.Collect();
}
}

If you plan on only performing a read on the excel file content, I suggest you use the ExcelDataReader library Link, which extracts the worksheetData into a DataSet object.
static void Main(string[] args)
{
IExcelDataReader reader = null;
string FilePath = "PathToExcelFile";
//Load file into a stream
FileStream stream = File.Open(FilePath, FileMode.Open, FileAccess.Read);
//Must check file extension to adjust the reader to the excel file type
if (System.IO.Path.GetExtension(FilePath).Equals(".xls"))
{
reader = ExcelReaderFactory.CreateBinaryReader(stream);
}
else if (System.IO.Path.GetExtension(FilePath).Equals(".xlsx"))
{
reader = ExcelReaderFactory.CreateBinaryReader(stream);
}
if (reader != null)
{
//Fill DataSet
System.Data.DataSet result = reader.AsDataSet();
try
{
//Loop through rows for the desired worksheet
//In this case I use the table index "0" to pick the first worksheet in the workbook
foreach (DataRow row in result.Tables[0].Rows)
{
string FirstColumn = row[0].ToString();
}
}
catch
{
}
}
}

you can use LinqToExcel nuget package
https://www.nuget.org/packages/LinqToExcel/1.10.1
sample code:
string path = #"Users.xlsx";
var excel = new ExcelQueryFactory(path);
return (from c in excel.Worksheet<User>()
select c).OrderBy(a => a.Name).ToList();

Related

How to export Excel from SQL Server Compact on Windows CE [duplicate]

How can i export my data from SQL server 2008 into Excel 2010 or later ?
i have tried on SQL way:
sp_configure 'show advanced options', 0;
GO
RECONFIGURE;
GO
sp_configure 'Ad Hoc Distributed Queries', 0;
GO
RECONFIGURE;
GO
INSERT INTO OPENROWSET('Microsoft.Jet.OLEDB.4.0',
'Excel 8.0;Database=C:\testing.xls;Extended Properties=EXCEL 12.0;HDR=YES',
'SELECT NO_ORDRE, Date FROM [Sheet1$]')
SELECT [NO_ORDRE], GETDATE() FROM ORDRE
GO
Unfortuntely i receive error:
The OLE DB provider 'Microsoft.Jet.OLEDB.4.0' can not be used for distributed queries because the provider is configured to run in STA mode.
and then i tried on C# way:
public class ExportToExcel
{
private Excel.Application app;
private Excel.Workbook workbook;
private Excel.Worksheet previousWorksheet;
// private Excel.Range workSheet_range;
private string folder;
public ExportToExcel(string folder)
{
this.folder = folder;
this.app = null;
this.workbook = null;
this.previousWorksheet = null;
// this.workSheet_range = null;
createDoc();
}
private void createDoc()
{
try
{
app = new Excel.Application();
app.Visible = false;
workbook = app.Workbooks.Add(1);
}
catch (Exception excThrown)
{
throw new Exception(excThrown.Message);
}
finally
{
}
}
public void shutDown()
{
try
{
workbook = null;
app.Quit();
}
catch (Exception excThrown)
{
throw new Exception(excThrown.Message);
}
finally
{
}
}
public void ExportTable(string query, string sheetName)
{
SqlDataReader myReader = null;
try
{
using (var connectionWrapper = new Connexion())
{
var connectedConnection = connectionWrapper.GetConnected();
Excel.Worksheet worksheet = (Excel.Worksheet)workbook.Sheets.Add(Missing.Value, Missing.Value, 1, Excel.XlSheetType.xlWorksheet);
worksheet.Name = sheetName;
previousWorksheet = worksheet;
SqlCommand myCommand = new SqlCommand(query, connectionWrapper.conn);
myReader = myCommand.ExecuteReader();
int columnCount = myReader.FieldCount;
for (int n = 0; n < columnCount; n++)
{
//Console.Write(myReader.GetName(n) + "\t");
createHeaders(worksheet, 1, n + 1, myReader.GetName(n));
}
int rowCounter = 2;
while (myReader.Read())
{
for (int n = 0; n < columnCount; n++)
{
//Console.WriteLine();
//Console.Write(myReader[myReader.GetName(n)].ToString() + "\t");
addData(worksheet, rowCounter, n + 1, myReader[myReader.GetName(n)].ToString());
}
rowCounter++;
}
}
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
finally
{
if (myReader != null && !myReader.IsClosed)
{
myReader.Close();
}
myReader = null;
}
}
public void createHeaders(Excel.Worksheet worksheet, int row, int col, string htext)
{
worksheet.Cells[row, col] = htext;
}
public void addData(Excel.Worksheet worksheet, int row, int col, string data)
{
worksheet.Cells[row, col] = data;
}
public void SaveWorkbook()
{
String folderPath = "C:\\My Files\\" + this.folder;
if (!System.IO.Directory.Exists(folderPath))
{
System.IO.Directory.CreateDirectory(folderPath);
}
string fileNameBase = "db";
String fileName = fileNameBase;
string ext = ".xlsx";
int counter = 1;
while (System.IO.File.Exists(folderPath + fileName + ext))
{
fileName = fileNameBase + counter;
counter++;
}
fileName = fileName + ext;
string filePath = folderPath + fileName;
try
{
workbook.SaveAs(filePath, Excel.XlFileFormat.xlWorkbookDefault, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Excel.XlSaveAsAccessMode.xlNoChange, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value);
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
}
unfortunately i got error:
Retrieving the COM class factory for component with CLSID {00024500-0000-0000-C000-000000000046} failed due to the following error: 80070005 Access is denied. (Exception from HRESULT: 0x80070005 (E_ACCESSDENIED)).
Any idea how can i export SQL to Excel ?
Your best bet might be to just write it out to a CSV. Excel registers itself as the file handler for CSV files, so it will open in excel by default.
For example:
private void SQLToCSV(string query, string Filename)
{
SqlConnection conn = new SqlConnection(connection);
conn.Open();
SqlCommand cmd = new SqlCommand(query, conn);
SqlDataReader dr = cmd.ExecuteReader();
using (System.IO.StreamWriter fs = new System.IO.StreamWriter(Filename))
{
// Loop through the fields and add headers
for (int i = 0; i < dr.FieldCount; i++)
{
string name = dr.GetName(i);
if (name.Contains(","))
name = "\"" + name + "\"";
fs.Write(name + ",");
}
fs.WriteLine();
// Loop through the rows and output the data
while (dr.Read())
{
for (int i = 0; i < dr.FieldCount; i++)
{
string value = dr[i].ToString();
if (value.Contains(","))
value = "\"" + value + "\"";
fs.Write(value + ",");
}
fs.WriteLine();
}
fs.Close();
}
}
C# SQL to Excel
Call you SP from Database
public DataTable GetDrugUtilizationReport_IndividualGenerateFile(long pharmacyId, DateTime from, DateTime to, long DrugNameId, int sortBy)
{
var parameters = new Dictionary<string, object>
{
{ "PharmacyId", pharmacyId },
{ "DateFrom", from },
{ "DateTo", to },
{ "DrugNameId", DrugNameId },
{ "SortBy", sortBy }
};
return ExecuteQuery("RPT_DrugUtilizationReportByIndividualGenerateFile", CommandType.StoredProcedure, parameters);
}
Use in your C# Code
private void OnCreateFileCommand(object obj)
{
string path, parameterLabel;
path = ConfigurationManager.AppSettings["VSSPORTEXELExportPath"];
parameterLabel = FromDate.ToString("yyyy-MM-dd") + "_" + ToDate.ToString("yyyy-MM-dd");
try
{
path =
ExcelUtlity.ExportDataToExcel(
dataTable:
context.GetDrugUtilizationReport_IndividualGenerateFile(GlobalVar.Pharminfo.pharminfo_PK,
FromDate, ToDate, SelectedDrug != null ? SelectedDrug.drugnameid_PK : 0,
sortBy: SortBy + 1),
directoryPath: path,
fileName_withoutExt: "DrugUtilizationReport" + "__" + parameterLabel,
skipComplexObjects: true,
skipInheritedProps: true);
DXMessageBox.Show("Data exported successfully at \"" + path + "\".", GlobalVar.MessageTitle,
MessageBoxButton.OK, MessageBoxImage.Information);
}
catch (Exception ex)
{
string errorMessage = ExceptionHelper.ProcessException(ex);
DXMessageBox.Show(errorMessage, GlobalVar.MessageTitle, MessageBoxButton.OK, MessageBoxImage.Error);
}
}
Excel Utility
public static string ExportDataToExcel(DataTable dataTable, string directoryPath, string fileName_withoutExt, bool skipComplexObjects, bool skipInheritedProps, string[] skipProps = null)
{
if (directoryPath[directoryPath.Length - 1] == '\\') // no need to check for >0 length. let it throw an exection for that
directoryPath = directoryPath + "\\";
using (var spreadSheet = new SpreadsheetControl())
{
// Create new excel document and import the datatable to the worksheet
spreadSheet.CreateNewDocument();
spreadSheet.BeginUpdate();
var worksheet = spreadSheet.Document.Worksheets.ActiveWorksheet;
worksheet.Import(source: dataTable, addHeader: true, firstRowIndex: 0, firstColumnIndex: 0);
// applying style on header
Range range = worksheet.Range["A1:" + worksheet.Columns[worksheet.Columns.LastUsedIndex].Heading+"1"];
Formatting rangeFormatting = range.BeginUpdateFormatting();
rangeFormatting.Fill.BackgroundColor = System.Drawing.Color.LightSteelBlue;
rangeFormatting.Font.FontStyle = SpreadsheetFontStyle.Bold;
range.AutoFitColumns();
range.EndUpdateFormatting(rangeFormatting);
spreadSheet.EndUpdate();
fileName_withoutExt += ".xlsx";
Directory.CreateDirectory(directoryPath); // if directory already exists, CreateDirectory will do nothing
spreadSheet.SaveDocument(directoryPath + fileName_withoutExt, DocumentFormat.OpenXml);
return directoryPath + fileName_withoutExt;
}
}
Using Microsoft Office dll
public bool WriteDataTableToExcel(System.Data.DataTable dataTable, string worksheetName, string saveAsLocation, string ReporType)
{
Microsoft.Office.Interop.Excel.Application excel;
Microsoft.Office.Interop.Excel.Workbook excelworkBook;
Microsoft.Office.Interop.Excel.Worksheet excelSheet;
Microsoft.Office.Interop.Excel.Range excelCellrange;
try
{
// Start Excel and get Application object.
excel = new Microsoft.Office.Interop.Excel.Application();
// for making Excel visible
excel.Visible = false;
excel.DisplayAlerts = false;
// Creation a new Workbook
excelworkBook = excel.Workbooks.Add(Type.Missing);
// Workk sheet
excelSheet = (Microsoft.Office.Interop.Excel.Worksheet)excelworkBook.ActiveSheet;
excelSheet.Name = worksheetName;
excelSheet.Cells[1, 1] = ReporType;
excelSheet.Cells[1, 2] = "Date : " + DateTime.Now.ToShortDateString();
// loop through each row and add values to our sheet
int rowcount = 2;
foreach (DataRow datarow in dataTable.Rows)
{
rowcount += 1;
for (int i = 1; i <= dataTable.Columns.Count; i++)
{
// on the first iteration we add the column headers
if (rowcount == 3)
{
excelSheet.Cells[2, i] = dataTable.Columns[i - 1].ColumnName;
excelSheet.Cells.Font.Color = System.Drawing.Color.Black;
}
excelSheet.Cells[rowcount, i] = datarow[i - 1].ToString();
//for alternate rows
if (rowcount > 3)
{
if (i == dataTable.Columns.Count)
{
if (rowcount % 2 == 0)
{
excelCellrange = excelSheet.Range[excelSheet.Cells[rowcount, 1], excelSheet.Cells[rowcount, dataTable.Columns.Count]];
FormattingExcelCells(excelCellrange, "#CCCCFF", System.Drawing.Color.Black, false);
}
}
}
}
}
// now we resize the columns
excelCellrange = excelSheet.Range[excelSheet.Cells[1, 1], excelSheet.Cells[rowcount, dataTable.Columns.Count]];
excelCellrange.EntireColumn.AutoFit();
Microsoft.Office.Interop.Excel.Borders border = excelCellrange.Borders;
border.LineStyle = Microsoft.Office.Interop.Excel.XlLineStyle.xlContinuous;
border.Weight = 2d;
excelCellrange = excelSheet.Range[excelSheet.Cells[1, 1], excelSheet.Cells[2, dataTable.Columns.Count]];
FormattingExcelCells(excelCellrange, "#000099", System.Drawing.Color.White, true);
//now save the workbook and exit Excel
excelworkBook.SaveAs(saveAsLocation); ;
excelworkBook.Close();
excel.Quit();
return true;
}
catch (Exception ex)
{
DXMessageBox.Show(ex.Message);
return false;
}
finally
{
excelSheet = null;
excelCellrange = null;
excelworkBook = null;
}
}
/// <summary>
/// FUNCTION FOR FORMATTING EXCEL CELLS
/// </summary>
/// <param name="range"></param>
/// <param name="HTMLcolorCode"></param>
/// <param name="fontColor"></param>
/// <param name="IsFontbool"></param>
public void FormattingExcelCells(Microsoft.Office.Interop.Excel.Range range, string HTMLcolorCode, System.Drawing.Color fontColor, bool IsFontbool)
{
range.Interior.Color = System.Drawing.ColorTranslator.FromHtml(HTMLcolorCode);
range.Font.Color = System.Drawing.ColorTranslator.ToOle(fontColor);
if (IsFontbool == true)
{
range.Font.Bold = IsFontbool;
}
}
I have modified code which was given above as and is working. Edit according to your requirements
namespace ExcelExport
{
public class ExportToExcel
{
string strCon = ConfigurationManager.ConnectionStrings["SafewayGVDemoDBContext"].ConnectionString;
private Microsoft.Office.Interop.Excel.Application app;
private Microsoft.Office.Interop.Excel.Workbook workbook;
private Microsoft.Office.Interop.Excel.Worksheet previousWorksheet;
// private Excel.Range workSheet_range;
private string folder;
public ExportToExcel(string folder)
{
this.folder = folder;
this.app = null;
this.workbook = null;
this.previousWorksheet = null;
// this.workSheet_range = null;
createDoc();
}
private void createDoc()
{
try
{
app = new Microsoft.Office.Interop.Excel.Application();
app.Visible = false;
workbook = app.Workbooks.Add(1);
}
catch (Exception excThrown)
{
throw new Exception(excThrown.Message);
}
finally
{
}
}
public void shutDown()
{
try
{
workbook = null;
app.Quit();
}
catch (Exception excThrown)
{
throw new Exception(excThrown.Message);
}
finally
{
}
}
public void ExportTable(string procName, string sheetName)
{
SqlDataReader myReader = null;
try
{
Microsoft.Office.Interop.Excel.Worksheet worksheet = (Microsoft.Office.Interop.Excel.Worksheet)workbook.Sheets.Add(Missing.Value, Missing.Value, 1, Microsoft.Office.Interop.Excel.XlSheetType.xlWorksheet);
using (SqlConnection Sqlcon = new SqlConnection(strCon))
{
SqlCommand cmd = new SqlCommand();
Sqlcon.Open();
cmd.Connection = Sqlcon;
cmd.CommandType = CommandType.StoredProcedure;
cmd.CommandText = procName;
cmd.Parameters.Add(new SqlParameter("#pvchAction", SqlDbType.VarChar, 50));
cmd.Parameters.Add("#pIntErrDescOut", SqlDbType.Int).Direction = ParameterDirection.Output;
cmd.Parameters["#pvchAction"].Value = "select";
worksheet.Name = sheetName;
previousWorksheet = worksheet;
myReader = cmd.ExecuteReader();
int columnCount = myReader.FieldCount;
for (int n = 0; n < columnCount; n++)
{
//Console.Write(myReader.GetName(n) + "\t");
createHeaders(worksheet, 1, n + 1, myReader.GetName(n));
}
int rowCounter = 2;
while (myReader.Read())
{
for (int n = 0; n < columnCount; n++)
{
//Console.WriteLine();
//Console.Write(myReader[myReader.GetName(n)].ToString() + "\t");
addData(worksheet, rowCounter, n + 1, myReader[myReader.GetName(n)].ToString());
}
rowCounter++;
}
}
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
finally
{
if (myReader != null && !myReader.IsClosed)
{
myReader.Close();
}
myReader = null;
}
}
public void createHeaders(Microsoft.Office.Interop.Excel.Worksheet worksheet, int row, int col, string htext)
{
worksheet.Cells[row, col] = htext;
}
public void addData(Microsoft.Office.Interop.Excel.Worksheet worksheet, int row, int col, string data)
{
worksheet.Cells[row, col] = data;
}
public void SaveWorkbook()
{
String folderPath = #"C:\My Files\" + this.folder;
if (!System.IO.Directory.Exists(folderPath))
{
System.IO.Directory.CreateDirectory(folderPath);
}
string fileNameBase = "db";
String fileName = fileNameBase;
string ext = ".xlsx";
int counter = 1;
//System.IO.File.Open(folderPath + fileName + ext, System.IO.FileMode.Open);
while (System.IO.File.Exists(folderPath + #"\"+ fileName + ext))
{
fileName = fileNameBase + counter;
counter++;
}
fileName = fileName + ext;
string filePath = folderPath +#"\"+ fileName;
try
{
workbook.SaveAs(filePath, Microsoft.Office.Interop.Excel.XlFileFormat.xlWorkbookDefault, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Microsoft.Office.Interop.Excel.XlSaveAsAccessMode.xlNoChange, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value);
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
}
Since you're using Excel 2010 the easiest solution is to download PowerPivot from Microsoft and execute the SQL query directly. This will create a refreshable data connection that pulls the data from the Query into a pivot table.
http://www.microsoft.com/bi/en-us/Solutions/Pages/PowerPivot.aspx
This is hundred percent working for VS-2013 Premium for C# for Coded UI testing. just copy and paste the code That's it. Its working for SQL Server database You can save the data into xls, xlsx, or csv and can use that same csv for parameterization. you need to install following packages to make it work.
using System.Data.SqlClient
using Excel=Microsoft.Office.Interop.Excel
using SQL = System.Data
///***Copy from here and paste it under / To generate code for this test, select "Generate Code for Coded UI Test" from the shortcut menu and select one of the menu items.
SqlConnection cnn;
string connectionstring = null;
string sql = null;
string data = null;
int i = 0;
int j = 0;
////*** Preparing excel Application
Excel.Application xlApp;
Excel.Workbook xlWorkBook;
Excel.Worksheet xlWorkSheet;
object misValue = System.Reflection.Missing.Value;
///*** Opening Excel application
xlApp = new Microsoft.Office.Interop.Excel.Application();
xlWorkBook = xlApp.Workbooks.Open(#"C:\Users\MM18100\Documents\Visual Studio 2013\Projects\SQL\SQL\Book1.csv");
xlWorkSheet = (Excel.Worksheet)(xlWorkBook.ActiveSheet as Excel.Worksheet);
////*** It will always remove the prvious result from the CSV file so that we can get always the updated data
xlWorkSheet.UsedRange.Select();
xlWorkSheet.UsedRange.Delete(Excel.XlDeleteShiftDirection.xlShiftUp);
xlApp.DisplayAlerts = false;
//xlWorkBook.Save();
/////***Opening SQL Database
connectionstring = "Integrated Security = SSPI;Initial Catalog=Exascale; Data Source=DCNA-Q-SQL-07;";
cnn = new SqlConnection(connectionstring);
cnn.Open();
////** Write your Sql Query here
sql = "SELECT TOP 10 [FirstName],[MiddleName],[LastName],[Email],[AltEmail],[Phone],[AltPhoneNumber],[Mobile],[Fax],[CompanyName],[AuthorizedUserName],[AuthorizedUserPhone],[CreatedDate],[ModifiedDate],[VERSION],[LanguageID],[TaxID],[CustomerType]FROM [Exascale].[dbo].[Customer] Where [FirstName] = 'Automation'";
///*** Preparing to retrieve value from the database
SQL.DataTable dtable = new SQL.DataTable();
SqlDataAdapter dscmd = new SqlDataAdapter(sql, cnn);
SQL.DataSet ds = new SQL.DataSet();
dscmd.Fill(dtable);
////*** Generating the column Names here
string[] colNames = new string[dtable.Columns.Count];
int col = 0;
foreach (SQL.DataColumn dc in dtable.Columns)
colNames[col++] = dc.ColumnName;
char lastColumn = (char)(65 + dtable.Columns.Count - 1);
xlWorkSheet.get_Range("A1", lastColumn + "1").Value2 = colNames;
xlWorkSheet.get_Range("A1", lastColumn + "1").Font.Bold = true;
xlWorkSheet.get_Range("A1", lastColumn + "1").VerticalAlignment
= Excel.XlVAlign.xlVAlignCenter;
/////*** Inserting the Column and Values into Excel file
for (i = 0 ; i <= dtable.Rows.Count - 1; i++)
{
for (j = 0; j <= dtable.Columns.Count-1; j++)
{
data = dtable.Rows[i].ItemArray[j].ToString();
xlWorkSheet.Cells[i + 2, j + 1] = data;
}
}
///**Saving the csv file without notification.
xlApp.DisplayAlerts = false;
xlWorkBook.Save();
//xlWorkBook.SaveAs("Book1.csv", Excel.XlFileFormat.xlWorkbookNormal, misValue, misValue, misValue, misValue, Excel.XlSaveAsAccessMode.xlExclusive, misValue, misValue, misValue, misValue, misValue);
xlWorkBook.Close(true, misValue, misValue);
xlApp.Quit();
releaseObject(xlWorkSheet);
releaseObject(xlWorkBook);
releaseObject(xlApp);
////MessageBox.Show("Excel file created , you can find the file C:\\Users\\MM18100\\Documents\\informations.xls");
}
private void releaseObject(object obj)
{
try
{
System.Runtime.InteropServices.Marshal.ReleaseComObject(obj);
obj = null;
}
catch (Exception ex)
{
obj = null;
MessageBox.Show("Exception Occured while releasing object " + ex.ToString());
}
finally
{
GC.Collect();
}
}
private void button1_Click(object sender, EventArgs e)
{
string StartDate = Start_Date.Value.Date.ToString("MM/dd/yyyy").Replace("-", "/");
string EndDate = End_Date.Value.Date.ToString("MM/dd/yyyy").Replace("-", "/");
string LogFolder = #"C:\Log\";
try
{
string StoredProcedureName = comboBox1.Text;
SqlConnection SQLConnection = new SqlConnection();
SQLConnection.ConnectionString = ConnectionString;
//Load Data into DataTable from by executing Stored Procedure
string queryString =
"EXEC " + StoredProcedureName + " #Ifromdate ='" + StartDate + "',#Itodate ='" + EndDate+"'";
SqlDataAdapter adapter = new SqlDataAdapter(queryString, SQLConnection);
DataSet ds = new DataSet();
adapter.Fill(ds);
DataTable DtValue = new DataTable();
DtValue = (ds.Tables[0]);
}
catch (Exception exception)
{
// Create Log File for Errors
using (StreamWriter sw = File.CreateText(LogFolder
+ "\\" + "ErrorLog_" + datetime + ".log"))
{
sw.WriteLine(exception.ToString());
}
}
}
///JUST add ClosedXMl.dll
public void DataTableToExcel(DataTable dt)
{
string FileName = "Records";
string SheetName = "Records";
string folderPath = "C:\\New\\";
if (!Directory.Exists(folderPath))
{
Directory.CreateDirectory(folderPath);
}
using (XLWorkbook wb = new XLWorkbook())
{
wb.Worksheets.Add(dt, SheetName);
wb.SaveAs(folderPath + "\\" + FileName + ".xlsx");
}
}
ExcelPackage EP = new ExcelPackage();
ExcelWorksheet Sheet =
EP.Workbook.Worksheets.Add("subscriptions");
Sheet.Cells["A1"].Value = "Email";
Sheet.Cells["A1"].Style.Font.Bold = true;
Sheet.Cells["B1"].Value = "First Name";
Sheet.Cells["B1"].Style.Font.Bold = true;
Sheet.Cells["C1"].Value = "Middle Name";
Sheet.Cells["C1"].Style.Font.Bold = true;
Sheet.Cells["D1"].Value = "Last Name";
Sheet.Cells["D1"].Style.Font.Bold = true;
Sheet.Cells["E1"].Value = "Date Created";
Sheet.Cells["E1"].Style.Font.Bold = true;
Sheet.Cells["F1"].Value = "Subscribed";
Sheet.Cells["F1"].Style.Font.Bold = true;
var collection = MyRepository.GetSubscriptionsAll();
int row = 2;
foreach (var item in collection)
{
Sheet.Cells[string.Format("A{0}", row)].Value = item.Email;
Sheet.Cells[string.Format("B{0}", row)].Value
=item.FistName;
Sheet.Cells[string.Format("C{0}", row)].Value
=item.MiddleName;
Sheet.Cells[string.Format("D{0}", row)].Value
=item.LastName;
Sheet.Cells[string.Format("E{0}", row)].Value =
.DateCreated.ToString();
Sheet.Cells[string.Format("F{0}", row)].Value =
(item.Subscribed == false
? "No" : "Yes"); ;
row++;
}
Sheet.Cells["A:AZ"].AutoFitColumns();
System.Web.HttpContext.Current.Response.Clear();
System.Web.HttpContext.Current.Response.ContentType =
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
System.Web.HttpContext.Current.Response.AddHeader("content-
disposition",
"attachment: filename=" + "ListofSubscribers.xlsx");
System.Web.HttpContext.Current.Response.BinaryWrite(EP.GetAsByteArray());
System.Web.HttpContext.Current.Response.End();
}
Excel 2016 and newer comes with something called Power Query (Older versions will also work but require a separate install). With this tool you can pull data directly from a database into excel.
On the "Data" tab in Excel select "Get Data" --> "From Database" --> "From SQL Server database". Put in the database information and under "Advanced options" you can paste your SQL query in and pull the data directly in Excel. This works for many different database types, flat files and other sources.
2 simple options would be:
1) to use the SQL server import and export wizard, which you can use to Export any table from your database in Excel (Just make sure the mapping is correct)
2) Would be just to run your sql statement and then in your results window below, select all and right click and do a 'Copy with Headers' and then just paste the results in Excel
Bind your data into a grid view....and use the following code .....
protected void ImageButton1_Click1(object sender, ImageClickEventArgs e)
{
string attachment = "attachment; filename=Contacts.xls";
Response.ClearContent();
Response.AddHeader("content-disposition", attachment);
Response.ContentType = "application/ms-excel";
StringWriter sw = new StringWriter();HtmlTextWriter htw = new HtmlTextWriter(sw);
GridView2.RenderControl(htw);
Response.Write(sw.ToString());
Response.End();
}

create an excel file in C# with a file save dialog feature . The excel process will be keep running forever in the background

I am new to C#, working on a project recently. having problem about saving the excel file part. I want the user to be able to choose where to save the file (BTW, I don't want the file to be read-only). It is like file save dialog. I am using C# console .Net. I can save it to a specific location(with a path) now. Another problem, somehow, the excel file created by the program will be running forever in the background. Can anyone please help me? I have been working on this part for 2 days. Thank you so much.
Code:
private static void excelFile(System.Data.DataTable dtTable,List<Dictionary<string, object>> list)
{
Microsoft.Office.Interop.Excel.Application xlApp = new Microsoft.Office.Interop.Excel.Application();
string filepath = AppDomain.CurrentDomain.BaseDirectory;
Console.WriteLine(filepath);
string filename = #"output1.xlsx";
Console.WriteLine(filepath + filename);
// Microsoft.Office.Interop.Excel.Workbook wkbook = null;
var wkbook = xlApp.Workbooks.Add(Type.Missing);
wkbook.SaveAs(ReadOnlyRecommended: false);
_Worksheet wksheet = wkbook.ActiveSheet;
wksheet.Name = "APPLE";
try
{
for (var i = 0; i < dtTable.Columns.Count; i++)
{
wksheet.Cells[1, i + 1] = dtTable.Columns[i].ColumnName;
}
//rows
for (var i = 0; i < dtTable.Rows.Count; i++)
{
for (var j = 0; j < dtTable.Columns.Count; j++)
{
wksheet.Cells[i + 2, j + 1] = dtTable.Rows[i][j];
}
}
//System.IO.FileInfo fileInfo = new System.IO.FileInfo(filename);
//File.SetAttributes(filename, ~FileAttributes.ReadOnly);
//File.SetAttributes(filename, ~FileAttributes.Hidden);
//xlApp.ActiveWorkbook.Save();
// wkbook.Save();
//wkbook.Close();
//xlApp.ActiveWorkbook.Close();
xlApp.Workbooks.Close();
xlApp.Quit();
}
finally
{
if (wksheet != null) Marshal.ReleaseComObject(wksheet);
if (wkbook != null) Marshal.ReleaseComObject(wkbook);
if (xlApp != null) Marshal.ReleaseComObject(xlApp);
}
}
Finally I figured it out. The code below works.(ignore the catch block )
Code:
private static void excelFile(System.Data.DataTable dtTable, List<Dictionary<string, object>> list)
{
// File save dialog
SaveFileDialog saveFileDialog = new SaveFileDialog();
saveFileDialog.Filter = "Execl files (*.xls)|*.xls";
saveFileDialog.FilterIndex = 0;
saveFileDialog.RestoreDirectory = true;
saveFileDialog.CreatePrompt = true;
saveFileDialog.FileName = null;
saveFileDialog.Title = "Save path of the file to be exported";
//string filepath = AppDomain.CurrentDomain.BaseDirectory;
Excel.Application xlApp = null;
Excel.Workbooks wkbooks = null;
Excel.Workbook wkbook = null;
Excel.Sheets wksheets = null;
Excel.Worksheet wksheet = null;
try
{
xlApp = new Excel.Application();
wkbooks = xlApp.Workbooks;
wkbook = wkbooks.Add();
wksheets = wkbook.Sheets;
wksheet = wksheets.Add();
Console.WriteLine(list[0].Values);
wksheet.Name = "APPLE";
try
{
Console.WriteLine("It is working.");
for (var i = 0; i < dtTable.Columns.Count; i++)
{
wksheet.Cells[1, i + 1] = dtTable.Columns[i].ColumnName;
}
//rows
for (var i = 0; i < dtTable.Rows.Count; i++)
{
for (var j = 0; j < dtTable.Columns.Count; j++)
{
wksheet.Cells[i + 2, j + 1] = dtTable.Rows[i][j];
}
}
//wkbook.SaveAs(saveFileDialog, XlFileFormat.xlExcel8,false,
//false, false,false, XlSaveAsAccessMode.xlNoChange, Type.Missing,
//Type.Missing, Type.Missing,Type.Missing, Type.Missing);
Console.WriteLine("Processing!");
Console.WriteLine("File saved.");
wkbooks.Close();
wkbook.Close(false, Missing.Value, Missing.Value);
xlApp.Quit();
}
catch(Exception exp)
{
}
}
catch (Exception e)
{
//Console.WriteLine(e.ToString());
}
finally
{
if (wksheets != null) Marshal.ReleaseComObject(wksheets);
if (wkbook != null) Marshal.ReleaseComObject(wkbook);
if (wkbooks != null) Marshal.ReleaseComObject(wkbooks);
if (xlApp != null) Marshal.ReleaseComObject(xlApp);
}
}
}

The solution to read excel by using C#

Situation:
I'm using C#, and I need to read the content from an excel file.
The content in the excel file will be looks alike as the image.
The first column is the criteria, and the second column is the amount of the criteria. These content will have more than 1000 rows and will be placed at the last sheet of the excel file.
I'm trying to use File Helper to read the content from excel.
But from the example provided, I only know that I can read text file but not excel file.
Questions:
Is there any better example to show me how to read the content from excel by using the FileHelpers?
Is there any other better solution with example that can help me to read the content from excel. Please direct me.
You could ExcelToEnumerable for this. Here's an example:
First define a class that represents a row of spreadsheet data. In your case, it might be something like:
public class SpreadsheetRow
{
public string Category { get; set; }
public int Frequency { get; set; }
}
Then use ExcelToEnumerable to convert the spreadsheet data into an IEnumerable of type SpreadsheetRow
var filePath = "../Path/To/Spreadsheet.xlsx";
IEnumerable<SpreadsheetRow> result = filePath.ExcelToEnumerable<SpreadsheetRow>(x => x.UsingHeaderNames(false)
.Property(y => y.Category).UsesColumnNumber(0)
.Property(y => y.Frequency).UsesColumnNumber(1));
Disclaimer: I'm the author of ExcelToEnumerable
I think you should use OpenXML which will give you excel data in Datatable format and later you can use as per your wish.
static void Main(string[] args)
{
DataTable dt = new DataTable();
using (SpreadsheetDocument spreadSheetDocument = SpreadsheetDocument.Open(#"..\..\example.xlsx", false))
{
WorkbookPart workbookPart = spreadSheetDocument.WorkbookPart;
IEnumerable<Sheet> sheets = spreadSheetDocument.WorkbookPart.Workbook.GetFirstChild<Sheets>().Elements<Sheet>();
string relationshipId = sheets.First().Id.Value;
WorksheetPart worksheetPart = (WorksheetPart)spreadSheetDocument.WorkbookPart.GetPartById(relationshipId);
Worksheet workSheet = worksheetPart.Worksheet;
SheetData sheetData = workSheet.GetFirstChild<SheetData>();
IEnumerable<Row> rows = sheetData.Descendants<Row>();
foreach (Cell cell in rows.ElementAt(0))
{
dt.Columns.Add(GetCellValue(spreadSheetDocument, cell));
}
foreach (Row row in rows) //this will also include your header row...
{
DataRow tempRow = dt.NewRow();
for (int i = 0; i < row.Descendants<Cell>().Count(); i++)
{
tempRow[i] = GetCellValue(spreadSheetDocument, row.Descendants<Cell>().ElementAt(i-1));
}
dt.Rows.Add(tempRow);
}
}
dt.Rows.RemoveAt(0); //...so i'm taking it out here.
}
public static string GetCellValue(SpreadsheetDocument document, Cell cell)
{
SharedStringTablePart stringTablePart = document.WorkbookPart.SharedStringTablePart;
string value = cell.CellValue.InnerXml;
if (cell.DataType != null && cell.DataType.Value == CellValues.SharedString)
{
return stringTablePart.SharedStringTable.ChildElements[Int32.Parse(value)].InnerText;
}
else
{
return value;
}
}
Note: Reference From Excel to DataTable in C# with Open XML
You can read an Excel by using Microsoft.Office.Interop.Excel Library . You can find the full process in attached link
How to read from Excel in C#
using System;
using System.Windows.Forms;
using Excel = Microsoft.Office.Interop.Excel;
namespace WindowsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
Excel.Application xlApp ;
Excel.Workbook xlWorkBook ;
Excel.Worksheet xlWorkSheet ;
Excel.Range range ;
string str;
int rCnt = 0;
int cCnt = 0;
xlApp = new Excel.Application();
xlWorkBook = xlApp.Workbooks.Open("csharp.net-informations.xls", 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;
for (rCnt = 1; rCnt <= range.Rows.Count; rCnt++)
{
for (cCnt = 1; cCnt <= range.Columns.Count; cCnt++)
{
str = (string)(range.Cells[rCnt, cCnt] as Excel.Range).Value2 ;
MessageBox.Show(str);
}
}
xlWorkBook.Close(true, null, null);
xlApp.Quit();
releaseObject(xlWorkSheet);
releaseObject(xlWorkBook);
releaseObject(xlApp);
}
private void releaseObject(object obj)
{
try
{
System.Runtime.InteropServices.Marshal.ReleaseComObject(obj);
obj = null;
}
catch (Exception ex)
{
obj = null;
MessageBox.Show("Unable to release the Object " + ex.ToString());
}
finally
{
GC.Collect();
}
}
}
}

How to read all the rows of the excel sheet and run in Selenium test script using C#?

I need help reading all the rows from excel sheet as a test data in my selenium test case.
I can read only one row of an excel sheet with the following code.
//set up test for selenium
public void SetupTest()
{
selenium = new DefaultSelenium("localhost", 4444, "*googlechrome", "http://www.google.com/");
selenium.Start();
verificationErrors = new StringBuilder();
}
//Connects me to my excel sheet which is SampleTestData.xls
public void ConnectExcel()
{
excel.Application excelApp = new excel.Application();
excelApp.Visible = true;
string ExcelDataPath = #"C:\SampleTestData.xls";
excel.Workbook excelWorkBook = excelApp.Workbooks.Open(ExcelDataPath, 0, false, 5, "", "", false, excel.XlPlatform.xlWindows, "", true, false, 0, true, false, false);
excel.Sheets excelSheets = excelWorkBook.Worksheets;
excel.Worksheet DataworkSheet = (excel.Worksheet)excelSheets.get_Item("Sheet1");
System.String Search1 = ((excel.Range)DataworkSheet.get_Range("A1", Type.Missing)).Value2 as string;
}
//selenium code to run the test
public void StartTest()
{
selenium.open("");
selenium.WaitForPageToLoad("100000");
selenium.Type("gbqfif", search1);
selenium.Click("btnG");
selenium.WaitForPageToLoad("100000");
}
This code lets me select only one row that contains value of search1. However, I need to iterate it such a way that it will keep running StartTest() method until all the rows(50) in the excel sheet are entered.
Any help would be appreciated.
This answer may or may not help you but I am going to take a chance and post 2 samples of code that you can use..
Example #1
using System;
using System.Windows.Forms;
using Excel = Microsoft.Office.Interop.Excel;
namespace WindowsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
Excel.Application xlApp ;
Excel.Workbook xlWorkBook ;
Excel.Worksheet xlWorkSheet ;
Excel.Range range ;
string str;
int rCnt = 0;
int cCnt = 0;
xlApp = new Excel.ApplicationClass();
xlWorkBook = xlApp.Workbooks.Open("csharp.net-informations.xls", 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;
for (rCnt = 1; rCnt <= range.Rows.Count; rCnt++)
{
for (cCnt = 1; cCnt <= range.Columns.Count; cCnt++)
{
str = (string)(range.Cells[rCnt, cCnt] as Excel.Range).Value2 ;
MessageBox.Show(str);
}
}
xlWorkBook.Close(true, null, null);
xlApp.Quit();
releaseObject(xlWorkSheet);
releaseObject(xlWorkBook);
releaseObject(xlApp);
}
private void releaseObject(object obj)
{
try
{
System.Runtime.InteropServices.Marshal.ReleaseComObject(obj);
obj = null;
}
catch (Exception ex)
{
obj = null;
MessageBox.Show("Unable to release the Object " + ex.ToString());
}
finally
{
GC.Collect();
}
}
}
}
Example #2
FileStream stream = File.Open(filePath, FileMode.Open, FileAccess.Read);
//1. Reading from a binary Excel file ('97-2003 format; *.xls)
IExcelDataReader excelReader = ExcelReaderFactory.CreateBinaryReader(stream);
//...
//2. Reading from a OpenXml Excel file (2007 format; *.xlsx)
IExcelDataReader excelReader = ExcelReaderFactory.CreateOpenXmlReader(stream);
//...
//3. DataSet - The result of each spreadsheet will be created in the result.Tables
DataSet result = excelReader.AsDataSet();
//...
//4. DataSet - Create column names from first row
excelReader.IsFirstRowAsColumnNames = true;
DataSet result = excelReader.AsDataSet();
//5. Data Reader methods
while (excelReader.Read())
{
//excelReader.GetInt32(0);
}
//6. Free resources (IExcelDataReader is IDisposable)
excelReader.Close();
Example #3
using (FileStream fileStream = File.Open(inputFilenames[0], FileMode.Open, FileAccess.Read))
{
IExcelDataReader excelReader;
if (Path.GetExtension(inputFilenames[0]) == ".xls")
excelReader = Factory.CreateReader(fileStream, ExcelFileType.Binary);
else
excelReader = Factory.CreateReader(fileStream, ExcelFileType.OpenXml);
excelReader.NextResult();
while (excelReader.Name != this.Worksheet)
excelReader.NextResult();
while (excelReader.Read())
{
if (FirstRowHasColumnNames)
{
FirstRowHasColumnNames = false;
}
else
{
//do stuff
var test = GetColumnData(excelReader, 1);
}
}
this.Save(outputFilename);
}
you can look at this link as well
Reading from Excel File
Try this:-
//Reading from a OpenXml Excel file (2007 format; *.xlsx)
IExcelDataReader excelReader = ExcelReaderFactory.CreateOpenXmlReader(stream);
// DataSet - Create column names from first row
excelReader.IsFirstRowAsColumnNames = true;
DataSet result = excelReader.AsDataSet();
while (excelReader.Read())
{ // Reading from row and get columns by index
var test = excelReader.GetString(1);
}

How to read data of an Excel file using C#?

How to read an Excel file using C#? I open an Excel file for reading and copy it to clipboard to search email format, but I don't know how to do it.
FileInfo finfo;
Excel.ApplicationClass ExcelObj = new Excel.ApplicationClass();
ExcelObj.Visible = false;
Excel.Workbook theWorkbook;
Excel.Worksheet worksheet;
if (listView1.Items.Count > 0)
{
foreach (ListViewItem s in listView1.Items)
{
finfo = new FileInfo(s.Text);
if (finfo.Extension == ".xls" || finfo.Extension == ".xlsx" || finfo.Extension == ".xlt" || finfo.Extension == ".xlsm" || finfo.Extension == ".csv")
{
theWorkbook = ExcelObj.Workbooks.Open(s.Text, 0, true, 5, "", "", true, Excel.XlPlatform.xlWindows, "\t", false, false, 0, true, false, false);
for (int count = 1; count <= theWorkbook.Sheets.Count; count++)
{
worksheet = (Excel.Worksheet)theWorkbook.Worksheets.get_Item(count);
worksheet.Activate();
worksheet.Visible = false;
worksheet.UsedRange.Cells.Select();
}
}
}
}
OK,
One of the more difficult concepts to grasp about Excel VSTO programming is that you don't refer to cells like an array, Worksheet[0][0] won't give you cell A1, it will error out on you. Even when you type into A1 when Excel is open, you are actually entering data into Range A1. Therefore you refer to cells as Named Ranges. Here's an example:
Excel.Worksheet sheet = workbook.Sheets["Sheet1"] as Excel.Worksheet;
Excel.Range range = sheet.get_Range("A1", Missing.Value)
You can now literally type:
range.Text // this will give you the text the user sees
range.Value2 // this will give you the actual value stored by Excel (without rounding)
If you want to do something like this:
Excel.Range range = sheet.get_Range("A1:A5", Missing.Value)
if (range1 != null)
foreach (Excel.Range r in range1)
{
string user = r.Text
string value = r.Value2
}
There might be a better way, but this has worked for me.
The reason you need to use Value2 and not Value is because the Value property is a parametrized and C# doesn't support them yet.
As for the cleanup code, i will post that when i get to work tomorrow, i don't have the code with me, but it's very boilerplate. You just close and release the objects in the reverse order you created them. You can't use a Using() block because the Excel.Application or Excel.Workbook doesn't implement IDisposable, and if you don't clean-up, you will be left with a hanging Excel objects in memory.
Note:
If you don't set the Visibility property Excel doesn't display, which can be disconcerting to your users, but if you want to just rip the data out, that is probably good enough
You could OleDb, that will work too.
I hope that gets you started, let me know if you need further clarification. I'll post a complete
here is a complete sample:
using System;
using System.IO;
using System.Reflection;
using NUnit.Framework;
using ExcelTools = Ms.Office;
using Excel = Microsoft.Office.Interop.Excel;
namespace Tests
{
[TestFixture]
public class ExcelSingle
{
[Test]
public void ProcessWorkbook()
{
string file = #"C:\Users\Chris\Desktop\TestSheet.xls";
Console.WriteLine(file);
Excel.Application excel = null;
Excel.Workbook wkb = null;
try
{
excel = new Excel.Application();
wkb = ExcelTools.OfficeUtil.OpenBook(excel, file);
Excel.Worksheet sheet = wkb.Sheets["Data"] as Excel.Worksheet;
Excel.Range range = null;
if (sheet != null)
range = sheet.get_Range("A1", Missing.Value);
string A1 = String.Empty;
if( range != null )
A1 = range.Text.ToString();
Console.WriteLine("A1 value: {0}", A1);
}
catch(Exception ex)
{
//if you need to handle stuff
Console.WriteLine(ex.Message);
}
finally
{
if (wkb != null)
ExcelTools.OfficeUtil.ReleaseRCM(wkb);
if (excel != null)
ExcelTools.OfficeUtil.ReleaseRCM(excel);
}
}
}
}
I'll post the functions from ExcelTools tomorrow, I don't have that code with me either.
Edit:
As promised, here are the Functions from ExcelTools you might need.
public static Excel.Workbook OpenBook(Excel.Application excelInstance, string fileName, bool readOnly, bool editable,
bool updateLinks) {
Excel.Workbook book = excelInstance.Workbooks.Open(
fileName, updateLinks, readOnly,
Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing,
Type.Missing, editable, Type.Missing, Type.Missing, Type.Missing,
Type.Missing, Type.Missing);
return book;
}
public static void ReleaseRCM(object o) {
try {
System.Runtime.InteropServices.Marshal.ReleaseComObject(o);
} catch {
} finally {
o = null;
}
}
To be frank, this stuff is much easier if you use VB.NET. It's in C# because I didn't write it. VB.NET does option parameters well, C# does not, hence the Type.Missing. Once you typed Type.Missing twice in a row, you run screaming from the room!
As for you question, you can try to following:
http://msdn.microsoft.com/en-us/library/microsoft.office.interop.excel.range.find(VS.80).aspx
I will post an example when I get back from my meeting... cheers
Edit: Here is an example
range = sheet.Cells.Find("Value to Find",
Type.Missing,
Type.Missing,
Type.Missing,
Type.Missing,
Excel.XlSearchDirection.xlNext,
Type.Missing,
Type.Missing, Type.Missing);
range.Text; //give you the value found
Here is another example inspired by this site:
range = sheet.Cells.Find("Value to find", Type.Missing, Type.Missing,Excel.XlLookAt.xlWhole,Excel.XlSearchOrder.xlByColumns,Excel.XlSearchDirection.xlNext,false, false, Type.Missing);
It helps to understand the parameters.
P.S. I'm one of those weird people who enjoys learning COM automation. All this code steamed from a tool I wrote for work which required me to process over 1000+ spreadsheets from the lab each Monday.
You can use Microsoft.Office.Interop.Excel assembly to process excel files.
Right click on your project and go to Add reference. Add the
Microsoft.Office.Interop.Excel assembly.
Include using
Microsoft.Office.Interop.Excel; to make use of assembly.
Here is the sample code:
using Microsoft.Office.Interop.Excel;
//create the Application object we can use in the member functions.
Microsoft.Office.Interop.Excel.Application _excelApp = new Microsoft.Office.Interop.Excel.Application();
_excelApp.Visible = true;
string fileName = "C:\\sampleExcelFile.xlsx";
//open the workbook
Workbook workbook = _excelApp.Workbooks.Open(fileName,
Type.Missing, Type.Missing, Type.Missing, Type.Missing,
Type.Missing, Type.Missing, Type.Missing, Type.Missing,
Type.Missing, Type.Missing, Type.Missing, Type.Missing,
Type.Missing, Type.Missing);
//select the first sheet
Worksheet worksheet = (Worksheet)workbook.Worksheets[1];
//find the used range in worksheet
Range excelRange = worksheet.UsedRange;
//get an object array of all of the cells in the worksheet (their values)
object[,] valueArray = (object[,])excelRange.get_Value(
XlRangeValueDataType.xlRangeValueDefault);
//access the cells
for (int row = 1; row <= worksheet.UsedRange.Rows.Count; ++row)
{
for (int col = 1; col <= worksheet.UsedRange.Columns.Count; ++col)
{
//access each cell
Debug.Print(valueArray[row, col].ToString());
}
}
//clean up stuffs
workbook.Close(false, Type.Missing, Type.Missing);
Marshal.ReleaseComObject(workbook);
_excelApp.Quit();
Marshal.FinalReleaseComObject(_excelApp);
Why don't you create OleDbConnection? There are a lot of available resources in the Internet. Here is an example
OleDbConnection con = new OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source="+filename+";Extended Properties=Excel 8.0");
con.Open();
try
{
//Create Dataset and fill with imformation from the Excel Spreadsheet for easier reference
DataSet myDataSet = new DataSet();
OleDbDataAdapter myCommand = new OleDbDataAdapter(" SELECT * FROM ["+listname+"$]" , con);
myCommand.Fill(myDataSet);
con.Close();
richTextBox1.AppendText("\nDataSet Filled");
//Travers through each row in the dataset
foreach (DataRow myDataRow in myDataSet.Tables[0].Rows)
{
//Stores info in Datarow into an array
Object[] cells = myDataRow.ItemArray;
//Traverse through each array and put into object cellContent as type Object
//Using Object as for some reason the Dataset reads some blank value which
//causes a hissy fit when trying to read. By using object I can convert to
//String at a later point.
foreach (object cellContent in cells)
{
//Convert object cellContect into String to read whilst replacing Line Breaks with a defined character
string cellText = cellContent.ToString();
cellText = cellText.Replace("\n", "|");
//Read the string and put into Array of characters chars
richTextBox1.AppendText("\n"+cellText);
}
}
//Thread.Sleep(15000);
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
//Thread.Sleep(15000);
}
finally
{
con.Close();
}
try
{
DataTable sheet1 = new DataTable("Excel Sheet");
OleDbConnectionStringBuilder csbuilder = new OleDbConnectionStringBuilder();
csbuilder.Provider = "Microsoft.ACE.OLEDB.12.0";
csbuilder.DataSource = fileLocation;
csbuilder.Add("Extended Properties", "Excel 12.0 Xml;HDR=YES");
string selectSql = #"SELECT * FROM [Sheet1$]";
using (OleDbConnection connection = new OleDbConnection(csbuilder.ConnectionString))
using (OleDbDataAdapter adapter = new OleDbDataAdapter(selectSql, connection))
{
connection.Open();
adapter.Fill(sheet1);
}
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
This worked for me. Please try it and let me know for queries.
First of all, it's important to know what you mean by "open an Excel file for reading and copy it to clipboard..."
This is very important because there are many ways you could do that depending just on what you intend to do. Let me explain:
If you want to read a set of data and copy that in the clipboard and you know the data format (e.g. column names), I suggest you use an OleDbConnection to open the file, this way you can treat the xls file content as a Database Table, so you can read data with SQL instruction and treat the data as you want.
If you want to do operations on the data with the Excel object model then open it in the way you began.
Some time it's possible to treat an xls file as a kind of csv file, there are tools like File Helpers which permit you to treat and open an xls file in a simple way by mapping a structure on an arbitrary object.
Another important point is in which Excel version the file is.
I have, unfortunately I say, a strong experience working with Office automation in all ways, even if bounded in concepts like Application Automation, Data Management and Plugins, and generally I suggest only as the last resort, to using Excel automation or Office automation to read data; just if there aren't better ways to accomplish that task.
Working with automation could be heavy in performance, in terms of resource cost, could involve in other issues related for example to security and more, and last but not at least, working with COM interop it's not so "free"..
So my suggestion is think and analyze the situation within your needs and then take the better way.
Here's a 2020 answer - if you don't need to support the older .xls format (so pre 2003) you could use either:
LightweightExcelReader to access specfic cells, or cursor through all the data in a spreadsheet.
or
ExcelToEnumerable if you want to map spreadsheet data to a list of objects.
Pros :
Performance - at the time of writing (the the fastest way to read an .xlsx file)[https://github.com/ChrisHodges/ExcelToEnumerable#performance].
Simplicity - less verbose than OLE DB or OpenXml
Cons:
Neither LightweightExcelReader nor ExcelToEnumerable support .xls files.
Disclaimer: I am the author of LightweightExcelReader and ExcelToEnumerable
Use Open XML.
Here is some code to process a spreadsheet with a specific tab or sheet name and dump it to something like CSV. (I chose a pipe instead of comma).
I wish it was easier to get the value from a cell, but I think this is what we are stuck with. You can see that I reference the MSDN documents where I got most of this code. That is what Microsoft recommends.
/// <summary>
/// Got code from: https://msdn.microsoft.com/en-us/library/office/gg575571.aspx
/// </summary>
[Test]
public void WriteOutExcelFile()
{
var fileName = "ExcelFiles\\File_With_Many_Tabs.xlsx";
var sheetName = "Submission Form"; // Existing tab name.
using (var document = SpreadsheetDocument.Open(fileName, isEditable: false))
{
var workbookPart = document.WorkbookPart;
var sheet = workbookPart.Workbook.Descendants<Sheet>().FirstOrDefault(s => s.Name == sheetName);
var worksheetPart = (WorksheetPart)(workbookPart.GetPartById(sheet.Id));
var sheetData = worksheetPart.Worksheet.Elements<SheetData>().First();
foreach (var row in sheetData.Elements<Row>())
{
foreach (var cell in row.Elements<Cell>())
{
Console.Write("|" + GetCellValue(cell, workbookPart));
}
Console.Write("\n");
}
}
}
/// <summary>
/// Got code from: https://msdn.microsoft.com/en-us/library/office/hh298534.aspx
/// </summary>
/// <param name="cell"></param>
/// <param name="workbookPart"></param>
/// <returns></returns>
private string GetCellValue(Cell cell, WorkbookPart workbookPart)
{
if (cell == null)
{
return null;
}
var value = cell.CellFormula != null
? cell.CellValue.InnerText
: cell.InnerText.Trim();
// If the cell represents an integer number, you are done.
// For dates, this code returns the serialized value that
// represents the date. The code handles strings and
// Booleans individually. For shared strings, the code
// looks up the corresponding value in the shared string
// table. For Booleans, the code converts the value into
// the words TRUE or FALSE.
if (cell.DataType == null)
{
return value;
}
switch (cell.DataType.Value)
{
case CellValues.SharedString:
// For shared strings, look up the value in the
// shared strings table.
var stringTable =
workbookPart.GetPartsOfType<SharedStringTablePart>()
.FirstOrDefault();
// If the shared string table is missing, something
// is wrong. Return the index that is in
// the cell. Otherwise, look up the correct text in
// the table.
if (stringTable != null)
{
value =
stringTable.SharedStringTable
.ElementAt(int.Parse(value)).InnerText;
}
break;
case CellValues.Boolean:
switch (value)
{
case "0":
value = "FALSE";
break;
default:
value = "TRUE";
break;
}
break;
}
return value;
}
Use OLEDB Connection to communicate with excel files. it gives better result
using System.Data.OleDb;
string physicalPath = "Your Excel file physical path";
OleDbCommand cmd = new OleDbCommand();
OleDbDataAdapter da = new OleDbDataAdapter();
DataSet ds = new DataSet();
String strNewPath = physicalPath;
String connString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + strNewPath + ";Extended Properties=\"Excel 12.0;HDR=Yes;IMEX=2\"";
String query = "SELECT * FROM [Sheet1$]"; // You can use any different queries to get the data from the excel sheet
OleDbConnection conn = new OleDbConnection(connString);
if (conn.State == ConnectionState.Closed) conn.Open();
try
{
cmd = new OleDbCommand(query, conn);
da = new OleDbDataAdapter(cmd);
da.Fill(ds);
}
catch
{
// Exception Msg
}
finally
{
da.Dispose();
conn.Close();
}
The Output data will be stored in dataset, using the dataset object you can easily access the datas.
Hope this may helpful
Using OlebDB, we can read excel file in C#, easily, here is the code while working with Web-Form, where FileUpload1 is file uploading tool
string path = Server.MapPath("~/Uploads/");
if (!Directory.Exists(path))
{
Directory.CreateDirectory(path);
}
//get file path
filePath = path + Path.GetFileName(FileUpload1.FileName);
//get file extenstion
string extension = Path.GetExtension(FileUpload1.FileName);
//save file on "Uploads" folder of project
FileUpload1.SaveAs(filePath);
string conString = string.Empty;
//check file extension
switch (extension)
{
case ".xls": //Excel 97-03.
conString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=Excel03ConString;Extended Properties='Excel 8.0;HDR=YES'";
break;
case ".xlsx": //Excel 07 and above.
conString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=Excel07ConString;Extended Properties='Excel 8.0;HDR=YES'";
break;
}
//create datatable object
DataTable dt = new DataTable();
conString = string.Format(conString, filePath);
//Use OldDb to read excel
using (OleDbConnection connExcel = new OleDbConnection(conString))
{
using (OleDbCommand cmdExcel = new OleDbCommand())
{
using (OleDbDataAdapter odaExcel = new OleDbDataAdapter())
{
cmdExcel.Connection = connExcel;
//Get the name of First Sheet.
connExcel.Open();
DataTable dtExcelSchema;
dtExcelSchema = connExcel.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, null);
string sheetName = dtExcelSchema.Rows[0]["TABLE_NAME"].ToString();
connExcel.Close();
//Read Data from First Sheet.
connExcel.Open();
cmdExcel.CommandText = "SELECT * From [" + sheetName + "]";
odaExcel.SelectCommand = cmdExcel;
odaExcel.Fill(dt);
connExcel.Close();
}
}
}
//bind datatable with GridView
GridView1.DataSource = dt;
GridView1.DataBind();
Source : https://qawithexperts.com/article/asp-net/read-excel-file-and-import-data-into-gridview-using-datatabl/209
Console application similar code example
https://qawithexperts.com/article/c-sharp/read-excel-file-in-c-console-application-example-using-oledb/168
If you need don't want to use OleDB, you can try https://github.com/ExcelDataReader/ExcelDataReader
which seems to have the ability to handle both formats (.xls and .xslx)
Excel File Reader & Writer Without Excel On u'r System
Download and add the dll for
NPOI u'r project.
Using this code to read a excel file.
using (FileStream file = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{
XSSFWorkbook XSSFWorkbook = new XSSFWorkbook(file);
}
ISheet objxlWorkSheet = XSSFWorkbook.GetSheetAt(0);
int intRowCount = 1;
int intColumnCount = 0;
for (; ; )
{
IRow Row = objxlWorkSheet.GetRow(intRowCount);
if (Row != null)
{
ICell Cell = Row.GetCell(0);
ICell objCell = objxlWorkSheet.GetRow(intRowCount).GetCell(intColumnCount); }}
You can use ExcelDataReader see GitHub
You need to install nugets :
-ExcelDataReader
-ExcelDataReader.DataSet
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.IO;
using ExcelDataReader;
using System.Text;
/// <summary>
/// Excel parsing in this class is performed by using a common shareware Lib found on:
/// https://github.com/ExcelDataReader/ExcelDataReader
/// </summary>
public static class ExcelParser
{
/// <summary>
/// Load, read and get values from Excel sheet
/// </summary>
public static List<FileRow> GetExcelRows(string path, string sheetName, bool skipFirstLine)
{
if (File.Exists(path))
{
return GetValues(path, sheetName, skipFirstLine);
}
else
throw new Exception("The process cannot access the file");
}
/// <summary>
/// Parse sheet names from given Excel file.
/// </summary>
public static List<string> GetSheetNames(string path)
{
using (var stream = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read))
{
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
using (var excelReader = GetExcelDataReader(path, stream))
{
var dataset = excelReader.AsDataSet(new ExcelDataSetConfiguration()
{
ConfigureDataTable = (_) => new ExcelDataTableConfiguration()
{
UseHeaderRow = true
}
});
var names = from DataTable table in dataset.Tables
select table.TableName;
return names.ToList();
}
}
}
/// <summary>
/// Parse values from Excel sheet and add to Rows collection.
/// </summary>
public static List<FileRow> GetValues(string path, string sheetName, bool skipFirstLine)
{
var rowItems = new List<FileRow>();
using (var stream = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read))
{
using (var excelReader = GetExcelDataReader(path, stream))
{
var dataset = excelReader.AsDataSet(new ExcelDataSetConfiguration()
{
ConfigureDataTable = (_) => new ExcelDataTableConfiguration()
{
UseHeaderRow = skipFirstLine
}
});
foreach (DataRow row in dataset.Tables[sheetName].Rows)
{
var rowItem = new FileRow();
foreach (var value in row.ItemArray)
rowItem.Values.Add(value);
rowItems.Add(rowItem);
}
}
}
return rowItems;
}
private static IExcelDataReader GetExcelDataReader(string path, Stream stream)
{
var extension = GetExtension(path);
switch (extension)
{
case "xls":
return ExcelReaderFactory.CreateBinaryReader(stream);
case "xlsx":
return ExcelReaderFactory.CreateOpenXmlReader(stream);
default:
throw new Exception(string.Format("'{0}' is not a valid Excel extension", extension));
}
}
private static string GetExtension(string path)
{
var extension = Path.GetExtension(path);
return extension == null ? null : extension.ToLower().Substring(1);
}
}
With this entity :
public class FileRow
{
public List<object> Values { get; set; }
public FileRow()
{
Values = new List<object>();
}
}
Use like that :
var txtPath = #"D:\Path\excelfile.xlsx";
var sheetNames = ExcelParser.GetSheetNames(txtPath);
var datas = ExcelParser.GetExcelRows(txtPath, sheetNames[0], true);
The recommended way to read Excel files on server side app is Open XML.
Sharing few links -
https://msdn.microsoft.com/en-us/library/office/hh298534.aspx
https://msdn.microsoft.com/en-us/library/office/ff478410.aspx
https://msdn.microsoft.com/en-us/library/office/cc823095.aspx
public void excelRead(string sheetName)
{
Excel.Application appExl = new Excel.Application();
Excel.Workbook workbook = null;
try
{
string methodName = "";
Excel.Worksheet NwSheet;
Excel.Range ShtRange;
//Opening Excel file(myData.xlsx)
appExl = new Excel.Application();
workbook = appExl.Workbooks.Open(sheetName, Missing.Value, ReadOnly: false);
NwSheet = (Excel.Worksheet)workbook.Sheets.get_Item(1);
ShtRange = NwSheet.UsedRange; //gives the used cells in sheet
int rCnt1 = 0;
int cCnt1 = 0;
for (rCnt1 = 1; rCnt1 <= ShtRange.Rows.Count; rCnt1++)
{
for (cCnt1 = 1; cCnt1 <= ShtRange.Columns.Count; cCnt1++)
{
if (Convert.ToString(NwSheet.Cells[rCnt1, cCnt1].Value2) == "Y")
{
methodName = NwSheet.Cells[rCnt1, cCnt1 - 2].Value2;
Type metdType = this.GetType();
MethodInfo mthInfo = metdType.GetMethod(methodName);
if (Convert.ToString(NwSheet.Cells[rCnt1, cCnt1 - 2].Value2) == "fn_AddNum" || Convert.ToString(NwSheet.Cells[rCnt1, cCnt1 - 2].Value2) == "fn_SubNum")
{
StaticVariable.intParam1 = Convert.ToInt32(NwSheet.Cells[rCnt1, cCnt1 + 3].Value2);
StaticVariable.intParam2 = Convert.ToInt32(NwSheet.Cells[rCnt1, cCnt1 + 4].Value2);
object[] mParam1 = new object[] { StaticVariable.intParam1, StaticVariable.intParam2 };
object result = mthInfo.Invoke(this, mParam1);
StaticVariable.intOutParam1 = Convert.ToInt32(result);
NwSheet.Cells[rCnt1, cCnt1 + 5].Value2 = Convert.ToString(StaticVariable.intOutParam1) != "" ? Convert.ToString(StaticVariable.intOutParam1) : String.Empty;
}
else
{
object[] mParam = new object[] { };
mthInfo.Invoke(this, mParam);
NwSheet.Cells[rCnt1, cCnt1 + 5].Value2 = StaticVariable.outParam1 != "" ? StaticVariable.outParam1 : String.Empty;
NwSheet.Cells[rCnt1, cCnt1 + 6].Value2 = StaticVariable.outParam2 != "" ? StaticVariable.outParam2 : String.Empty;
}
NwSheet.Cells[rCnt1, cCnt1 + 1].Value2 = StaticVariable.resultOut;
NwSheet.Cells[rCnt1, cCnt1 + 2].Value2 = StaticVariable.resultDescription;
}
else if (Convert.ToString(NwSheet.Cells[rCnt1, cCnt1].Value2) == "N")
{
MessageBox.Show("Result is No");
}
else if (Convert.ToString(NwSheet.Cells[rCnt1, cCnt1].Value2) == "EOF")
{
MessageBox.Show("End of File");
}
}
}
workbook.Save();
workbook.Close(true, Missing.Value, Missing.Value);
appExl.Quit();
System.Runtime.InteropServices.Marshal.FinalReleaseComObject(ShtRange);
System.Runtime.InteropServices.Marshal.FinalReleaseComObject(NwSheet);
System.Runtime.InteropServices.Marshal.FinalReleaseComObject(workbook);
System.Runtime.InteropServices.Marshal.FinalReleaseComObject(appExl);
}
catch (Exception)
{
workbook.Close(true, Missing.Value, Missing.Value);
}
finally
{
GC.Collect();
GC.WaitForPendingFinalizers();
System.Runtime.InteropServices.Marshal.CleanupUnusedObjectsInCurrentContext();
}
}
//code for reading excel data in datatable
public void testExcel(string sheetName)
{
try
{
MessageBox.Show(sheetName);
foreach(Process p in Process.GetProcessesByName("EXCEL"))
{
p.Kill();
}
//string fileName = "E:\\inputSheet";
Excel.Application oXL;
Workbook oWB;
Worksheet oSheet;
Range oRng;
// creat a Application object
oXL = new Excel.Application();
// get WorkBook object
oWB = oXL.Workbooks.Open(sheetName);
// get WorkSheet object
oSheet = (Microsoft.Office.Interop.Excel.Worksheet)oWB.Sheets[1];
System.Data.DataTable dt = new System.Data.DataTable();
//DataSet ds = new DataSet();
//ds.Tables.Add(dt);
DataRow dr;
StringBuilder sb = new StringBuilder();
int jValue = oSheet.UsedRange.Cells.Columns.Count;
int iValue = oSheet.UsedRange.Cells.Rows.Count;
// get data columns
for (int j = 1; j <= jValue; j++)
{
oRng = (Microsoft.Office.Interop.Excel.Range)oSheet.Cells[1, j];
string strValue = oRng.Text.ToString();
dt.Columns.Add(strValue, System.Type.GetType("System.String"));
}
//string colString = sb.ToString().Trim();
//string[] colArray = colString.Split(':');
// get data in cell
for (int i = 2; i <= iValue; i++)
{
dr = dt.NewRow();
for (int j = 1; j <= jValue; j++)
{
oRng = (Microsoft.Office.Interop.Excel.Range)oSheet.Cells[i, j];
string strValue = oRng.Text.ToString();
dr[j - 1] = strValue;
}
dt.Rows.Add(dr);
}
if(StaticVariable.dtExcel != null)
{
StaticVariable.dtExcel.Clear();
StaticVariable.dtExcel = dt.Copy();
}
else
StaticVariable.dtExcel = dt.Copy();
oWB.Close(true, Missing.Value, Missing.Value);
oXL.Quit();
MessageBox.Show(sheetName);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
finally
{
}
}
//code for class initialize
public static void startTesting(TestContext context)
{
Playback.Initialize();
ReadExcel myClassObj = new ReadExcel();
string sheetName="";
StreamReader sr = new StreamReader(#"E:\SaveSheetName.txt");
sheetName = sr.ReadLine();
sr.Close();
myClassObj.excelRead(sheetName);
myClassObj.testExcel(sheetName);
}
//code for test initalize
public void runValidatonTest()
{
DataTable dtFinal = StaticVariable.dtExcel.Copy();
for (int i = 0; i < dtFinal.Rows.Count; i++)
{
if (TestContext.TestName == dtFinal.Rows[i][2].ToString() && dtFinal.Rows[i][3].ToString() == "Y" && dtFinal.Rows[i][4].ToString() == "TRUE")
{
MessageBox.Show(TestContext.TestName);
MessageBox.Show(dtFinal.Rows[i][2].ToString());
StaticVariable.runValidateResult = "true";
break;
}
}
//StaticVariable.dtExcel = dtFinal.Copy();
}
I'd recommend you to use Bytescout Spreadsheet.
https://bytescout.com/products/developer/spreadsheetsdk/bytescoutspreadsheetsdk.html
I tried it with Monodevelop in Unity3D and it is pretty straight forward. Check this sample code to see how the library works:
https://bytescout.com/products/developer/spreadsheetsdk/read-write-excel.html

Categories

Resources