简体   繁体   中英

Error reading Excel document in forms C#

I'm trying to take XLSX data and putting it into an DataGridView using the ExcelDataReader NuGet package. But i get a Object reference not set to an instance of an object error on line 35

foreach (DataTable dt in result.Tables)

Here is the full code.

    using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Data.OleDb;
using System.IO;
using Excel;

namespace MyForm
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        DataSet result;

        private void butOpen_Click(object sender, EventArgs e)
        {
            using (OpenFileDialog ofd = new OpenFileDialog())
            {
                if (ofd.ShowDialog() == DialogResult.OK)
                {
                    FileStream fs = File.Open(ofd.FileName, FileMode.Open, FileAccess.Read);
                    IExcelDataReader reader = ExcelReaderFactory.CreateBinaryReader(fs);
                    reader.IsFirstRowAsColumnNames = true;
                    result = reader.AsDataSet();
                    cboSheet.Items.Clear();
                    foreach (DataTable dt in result.Tables)
                    cboSheet.Items.Add(dt.TableName);
                    reader.Close();

                }
            }

        }

        private void cboSheet_SelectedIndexChanged(object sender, EventArgs e)
        {
            dataGridView.DataSource = result.Tables[cboSheet.SelectedIndex];

        }
    }
}

Here is the error message: Error

In response to the comments:

The property IsFirstRowAsColumnNames is no longer available on newer versions of the package.

From the GitHub page LINK :

AsDataSet configuration options

The AsDataSet() function accepts an optional configuration object to modify the behavior of the DataSet conversion:

var result = reader.AsDataSet(new ExcelDataSetConfiguration() {

    // Gets or sets a value indicating whether to set the DataColumn.DataType 
    // property in a second pass.
    UseColumnDataType = true,

    // Gets or sets a callback to obtain configuration options for a DataTable. 
    ConfigureDataTable = (tableReader) => new ExcelDataTableConfiguration() {

        // Gets or sets a value indicating the prefix of generated column names.
        EmptyColumnNamePrefix = "Column",

        // Gets or sets a value indicating whether to use a row from the 
        // data as column names.
        UseHeaderRow = false,

        // Gets or sets a callback to determine which row is the header row. 
        // Only called when UseHeaderRow = true.
        ReadHeaderRow = (rowReader) => {
            // F.ex skip the first row and use the 2nd row as column headers:
            rowReader.Read();
        }
    }
});

I'm guessing that the line UseHeaderRow = true; in the ExcelDataTAbleConfiguration would result in the wanted behavior.

EDIT: Add working example

This example works for me with a new .xlsx file created in Excel 2016. The file contains two sheets: Sheet 1 and Sheet 2. Both contain two columns with two rows of text.

List<string> tblNames = new List<string>();
OpenFileDialog ofd = new OpenFileDialog();

if (ofd.ShowDialog() ?? false)
{
    using (FileStream fs = File.Open(ofd.FileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
    {
        using (IExcelDataReader reader = ExcelReaderFactory.CreateReader(fs))
        {
            var result = reader.AsDataSet(new ExcelDataSetConfiguration()
            {
                UseColumnDataType = true,

                ConfigureDataTable = (tableReader) => new ExcelDataTableConfiguration()
                {                                
                    UseHeaderRow = true
                }
            });

            foreach (DataTable dt in result.Tables)
                tblNames.Add(dt.TableName);
        }
    }
}

This is a WPF application, so the usage of OpenFileDialog looks a bit different.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM