Получение списка столбцов в указанном c рабочем листе Excel - PullRequest
1 голос
/ 17 марта 2020

Мне нужна помощь в получении столбцов из определенного листа c с использованием C#. В настоящее время я могу подключиться к файлу Excel и получить чтение столбцов, но он дает мне столбцы для каждого листа в моем Excel, а не конкретный c.

Что я могу сделать с моим кодом, чтобы получить только столбцы из нужного листа? Вот мой код, который в настоящее время заполняет мой список флажков всеми столбцами.

    OleDbConnection excelConnection = new OleDbConnection(String.Format("Provider=Microsoft.ACE.OLEDB.12.0;Data Source={0};Extended Properties=\"Excel 12.0\"", strFullPath));

    using (OleDbCommand cmd = new OleDbCommand("SELECT * FROM [LogFile$]", excelConnection))
    {
            excelConnection.Open();

            DataTable dt = excelConnection.GetSchema("Columns");

            cbColumnList.DataSource = dt;
            cbColumnList.DataTextField = "Column_name";
            cbColumnList.DataValueField = "Column_name";
            cbColumnList.DataBind();
    }

Я уверен, что моя проблема как-то связана с тем, где я создаю DataTable, так как я извлекаю Схему из excelConnection, а не из cmd, таким образом, скорее всего, в моем запросе я обхожу определили рабочую таблицу для получения столбцов. Если это так, как бы я это исправить?

1 Ответ

0 голосов
/ 21 марта 2020

Первое решение

    using System;
    using System.Data;
    using System.Data.OleDb;

    namespace ConsoleApp35
    {
        class Program
        {
            static void Main(string[] args)
            {
                using (OleDbConnection excelConnection = new OleDbConnection(String.Format("Provider=Microsoft.ACE.OLEDB.12.0;Data Source={0};Extended Properties=\"Excel 12.0\"", @"D:\Coverage.xlsx")))
                {
                    excelConnection.Open();
                    var dt = new DataTable();
                    var da = new OleDbDataAdapter();
                    var _command = new OleDbCommand();
                    _command.Connection = excelConnection;
                    _command.CommandText = "SELECT * FROM [Sheet1$]";
                    da.SelectCommand = _command;

                    try
                    {
                        da.Fill(dt);

                        // printing columns names
                        foreach (DataColumn d in dt.Columns)
                        {
                            Console.WriteLine(d.ColumnName);
                        }

                        // dt has all data from Sheet1
                        foreach (DataRow r in dt.Rows)
                        {
                            Console.WriteLine(String.Join(", ", r.ItemArray));
                        }
                    }
                    catch (Exception e)
                    {
                        // process error here
                    }

                    Console.ReadLine();
                }
            }
        }
    }

Второе решение

Это решение предназначено для тех, кто имеет те же требования, но использует Open XML .

Установите оба пакета Open XML от Microsoft: https://www.microsoft.com/en-us/download/details.aspx?displaylang=en&id=5124

В своем решении добавьте ссылки на сборки DocumentFormat.Open Xml и WindowsBase. Добавьте следующее, используя директивы:

    using DocumentFormat.OpenXml.Spreadsheet;
    using DocumentFormat.OpenXml.Packaging;
    using System.Text.RegularExpressions; 

Добавьте следующие методы в ваш класс, который обрабатывает ваш файл Excel.

    private static string GetColumnName(string cellName)
    {
        var regex = new Regex("[a-zA-Z]+");
        var match = regex.Match(cellName);
        return match.Value;
    }

    public static SharedStringItem GetSharedStringItemById(WorkbookPart 
    workbookPart, int id)
    {
        return workbookPart.SharedStringTablePart.SharedStringTable.Elements<SharedStringItem> ().ElementAt(id);
    }

Используйте следующий код для получения имен столбцов с указанного листа. Кроме того, кроме того, вы можете обработать все необходимые данные из файла. Я протестировал чтение данных из простого листа Excel, который содержит 2 столбца и несколько строк, где ячейки имеют целочисленные и строковые значения. Для обработки других типов данных вам необходимо добавить дополнительные блоки проверки кода cell.DataType.

    var columnsNames = new HashSet<string>();
    var data = new List<List<string>>();
    using (SpreadsheetDocument myDoc = 
    DocumentFormat.OpenXml.Packaging.SpreadsheetDocument.Open(@"D:\FileName.xlsx", 
    false))
    {
        foreach (Sheet s in myDoc.WorkbookPart.Workbook.Sheets)
        {
            if (s.Name == "Sheet1") {
                string relationshipId = s.Id.Value;
                WorksheetPart worksheetPart = (WorksheetPart)myDoc.WorkbookPart.GetPartById(relationshipId);
                var sd = worksheetPart.Worksheet.Elements<SheetData>().First();
                IEnumerable<Row> rows = sd.Elements<Row>();
                foreach (Row row in rows)
                {
                      var rowList = new List<string>();
                      foreach (Cell cell in row.Elements<Cell>())
                      {
                            // get columns names
                            var columnName = GetColumnName(cell.CellReference.Value);
                            columnsNames.Add(columnName);

                            // process data
                            string cellValue = string.Empty;
                            if (cell.DataType != null)
                            {
                                if (cell.DataType == CellValues.SharedString)
                                {
                                    int id = -1;

                                    if (Int32.TryParse(cell.InnerText, out id))
                                    {
                                        SharedStringItem item = GetSharedStringItemById(myDoc.WorkbookPart, id);

                                        if (item.Text != null)
                                        {
                                            cellValue = item.Text.Text;
                                        }
                                        else if (item.InnerText != null)
                                        {
                                            cellValue = item.InnerText;
                                        }
                                        else if (item.InnerXml != null)
                                        {
                                            cellValue = item.InnerXml;
                                        }
                                    }
                                }
                            }
                            else
                            {
                                cellValue = cell.CellValue.Text;
                            }

                            rowList.Add(cellValue);
                      }
                      data.Add(rowList);
                }
             }
        }
        myDoc.Close();
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...