C# 如何以OpenXML格式更快地阅读

C# 如何以OpenXML格式更快地阅读,c#,.net,excel,c#-4.0,openxml,C#,.net,Excel,C# 4.0,Openxml,当我使用OLEDB时,从Excel工作表中读取3200行只需2-3秒。现在我改为OpenXML格式,现在从Excel工作表中读取3200行需要1分钟以上的时间 下面是我的代码: public static DataTable ReadExcelFileDOM(string filename) { DataTable table; using (SpreadsheetDocument myDoc = SpreadsheetDocument.Open(filename, tr

当我使用OLEDB时,从Excel工作表中读取3200行只需2-3秒。现在我改为OpenXML格式,现在从Excel工作表中读取3200行需要1分钟以上的时间

下面是我的代码:

public static DataTable ReadExcelFileDOM(string filename) 
{ 
    DataTable table; 

    using (SpreadsheetDocument myDoc = SpreadsheetDocument.Open(filename, true)) 
    { 
        WorkbookPart workbookPart = myDoc.WorkbookPart; 
        Sheet worksheet = workbookPart.Workbook.Descendants<Sheet>().First(); 
        WorksheetPart worksheetPart = 
         (WorksheetPart)(workbookPart.GetPartById(worksheet.Id)); 
        SheetData sheetData = 
            worksheetPart.Worksheet.Elements<SheetData>().First(); 
        List<List<string>> totalRows = new List<List<string>>(); 
        int maxCol = 0; 

        foreach (Row r in sheetData.Elements<Row>()) 
        { 
            // Add the empty row. 
            string value = null; 
            while (totalRows.Count < r.RowIndex - 1) 
            { 
                List<string> emptyRowValues = new List<string>(); 
                for (int i = 0; i < maxCol; i++) 
                { 
                    emptyRowValues.Add(""); 
                } 
                totalRows.Add(emptyRowValues); 
            } 


            List<string> tempRowValues = new List<string>(); 
            foreach (Cell c in r.Elements<Cell>()) 
            { 
                #region get the cell value of c. 
                if (c != null) 
                { 
                    value = c.InnerText; 

                    // If the cell represents a numeric value, you are done.  
                    // For dates, this code returns the serialized value that  
                    // represents the date. The code handles strings and Booleans 
                    // individually. For shared strings, the code looks up the  
                    // corresponding value in the shared string table. For Booleans,  
                    // the code converts the value into the words TRUE or FALSE. 
                    if (c.DataType != null) 
                    { 
                        switch (c.DataType.Value) 
                        { 
                            case CellValues.SharedString: 
                                // For shared strings, look up the value in the shared  
                                // strings table. 
                                var stringTable = workbookPart. 
                                    GetPartsOfType<SharedStringTablePart>().FirstOrDefault(); 

                                // If the shared string table is missing, something is  
                                // wrong. Return the index that you found in the cell. 
                                // Otherwise, look up the correct text in the table. 
                                if (stringTable != null) 
                                { 
                                    value = stringTable.SharedStringTable. 
                                        ElementAt(int.Parse(value)).InnerText; 
                                } 
                                break; 

                            case CellValues.Boolean: 
                                switch (value) 
                                { 
                                    case "0": 
                                        value = "FALSE"; 
                                        break; 
                                    default: 
                                        value = "TRUE"; 
                                        break; 
                                } 
                                break; 
                        } 
                    } 

                    Console.Write(value + "  "); 
                } 
                #endregion 

                // Add the cell to the row list. 
                int i = Convert.ToInt32(c.CellReference.ToString().ToCharArray().First() - 'A'); 

                // Add the blank cell in the row. 
                while (tempRowValues.Count < i) 
                { 
                    tempRowValues.Add(""); 
                } 
                tempRowValues.Add(value); 
            } 

            // add the row to the totalRows. 
            maxCol = processList(tempRowValues, totalRows, maxCol); 

            Console.WriteLine(); 
        } 

        table = ConvertListListStringToDataTable(totalRows, maxCol); 
    } 
    return table; 
} 

/// <summary> 
/// Add each row to the totalRows. 
/// </summary> 
/// <param name="tempRows"></param> 
/// <param name="totalRows"></param> 
/// <param name="MaxCol">the max column number in rows of the totalRows</param> 
/// <returns></returns> 
private static int processList(List<string> tempRows, List<List<string>> totalRows, int MaxCol) 
{ 
    if (tempRows.Count > MaxCol) 
    { 
        MaxCol = tempRows.Count; 
    } 

    totalRows.Add(tempRows); 
    return MaxCol; 
} 

private static DataTable ConvertListListStringToDataTable(List<List<string>> totalRows, int maxCol) 
{ 
    DataTable table = new DataTable(); 
    for (int i = 0; i < maxCol; i++) 
    { 
        table.Columns.Add(); 
    } 
    foreach (List<string> row in totalRows) 
    { 
        while (row.Count < maxCol) 
        { 
            row.Add(""); 
        } 
        table.Rows.Add(row.ToArray()); 
    } 
    return table; 
} 
公共静态数据表ReadExcelFileDOM(字符串文件名)
{ 
数据表;
使用(SpreadsheetDocument myDoc=SpreadsheetDocument.Open(文件名,true))
{ 
WorkbookPart WorkbookPart=myDoc.WorkbookPart;
工作表=workbookPart.Workbook.subjects().First();
工作表部件工作表部件=
(WorksheetPart)(workbookPart.GetPartById(worksheet.Id));
SheetData SheetData=
worksheetPart.Worksheet.Elements().First();
List totalRows=新列表();
int-maxCol=0;
foreach(sheetData.Elements()中的r行)
{ 
//添加空行。
字符串值=null;
while(totalRows.CountMaxCol)
{ 
MaxCol=tempRows.Count;
} 
totalRows.Add(tempRows);
返回MaxCol;
} 
专用静态数据表ConvertListListStringToDataTable(列表totalRows,int-maxCol)
{ 
DataTable=新的DataTable();
对于(int i=0;i

是否有一种有效的方法可以在某个地方更改此代码,从而使读取过程稍微快一点。如何将其更改为代码以加快阅读速度。谢谢。

我尝试了您的代码,并注意到在一个非常简单的示例中,我花了大约4秒的时间才完成

将my
.xls文件编辑到给定的详细信息(列:地区前缀、城市、日期、功能等)并添加约3600行后,您的代码将显示约10秒

我认为您应该删除任何Console.WriteLine语句,因为这些语句会减慢处理
xls文件的速度。去除所有这些数据后,我的秒表在相同行数下显示1.26秒

您可以找到console.WriteLine即使在上也如此缓慢的一些原因。在这个问题上有
class Program
{
    static void Main(string[] args)
    {
        var dt = new DataTable();
        using (var reader = new ExcelDataReader(@"data.xlsx"))
        {                
            dt.Load(reader);
        }

        Console.WriteLine("done: " + dt.Rows.Count);
        Console.ReadKey();
   }
}