Pass Excel data to C# Desktop Application - c#

I am looking to pass information from an excel workbook into a C# application that is already open by the user.
Currently, we have an excel workbook with a list of procedure reviews which are summarised as values. For example, a pass is a 1, a minor is 0 and a fail is -1.
This is listed in a sheet with two columns, the name of the procedure and the pass value;
| Procedure | Value
|------------|------------
| Test 1 | 1
| Test 2 | 0
| Test 3 | -1
I would like to take this table and pass it to our reporting application so that it can be manipulated in the front-end and then sent to a database.
Is there any way to create a pipe that will allow for the data to be passed tot he C# application, such as when a button is clicked?

Maybe try this:
Microsoft.Office.Interop.Excel.Application _excelApp = new Microsoft.Office.Interop.Excel.Application();
_excelApp.Visible = false;
string fileName = String.Empty;
OpenFileDialog ofd = new OpenFileDialog();
if (ofd.ShowDialog() == DialogResult.OK)
{
fileName = ofd.FileName;
//open the workbook
Microsoft.Office.Interop.Excel.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 or tell it the name of the sheet you want
if ((Microsoft.Office.Interop.Excel.Worksheet)workbook.Worksheets.get_Item("Worksheet") == null)
{
MessageBox.Show("Not a valid workbook");
}
else
{
Microsoft.Office.Interop.Excel.Worksheet worksheet = (Microsoft.Office.Interop.Excel.Worksheet)workbook.Worksheets.get_Item("Worksheet");
//select how you want data to be transferred into your c# application?
tTag.Text = worksheet.get_Range("B2", System.Reflection.Missing.Value).Text;
//clean up stuffs
workbook.Close(false, Type.Missing, Type.Missing);
System.Runtime.InteropServices.Marshal.ReleaseComObject(workbook);
_excelApp.Quit();
System.Runtime.InteropServices.Marshal.FinalReleaseComObject(_excelApp);
}
}

Related

How to identify the Excel custom property is exists or not?

using Excel = Microsoft.Office.Interop.Excel;
I am using a method to set Excel custom property but if the property already exists it throws exception, and also how i can update the property if it already exists
public Excel.Workbook workBk;
Application _excelApp;
public void SetDocumentProperty(string propertyName, string propertyValue)
{
try
{
_excelApp = new Application();
workBk = _excelApp.Workbooks.Open(#"C:\12345.xlsx",
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);
object oDocCustomProps = workBk.CustomDocumentProperties;
Type typeDocCustomProps = oDocCustomProps.GetType();
object[] oArgs = {propertyName,false,
MsoDocProperties.msoPropertyTypeString,
propertyValue};
typeDocCustomProps.InvokeMember("Add", BindingFlags.Default |
BindingFlags.InvokeMethod, null,
oDocCustomProps, oArgs);
workBk.Save();
}
finally
{
workBk.Close(false, #"C:\12345.xlsx", null);
Marshal.ReleaseComObject(workBk);
}
}
string [] files = System.IO.Directory.GetFiles(directory);
u can use server mappath if u puting the excel file in u project like this
string[] files = System.IO.Directory.GetFiles(Server.MapPath("~\upload"));
this line will give u all the files that already exist in a directory this way u can check if file already exist without getting an exception

Copy an Excel sheet to new sheet including formatting - C#

I need to create one method that it's able to copy an excel sheet and then, paste it on a new excel sheet in the same workbook, but it's necessary to copy the formatting as well.
I found several codes, but all of them not copy the formatting, only the text.
below the code that I wrote:
// Opening Excel File
Microsoft.Office.Interop.Excel.Application excel = null;
excel = new Microsoft.Office.Interop.Excel.Application();
Microsoft.Office.Interop.Excel.Workbook workbook = excel.Workbooks.Open(file, 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);
Microsoft.Office.Interop.Excel.Sheets sheets = workbook.Worksheets;
Microsoft.Office.Interop.Excel.Worksheet sheet = (Microsoft.Office.Interop.Excel.Worksheet)sheets.get_Item(1);
Microsoft.Office.Interop.Excel.Worksheet sheet2 = (Microsoft.Office.Interop.Excel.Worksheet)sheets.get_Item(2);
// Copy the source sheet
Object defaultArg = Type.Missing;
sheet = (Worksheet)workbook.Sheets[1];
sheet.UsedRange.Copy(defaultArg);
// Paste on destination sheet
sheet2.UsedRange._PasteSpecial(XlPasteType.xlPasteValues, XlPasteSpecialOperation.xlPasteSpecialOperationNone, false, false);
workbook.Save();
common.closeExcel(excel, workbook);
If anybody has any suggestion, please let me know.
Thanks,
This will make an exact copy of a sheet to a new sheet renamed as the original :
Dim x = 2
For numtimes = 1 To x
Sheet1.Copy _
After:=Sheet1
Next

update a value in a cell and all other cells will be automatically changed

For example, I have a spreadsheet excel. I want to read it using C#.
In the spreadsheet, I have two or more cell:
A1 = 0
B1 = A1 + 7
Is it possible that if I change the value of A1 to 1 using C# and then the B1 cell will be automatically updated?
The second cell will auto update. Here's some code using MS Excel Object Model (include Microsoft.Interop.Excel.dll):
using System;
namespace exceltest2
{
using Microsoft.Office.Interop.Excel;
internal class Program
{
private static void Main(string[] args)
{
Application excel = null;
Workbook wb = null;
try
{
// run Excel
excel = new Application();
excel.Visible = false;
// Open file
wb = excel.Workbooks.Open(
#"D:\test.xlsx", Type.Missing, false, // Read-Only?
Type.Missing, Type.Missing, Type.Missing,
Type.Missing, Type.Missing, Type.Missing,
Type.Missing, Type.Missing, Type.Missing,
Type.Missing, Type.Missing, Type.Missing);
// Read worksheets
Sheets sheets = wb.Worksheets;
// Select worksheets
Worksheet ws = (Worksheet)sheets.get_Item("Table1");
Range range = (Range)ws.get_Range("A1", "A1");
// Check Values #1
Console.WriteLine(ws.get_Range("A1", "A1").Value2.ToString());
Console.WriteLine(ws.get_Range("A2", "A2").Value2.ToString());
range.Cells[1, 1] = 15;
// Check Values #2
Console.WriteLine(ws.get_Range("A1", "A1").Value2.ToString());
Console.WriteLine(ws.get_Range("A2", "A2").Value2.ToString());
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
finally
{
wb.Save();
wb.Close(false, null, null);
excel.Quit();
Console.ReadLine();
}
}
}
}
You can access Excel Sheets with C# with help of OleDbConnection , OleDbDataAdapter and DataSet. Here is a sample, how to modify a excel file and cell values: http://csharp.net-informations.com/excel/csharp-excel-oledb-update.htm

Low performance when reading data from Excel workbook to ArrayList in C#

Here's a problem description.
CONDITIONS:
General idea is to read a lot of real numbers from MS Excel file and put them inro ArrayList for further processing.
An excel workbook has only one worksheet. All the numbers are real and they are stored in one column.
I read these numbers row by row and put them into ArrayList.
PROBLEM: the process takes too much time. Program spends about 2 minutes to fill an ArrayList with 10000 elements.
Here's my code. I need your advise to make it faster. But the structure of the file cannot be modified. It's only possible to modify code.
Help me please to make it faster.
// Method GetExcelData opens 1 excel file, reads data row by row and adds
// it into the array of source Data Values (sourceDataValues in our case).
private void GetExcelData(string fullPath, ArrayList arrForValues)
{
Excel.Application excelapp = new Excel.Application();
excelapp.Visible = false;
// to avoid appearing of Excel window on the screen
Excel.Workbook excelappworkbook = excelapp.Workbooks.Open(
fullPath,
Type.Missing, Type.Missing, true, Type.Missing,
Type.Missing, Type.Missing, Type.Missing, Type.Missing,
Type.Missing, Type.Missing, Type.Missing, Type.Missing,
Type.Missing, Type.Missing);
Excel.Worksheet excelworksheet = (Excel.Worksheet)excelappworkbook.Worksheets.get_Item(1);
Excel.Range excelcells = excelworksheet.UsedRange;
uint rowsNum = 0;
for (rowsNum = 1; rowsNum != excelcells.Rows.Count; rowsNum++)
{
arrForValues.Add((excelcells.Cells[rowsNum, 1] as Excel.Range).Value2);
}
excelappworkbook.Close(false, Type.Missing, Type.Missing);
excelapp.Quit();
}
The problem is resolved.
Everything is qute simple. First, we read all the range of current worksheet into simple two-dimension array - worksheetValuesArray. After that we put all the values from that array into our container, converting the type of elements to double. Here's the part of corrected solution:
private void GetExcelData(string fullPath, List<double> arrForValues)
{
Excel.Application excelapp = new Excel.Application();
excelapp.Visible = false;
// to avoid appearing of Excel window on the screen
Excel.Workbook excelappworkbook = excelapp.Workbooks.Open(
fullPath,
Type.Missing, Type.Missing, true, Type.Missing,
Type.Missing, Type.Missing, Type.Missing, Type.Missing,
Type.Missing, Type.Missing, Type.Missing, Type.Missing,
Type.Missing, Type.Missing);
Excel.Worksheet excelworksheet = (Excel.Worksheet)excelappworkbook.Worksheets.get_Item(1);
Excel.Range excelcells = excelworksheet.UsedRange;
object[,] worksheetValuesArray = excelcells.get_Value(Type.Missing);
for (int col = 1; col < (worksheetValuesArray.GetLength(1)+1); col++)
{
for (int row = 1; row < (worksheetValuesArray.GetLength(0)+1); row++)
{
arrForValues.Add((double) worksheetValuesArray[row, col]);
}
}
excelappworkbook.Close(false, Type.Missing, Type.Missing);
excelapp.Quit();
}
My experience with Excel automation is that it is always slow. I usually try an alternative method, such as saving it as a CSV and reading the data with a stream reader and splitting the string on a delimiter (comma, tab, etc). I would suggest looking at the process of receiving your data and see if there is another format readily available.
I tweaked the for loop. See if this yields better results.
// Method GetExcelData opens 1 excel file, reads data row by row and adds
// it into the array of source Data Values (sourceDataValues in our case).
private void GetExcelData(string fullPath, ArrayList arrForValues)
{
Microsoft.Office.Interop.Excel.Application excelapp = new Microsoft.Office.Interop.Excel.Application();
excelapp.Visible = false;
// to avoid appearing of Excel window on the screen
Microsoft.Office.Interop.Excel.Workbook excelappworkbook = excelapp.Workbooks.Open(
fullPath,
Type.Missing, Type.Missing, true, Type.Missing,
Type.Missing, Type.Missing, Type.Missing, Type.Missing,
Type.Missing, Type.Missing, Type.Missing, Type.Missing,
Type.Missing, Type.Missing);
Microsoft.Office.Interop.Excel.Worksheet excelworksheet = (Microsoft.Office.Interop.Excel.Worksheet)excelappworkbook.Worksheets.get_Item(1);
Microsoft.Office.Interop.Excel.Range excelcells = excelworksheet.UsedRange;
Microsoft.Office.Interop.Excel.Range newRange = excelworksheet.get_Range("A1","A"+excelcells.Rows.Count);
object[,] items = newRange.Value;
for (int i = 1; i < items.Length; i++)
{
arrForValues.Add(items[i,1]);
}
excelappworkbook.Close(false, Type.Missing, Type.Missing);
excelapp.Quit();
}
I don't know if you're gonna find much more performance. Excel interop is just slow (due to marshaling across COM boundaries I assume). I have gained some performance in my code (especially in Excel 2007 and higher) by setting the following.
excelapp.ScreenUpdating = false;
and
excelapp.Calculation = Excel.XlCalculation.xlCalculationManual;

Excel automation using C#

I have a folder with close to 400 excel files. I need to copy the worksheets in all these excel files to a single excel file.
using Interop and Reflection namespaces heres is what I have accomplished so far.
I use folderBrowserDialog to browse to the folder and select it, this enable me to get the file names of the files within the folder and iterate through them this is as far as i got, any help would be appreciated.
if (result == DialogResult.OK)
{
string path = fbd1.SelectedPath; //get the path
int pathLength = path.Length + 1;
string[] files = Directory.GetFiles(fbd1.SelectedPath);// getting the names of files in that folder
foreach (string i in files)
{
MessageBox.Show("1 " + i);
myExcel.Application excelApp = new myExcel.ApplicationClass();
excelApp.Visible = false;
MessageBox.Show("2 " + i);
myExcel.Workbook excelWorkbook = excelApp.Workbooks.Add(excelApp.Workbooks._Open(i, 0, false, 5, "", "", false, myExcel.XlPlatform.xlWindows, "", true, false, 0, true));
myExcel.Sheets excelSheets = excelWorkbook.Worksheets;
MessageBox.Show("3 " + i);
excelApp.Workbooks.Close();
excelApp.Quit();
}
MessageBox.Show("Done!");
}
How do i append the copied sheets to the destination file. Hope the question is clear?
thanks.
use Worksheet.Copy(Before, After) and specify after as the last worksheet of whatever main file you want. Please note you might need to create a new worksheet in the mainApp so that it has a worksheet to input after so that it doesn't throw an exception.
Try the following:
Excel.Application mainApp = new Excel.ApplicationClass();
mainApp.Visible = false;
Excel.Workbook mainWorkbook = excelApp.Workbooks.Add(null);
Excel.Sheets mainWorkSheets = mainWorkbook.Worksheets;
foreach (string i in files)
{
MessageBox.Show("1 " + i);
Excel.Application exApp = new Excel.ApplicationClass();
exApp.Visible = false;
MessageBox.Show("2 " + i);
Excel.Workbook exWorkbook = exApp.Workbooks.Open(i,
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);
MessageBox.Show("3 " + i);
foreach(Excel.Worksheet sheet in exWorkbook.Worksheets)
{
sheet.Copy(Type.Missing, mainWorkSheets[mainWorkSheets.Count -1]);
}
}
mainApp.Save("NewExcel");
How about something like: Merge(#"C:\ExcelFolder", #"C:\FinalDestination.xls"); works for me, directly outta working sample - trimmed for you.
Hopefully, you wont require any tweaks but in case you do, then do (0:
Please see following code:
private void Merge(string strSourceFolder, string strDestinationFile)
{
try
{
//1. Validate folder,
//2. Instantiate excel object
//3. Loop through the files
//4. Add sheets
//5. Save and enjoy!
object missing = System.Reflection.Missing.Value;
Microsoft.Office.Interop.Excel.ApplicationClass ExcelApp = new Microsoft.Office.Interop.Excel.ApplicationClass();
ExcelApp.Visible = false;
//Create destination object
Microsoft.Office.Interop.Excel.Workbook objBookDest = ExcelApp.Workbooks.Add(missing);
foreach (string filename in Directory.GetFiles(strSourceFolder))
{
if (File.Exists(filename))
{
//create an object
Microsoft.Office.Interop.Excel.Workbook objBookSource = 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);
//Browse through all files.
foreach (Microsoft.Office.Interop.Excel.Worksheet sheet in objBookSource.Worksheets)
{
sheet.Copy(Type.Missing, objBookDest.Worksheets[objBookSource.Worksheets.Count]);
}
objBookSource.Close(Type.Missing, Type.Missing, Type.Missing);
objBookSource = null;
}
}
objBookDest.SaveAs(strDestinationFile, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, XlSaveAsAccessMode.xlNoChange, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing);
objBookDest.Close(Type.Missing, Type.Missing, Type.Missing);
objBookDest = null;
ExcelApp = null;
}
catch (System.Exception e)
{
//Catch
}
}
You can try ZetExcel for Excel automation using C#. ZetExcel for .NET contains APIs to be used with .NET Framework, .NET Core & Xamarin platform.

Categories