C-Sharp | Java | Python | Swift | GO | WPF | Ruby | Scala | F# | JavaScript | SQL | PHP | Angular | HTML
Tip: Add the Microsoft.Office.Interop.Excel assembly by going to Project -> Add Reference.
Class: First, we make a new C# class file in Visual Studio and you can call it something like ExcelInterop.
Methods: If you look at Excel interop objects in IntelliSense, you will see many functions. You will only need to use a few.
Class that stores Application: C#
/// <summary>
/// This class contains the Excel Interop code we need.
/// It can be shared in many places to avoid duplication.
/// </summary>
class ExcelReaderInterop
{
    /// <summary>
    /// Store the Application object we can use in the member functions.
    /// </summary>
    Application _excelApp;
    /// <summary>
    /// Initialize a new Excel reader. Must be integrated
    /// with an Excel interface object.
    /// </summary>
    public ExcelReaderInterop()
    {
        _excelApp = new Application();
    }
}
Open: Put a public function on the class, and it can use the _excelApp we already have. This code uses the Workbooks.Open method.
Next: Open a workbook with Workbooks.Open. Send the workbook we open to another function called ExcelScanInternal.
Finally: Close the workbook and release all the memory. You will need to deal with exceptions in the catch block.
Note: I don't have the information about all the detailed exceptions that can be thrown. Just catch them in one statement.
CatchMethod that opens Excel workbooks: C#
/// <summary>
/// Open the file path received in Excel. Then, open the workbook
/// within the file. Send the workbook to the next function, the internal scan
/// function. Will throw an exception if a file cannot be found or opened.
/// </summary>
public void ExcelOpenSpreadsheets(string thisFileName)
{
    try
    {
        //
        // This mess of code opens an Excel workbook. I don't know what all
        // those arguments do, but they can be changed to influence behavior.
        //
        Workbook workBook = _excelApp.Workbooks.Open(thisFileName,
            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);
        //
        // Pass the workbook to a separate function. This new function
        // will iterate through the worksheets in the workbook.
        //
        ExcelScanInternal(workBook);
        //
        // Clean up.
        //
        workBook.Close(false, thisFileName, null);
        Marshal.ReleaseComObject(workBook);
    }
    catch
    {
        //
        // Deal with exceptions.
        //
    }
}
Tip: In Excel Interop, sheets are indexed starting at 1. This is similar to Visual Basic but not the C# language.
Example: The object array is directly usable in the C# language. Once you get the objects, you don't need to do any more Interop.
And: This provides a huge performance boost. There are benefits to reducing calls to Excel Interop.
Method that gets sheets: C#
/// <summary>
/// Scan the selected Excel workbook and store the information in the cells
/// for this workbook in an object[,] array. Then, call another method
/// to process the data.
/// </summary>
private void ExcelScanInternal(Workbook workBookIn)
{
    //
    // Get sheet Count and store the number of sheets.
    //
    int numSheets = workBookIn.Sheets.Count;
    //
    // Iterate through the sheets. They are indexed starting at 1.
    //
    for (int sheetNum = 1; sheetNum < numSheets + 1; sheetNum++)
    {
        Worksheet sheet = (Worksheet)workBookIn.Sheets[sheetNum];
        //
        // Take the used range of the sheet. Finally, get an object array of all
        // of the cells in the sheet (their values). You can do things with those
        // values. See notes about compatibility.
        //
        Range excelRange = sheet.UsedRange;
        object[,] valueArray = (object[,])excelRange.get_Value(
            XlRangeValueDataType.xlRangeValueDefault);
        //
        // Do something with the data in the array with a custom method.
        //
        ProcessObjects(valueArray);
    }
}
Note: This document is based on .NET 3.5. The approach shown here is the fastest one.
Excel interop benchmark
Cells[]:                30.0 seconds
get_Range(), Cells[]:   15.0 seconds
UsedRange, get_Value():  1.5 seconds [fastest]
Note: The function get_Value() returns objects that do not vary based on the original platform.
Example: The range of the data we want to chart is encoded in the topLeft and bottomRight constants. We use the ChartObjects property and Add a Chart.
Next: We set the range of the chart with SetSourceData. We use the XlChartType.xlLine enumerated constant and call ChartWizard().
Tip: Include the Microsoft.Office.Interop.Excel namespace by right-clicking on References and selecting Add Reference.
C# program that creates Excel chart from data
using Microsoft.Office.Interop.Excel;
class Program
{
    const string fileName = "C:\\Book1.xlsx";
    const string topLeft = "A1";
    const string bottomRight = "A4";
    const string graphTitle = "Graph Title";
    const string xAxis = "Time";
    const string yAxis = "Value";
    static void Main()
    {
        // Open Excel and get first worksheet.
        var application = new Application();
        var workbook = application.Workbooks.Open(fileName);
        var worksheet = workbook.Worksheets[1] as
            Microsoft.Office.Interop.Excel.Worksheet;
        // Add chart.
        var charts = worksheet.ChartObjects() as
            Microsoft.Office.Interop.Excel.ChartObjects;
        var chartObject = charts.Add(60, 10, 300, 300) as
            Microsoft.Office.Interop.Excel.ChartObject;
        var chart = chartObject.Chart;
        // Set chart range.
        var range = worksheet.get_Range(topLeft, bottomRight);
        chart.SetSourceData(range);
        // Set chart properties.
        chart.ChartType = Microsoft.Office.Interop.Excel.XlChartType.xlLine;
        chart.ChartWizard(Source: range,
            Title: graphTitle,
            CategoryTitle: xAxis,
            ValueTitle: yAxis);
        // Save.
        workbook.Save();
    }
}
Note: Some code contributed by Randall Kelsey was adapted for the charting example.
Tip: Many options can be changed to create different charts based on different data ranges.