优化将Excel文件读取到DataTable对象中

时间:2017-07-27 10:03:18

标签: c# excel datatable

我使用下面的代码将excel文件中的数据读入DataTable对象以供进一步使用。由于它从100k到500k的条目处理,读数可能会有点慢。我可以在代码中更改某些内容以优化流程吗?代码如下。

 public static DataTable ReadAsDataTable(string filePath)
    {
        DataTable dataTable = new DataTable();
        using (SpreadsheetDocument spreadSheetDocument = SpreadsheetDocument.Open(filePath, 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))
            {
                dataTable.Columns.Add(GetCellValue(spreadSheetDocument, cell));
            }
            foreach (Row row in rows)
            {
                DataRow dataRow = dataTable.NewRow();
                for (int i = 0; i < row.Descendants<Cell>().Count(); i++)
                {
                    dataRow[i] = GetCellValue(spreadSheetDocument, row.Descendants<Cell>().ElementAt(i));
                }
                dataTable.Rows.Add(dataRow);
            }
        }
        dataTable.Rows.RemoveAt(0);
        return dataTable;
    }

    private 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;
        }
    }

1 个答案:

答案 0 :(得分:0)

我不确定该API的编译器行为或该API的性能特征是什么,但如果您只调用row.Descendants<Cell>()一次,它会有帮助吗?它似乎是编译器可以优化的东西,但可能会涉及副作用,因此它不会做任何事情。

 foreach (Row row in rows)
 {
            var cells = row.Descendants<Cell>().ToArray();
            DataRow dataRow = dataTable.NewRow();
            for (int i = 0; i < cells.Length; i++)
            {
                dataRow[i] = GetCellValue(spreadSheetDocument, cells[i]);
            }
            dataTable.Rows.Add(dataRow);
 }