Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/272.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用c#读取大型Excel文件并获取索引_C#_Excel_Openxml_Excel Interop_Openxml Sdk - Fatal编程技术网

使用c#读取大型Excel文件并获取索引

使用c#读取大型Excel文件并获取索引,c#,excel,openxml,excel-interop,openxml-sdk,C#,Excel,Openxml,Excel Interop,Openxml Sdk,我曾尝试使用Microsoft.Office.Interop.Excel,但在阅读大型Excel文档时速度太慢(我花了5分钟以上)。我读到DocumentFormat.OpenXml在读取大型excel文档时速度更快,但实际上,我似乎无法存储列和行索引 现在,我只对获取列标题的第一行感兴趣,我将在经过一些逻辑之后阅读文档的其余部分。我一直无法找到一种方法来只读取excel文档的一部分。我想做类似的事情: int r = 1; //row index int c

我曾尝试使用Microsoft.Office.Interop.Excel,但在阅读大型Excel文档时速度太慢(我花了5分钟以上)。我读到DocumentFormat.OpenXml在读取大型excel文档时速度更快,但实际上,我似乎无法存储列和行索引

现在,我只对获取列标题的第一行感兴趣,我将在经过一些逻辑之后阅读文档的其余部分。我一直无法找到一种方法来只读取excel文档的一部分。我想做类似的事情:

        int r = 1;  //row index
        int c = 1;  //column index
        while (xlRange.Cells[r,c] != null && xlRange.Cells[r, c].Value2 != null)
        {
            TagListData.Add(new TagClass { IsTagSelected = false, TagName = xlRange[r, c].Value2.toString(), rIndex = r, cIndex = c });
            c += 3;
        }
用户将通过openFileDialog选择excel文档,因此我不能使用固定数量的列行。有没有办法让这一切顺利进行


感谢您在OpenXML中使用

如果一个单元格没有文本,它可能会也可能不会出现在单元格列表中(取决于它是否有文本)。因此,
while(…Value2!=null)
类型的方法在OpenXML中并不是一种真正安全的方法

下面是一种非常简单的读取第一行的方法(因此使用
Main
Dump
编写)。请注意(简化)使用SharedStringTable获取单元格的真实文本:

void Main()
{
    var fileName = @"c:\temp\openxml-read-row.xlsx";

    using (FileStream fs = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
    {
        using (SpreadsheetDocument doc = SpreadsheetDocument.Open(fs, false))
        {

            // Get the necessary bits of the doc
            WorkbookPart workbookPart = doc.WorkbookPart;
            SharedStringTablePart sstpart = workbookPart.GetPartsOfType<SharedStringTablePart>().First();
            SharedStringTable sst = sstpart.SharedStringTable;
            WorkbookStylesPart ssp = workbookPart.GetPartsOfType<WorkbookStylesPart>().First();
            Stylesheet ss = ssp.Stylesheet;

            // Get the first worksheet
            WorksheetPart worksheetPart = workbookPart.WorksheetParts.First();
            Worksheet sheet = worksheetPart.Worksheet;

            var rows = sheet.Descendants<Row>();
            var row = rows.First();
            foreach (var cell in row.Descendants<Cell>())
            {
                var txt = GetCellText(cell, sst);
                // LINQPad specific method .Dump()
                $"{cell.CellReference} = {txt}".Dump();
            }
        }
    }   
}

// Very basic way to get the text of a cell
private string GetCellText(Cell cell, SharedStringTable sst)
{
    if (cell == null)
        return "";

    if ((cell.DataType != null) && (cell.DataType == CellValues.SharedString))
    {
        int ssid = int.Parse(cell.CellValue.Text);
        string str = sst.ChildElements[ssid].InnerText;
        return str;
    }
    else if (cell.CellValue != null)
    {
        return cell.CellValue.Text;
    }
    return "";
}

查看Accor.IO.ExcelReader,也许这会有所帮助,但也许不感谢您的回答,但它似乎对我的excel文件不起作用。它似乎确实适用于较小的excel文档(我用一个只有一个单元格的文档进行了尝试),但它似乎对较大的excel文件使用了太多内存。我发现创建工作簿实例会使我的程序速度变慢。在我的代码中,我有:stringfilename=openFileDialog.filename;使用(var workbook=new XLWorkbook(filename)){//这里的所有内容都被注释掉了}这就是导致错误的原因。还有什么我可以做的吗?似乎ClosedXML在处理大文件时有问题。请参见此处:。似乎有一个测试版可以修复它。也许您必须坚持使用OpenXML方法和文件流。或禁用上述问题中提到的事件:。我自己没有遇到过这些问题,所以我恐怕没有任何见解。我不得不在调试菜单中禁用ContextSwitchDeadLock。ClosedXML现在正在工作,但读取文件仍需要>8分钟。我现在正在使用ExcelDataReader,读取该文件需要4-5分钟,但我将尝试寻找一种方法使其速度更快。谢谢你
using (var workbook = new XLWorkbook(fileName))
{
    var worksheet = workbook.Worksheets.First();
    var row = worksheet.Row(1);
    foreach (var cell in row.CellsUsed())
    {
        var txt = cell.Value.ToString();
        // LINQPad specific method .Dump()
        $"{cell.Address.ToString()} = {txt}".Dump();
    }
}