C#使用OpenXml.Spreadsheet填充数据网格

C#使用OpenXml.Spreadsheet填充数据网格,c#,datatable,openxml,C#,Datatable,Openxml,我想使用OpenXml.Spreadsheet引用用speadsheet中的值填充DataTable。不幸的是,我的方法不太管用。我得到的对象引用未设置为对象错误的实例。你能就最佳行动方案提出建议吗?看起来像我的收藏。添加(文本)似乎正在破坏它 using DocumentFormat.OpenXml.Spreadsheet; public DataTable ReadXls(string filePath) { // create a new data

我想使用OpenXml.Spreadsheet引用用speadsheet中的值填充DataTable。不幸的是,我的方法不太管用。我得到的对象引用未设置为对象错误的实例。你能就最佳行动方案提出建议吗?看起来像我的收藏。添加(文本)似乎正在破坏它

using DocumentFormat.OpenXml.Spreadsheet;


public DataTable ReadXls(string filePath)
    {       
        // create a new datatable

        DataTable xlsData = new DataTable();
        DataTable xlsDataOut = new DataTable();

        try
        {
            using (SpreadsheetDocument spreadsheetDocument = SpreadsheetDocument.Open(filePath, true))
            {
                // invoke spreadsheet stuff

                WorkbookPart workbookPart = spreadsheetDocument.WorkbookPart;
                WorksheetPart worksheetPart = workbookPart.WorksheetParts.First();
                SheetData sheetData = worksheetPart.Worksheet.Elements<SheetData>().First();

                // determine number of rows/columns to create DataTable

                foreach (Column col in sheetData.Elements<Column>())
                {
                    DataColumn serialno = new DataColumn();
                    serialno.AllowDBNull = true;
                    xlsData.Columns.Add(serialno);
                }

                foreach (Row r in sheetData.Elements<Row>())
                {
                    DataRow dtRow = xlsData.NewRow();
                    xlsData.Rows.Add(dtRow);
                }

                // column and row count for dataset
                int colcount = xlsData.Columns.Count;
                int rowcount = xlsData.Rows.Count;

                // invoke individual cell 

                foreach (Row r in sheetData.Elements<Row>())
                {
                    List<string> myCollection = new List<string>();
                    DataRow dr = xlsDataOut.NewRow();

                    foreach (Cell c in r.Elements<Cell>())
                    {
                        string text = c.CellValue.Text;
                        myCollection.Add(text);
                    }

                    for (int i = 0; i < colcount; i++)
                    {
                        dr[i] = myCollection[i];
                    }

                    xlsDataOut.Rows.Add(dr);
                }
            }
        }

        catch (Exception ex)
        {
            MessageBox.Show("Error creating DataTable from xls file" + "\n" + ex.Message + "\n" + ex.StackTrace);
        }

        return xlsDataOut;
    }
使用DocumentFormat.OpenXml.Spreadsheet;
公共数据表ReadXls(字符串文件路径)
{       
//创建一个新的数据表
DataTable xlsData=新DataTable();
DataTable xlsDataOut=新DataTable();
尝试
{
使用(SpreadsheetDocument SpreadsheetDocument=SpreadsheetDocument.Open(文件路径,true))
{
//调用电子表格
WorkbookPart WorkbookPart=电子表格文档.WorkbookPart;
WorksheetPart WorksheetPart=workbookPart.WorksheetParts.First();
SheetData SheetData=worksheetPart.Worksheet.Elements().First();
//确定要创建DataTable的行/列数
foreach(sheetData.Elements()中的列col)
{
DataColumn serialno=新DataColumn();
serialno.AllowDBNull=true;
xlsData.Columns.Add(序列号);
}
foreach(sheetData.Elements()中的r行)
{
DataRow dtRow=xlsData.NewRow();
xlsData.Rows.Add(dtRow);
}
//数据集的列和行计数
int colcount=xlsData.Columns.Count;
int rowcount=xlsData.Rows.Count;
//调用单个单元格
foreach(sheetData.Elements()中的r行)
{
List myCollection=新列表();
DataRow dr=xlsDataOut.NewRow();
foreach(r.Elements()中的单元格c)
{
字符串文本=c.CellValue.text;
myCollection.Add(文本);
}
for(int i=0;i
我找到了一个解决方案,这很有效。特别感谢来自专家交流的it_Saige

public void btnOpenExcel_Click(object sender, EventArgs e)
    {
        // Upload data from .xls file
        try
        {
            // Pulls up file reader

            using (OpenFileDialog ofd = new OpenFileDialog() { Filter = "xlsx|*.xlsx", ValidateNames = true })
            {
                if (ofd.ShowDialog() == DialogResult.OK)
                {
                    lblFileName.Text = ofd.FileName;

                    // use selected file name to populate Spreadsheet Viewer
                    var myData = SpreadsheetDocument.Open(ofd.FileName, false).GetDataTableFromSpreadSheet();
                    dataGridView.DataSource = myData;

                }
            }             
        }

        catch (Exception ex)
        {
            MessageBox.Show(ex.Message, "Something went wrong", MessageBoxButtons.OK, MessageBoxIcon.Error);
        }
    }

static class Extensions
{
    // this extension is for populating the GridView with values from a spreadsheet. 
    public static DataTable GetDataTableFromSpreadSheet(this SpreadsheetDocument document, int columns = -1, bool excludeHeader = true)
    {
        var results = new DataTable();
        try
        {
            var sheets = document.WorkbookPart.Workbook.GetFirstChild<Sheets>().Elements<Sheet>();
            var id = sheets.First().Id.Value;
            var part = (WorksheetPart)document.WorkbookPart.GetPartById(id);
            var sheet = part.Worksheet;
            var data = sheet.GetFirstChild<SheetData>();
            var rows = data.Descendants<Row>();
            if (rows.Count() != 0)
            {
                var colCount = rows.First().Cast<Cell>().Count();
                if (columns > colCount || columns <= 0)
                    columns = colCount;

                foreach (var cell in rows.First().Cast<Cell>().Take(columns))
                    results.Columns.Add(cell.GetValue(document));

                foreach (var row in rows.Skip(Convert.ToInt32(excludeHeader)))
                    results.Rows.Add((from cell in row.Cast<Cell>().Take(columns) select cell.GetValue(document)).ToArray());
            }
        }
        catch (Exception)
        {
            results = new DataTable();
        }
        return results;
    }

    public static string GetValue(this Cell cell, SpreadsheetDocument document)
    {
        string result = string.Empty;
        try
        {
            if (cell != null && cell.ChildElements.Count != 0)
            {
                var part = document.WorkbookPart.SharedStringTablePart;
                if (cell.DataType != null && cell.DataType == CellValues.SharedString)
                    result = part.SharedStringTable.ChildElements[Int32.Parse(cell.CellValue.InnerText)].InnerText;
                else
                    result = cell.CellValue.InnerText;
            }
        }
        catch (Exception)
        {
            result = string.Empty;
        }
        return result;
    }
}
public void btnOpenExcel\u单击(对象发送方,事件参数e)
{
//从.xls文件上载数据
尝试
{
//打开文件读取器
使用(OpenFileDialog ofd=newopenfiledialog(){Filter=“xlsx |*.xlsx”,ValidateNames=true})
{
if(ofd.ShowDialog()==DialogResult.OK)
{
lblFileName.Text=ofd.FileName;
//使用选定的文件名填充电子表格查看器
var myData=SpreadsheetDocument.Open(ofd.FileName,false).GetDataTableFromSpreadSheet();
dataGridView.DataSource=myData;
}
}             
}
捕获(例外情况除外)
{
MessageBox.Show(例如Message,“出错了”,MessageBoxButtons.OK,MessageBoxIcon.Error);
}
}
静态类扩展
{
//此扩展用于使用电子表格中的值填充GridView。
公共静态数据表GetDataTableFromSpreadSheet(此电子表格文档,int列=-1,bool excludeHeader=true)
{
var results=新数据表();
尝试
{
var sheets=document.WorkbookPart.Workbook.GetFirstChild().Elements();
var id=sheets.First().id.Value;
var part=(工作表部分)document.WorkbookPart.GetPartById(id);
var工作表=零件工作表;
var data=sheet.GetFirstChild();
var rows=data.subjects();
if(rows.Count()!=0)
{
var colCount=rows.First().Cast().Count();

如果(columns>colCount | | columns)“对象引用未设置为对象的实例”足够简单,但在哪一行?我怀疑
sheetData.Elements()
是否返回了任何内容。是吗?上次我尝试时,我必须迭代单元格以确定列数。