Как преобразовать потоковый файл excel в datatable C#?

Я использую Epplus для чтения файлов xlsx из потока.

У него есть ошибка, он не может прочитать некоторые столбцы в моей книге. Как читать файлы xlsx из потока в таблицу данных без epplus?

мой старый код:

 public static DataSet ReadExcelFile(Stream stream)
    {
        try
        {
            //2. Reading from a OpenXml Excel file (2007 format; *.xlsx)
            IExcelDataReader excelReader =    
                             ExcelReaderFactory.CreateOpenXmlReader(stream);
            //...
            DataSet result = excelReader.AsDataSet();

            return result;

        }
        catch (Exception x)
        {
            throw x;
        }
    }

Я не сообщал об этом, но я пробовал так много комбинаций. Если на листе есть пустые столбцы, читатель epplus не может правильно прочитать значения столбцов.


person Mennan    schedule 28.06.2012    source источник


Ответы (2)


"У него ошибка, он не может прочитать некоторые столбцы в моей книге"

Можете ли вы описать ошибку, сообщили о ней или уже известно, какая версия вы используете?

Вот простой способ загрузить файл Excel в DataTable с помощью EPPlus.

public static DataTable getDataTableFromExcel(string path)
{
    using (var pck = new OfficeOpenXml.ExcelPackage())
    {
        using (var stream = File.OpenRead(path))
        {
            pck.Load(stream);
        }
        var ws = pck.Workbook.Worksheets.First();  
        DataTable tbl = new DataTable();
        bool hasHeader = true; // adjust it accordingly( i've mentioned that this is a simple approach)
        foreach (var firstRowCell in ws.Cells[1, 1, 1, ws.Dimension.End.Column])
        {
            tbl.Columns.Add(hasHeader ? firstRowCell.Text : string.Format("Column {0}", firstRowCell.Start.Column));
        }
        var startRow = hasHeader ? 2 : 1;
        for (var rowNum = startRow; rowNum <= ws.Dimension.End.Row; rowNum++)
        {
            var wsRow = ws.Cells[rowNum, 1, rowNum, ws.Dimension.End.Column];
            var row = tbl.NewRow();
            foreach (var cell in wsRow)
            {
                row[cell.Start.Column - 1] = cell.Text;
            }
            tbl.Rows.Add(row);
        }
        return tbl;
    }
}
person Tim Schmelter    schedule 28.06.2012
comment
я получил нулевую ссылку на объект на var ws = pck.Workbook.Worksheets[Worksheet1]; Есть идеи ? - person Mennan; 28.06.2012
comment
@Mennan: вместо этого попробуйте var ws = pck.Workbook.Worksheets.First(); (соответственно отредактировал мой ответ). - person Tim Schmelter; 28.06.2012
comment
Я использую Epplus версии 3.0.0.2, а в pck.Workbook.Worksheets нет метода First(), извините, также я пробовал Worksheets[0] , но он все еще равен нулю. Я не понимаю - person Mennan; 28.06.2012
comment
@Mennan: Тогда вы не используете .NET framework ›= 3.5. Попробуйте var ws = pck.Workbook.Worksheets[1];, так как индекс ExcelWorksheets начинается с 1. Можете ли вы открыть этот файл Excel вручную? - person Tim Schmelter; 28.06.2012
comment
Спасибо за это, очень помогло. У меня были некоторые проблемы с пустыми столбцами, поэтому мне пришлось удалить их из Excel, чтобы это сработало. - person Contra; 12.09.2012
comment
@Contra Большое спасибо за удаление пустых столбцов. Рабочая книга.Рабочие листы.Первый(); выбрасывает индекс из исключения, когда у вас есть пустые столбцы на листе. - person emre nevayeshirazi; 20.12.2013
comment
@Tim Спасибо, это очень полезно для того, над чем я работаю. Чтобы что-то внести, необходимы следующие ссылки: использование System.IO; с помощью OfficeOpenXml; - person JPK; 12.03.2014
comment
Это работает отлично. Только одно сомнение. Могу ли я установить лист по имени вместо var ws = pck.Workbook.Worksheets[1];. Файл, который я хочу разобрать, представляет собой постоянно меняющийся ежедневный отчет, иногда они добавляют лист в начало, иногда удаляют его, но имена листов остаются постоянными. Так это возможно? - person fishmong3r; 21.07.2014
comment
@fishmong3r: да, вы можете использовать FirstOrDefault, чтобы получить первый лист с таким именем (или null, если его нет): var ws = pck.Workbook.Worksheets.FirstOrDefault(sheet => sheet.Name == "Name"); - person Tim Schmelter; 21.07.2014
comment
@TimSchmelter Большое спасибо. Я знаю, что это другое дело, но не могли бы вы помочь мне, как начать включать EPPlus.dll? Я сделал это: youtube.com/watch?v=x-KK7bmo1AM, но Я все еще получаю Could not load file or assembly - person fishmong3r; 21.07.2014
comment
@TimSchmelter, как это улучшить, чтобы сохранить тип данных для столбца? Ваше решение преобразует все в строки, верно? - person Gustav; 02.08.2016
comment
@Gustav: я думаю, что это сложно, так как Excel хранит все в виде строк, а числа и дату и время в виде двойников. Так что вам все равно нужно много конверсии. Если вы знаете целевые столбцы/типы, вы можете выполнить преобразование вручную, например, с помощью DateTime.Parse или int.Parse. - person Tim Schmelter; 02.08.2016
comment
@TimSchmelter Хорошо, я понимаю, и это имеет смысл. Спасибо за очень быстрый ответ, очень признателен. - person Gustav; 02.08.2016

Это прошлое, однако это все еще может помочь кому-то. По-видимому, некоторые столбцы на моем листе были объединены, поэтому, например, если столбцы A и B объединены, он распознает только столбец A как столбец со значением и поэтому возвращает столбец B как пустой, когда я вызываю значение этой конкретной ячейки ( Б). Чтобы обойти это, убедитесь, что вы знаете, какие ячейки объединены, а затем возьмите только первую и расценивайте остальные объединенные ячейки как нулевые.

person DAVID OLASUPO    schedule 07.08.2017