Как считать данные файла Excel с помощью C#?

Я согласен, что этот вопрос лучше подходит для Code Review.

В любом случае вы можете сделать что-то вроде этого:

Шаг 1: Создать метод (ы) расширения

public static IQueryable<T> SortByField<T, TKey>(this IQueryable<T> source, Expression<Func<T, TKey>> selector, bool ascending = true)
{
    return ascending ? source.OrderBy(selector) : source.OrderByDescending(selector);
}

public static IQueryable<T> SortByField<T, TKey>(this IQueryable<T> source, Expression<Func<T, TKey>> selector, string order = "asc")
{
    return SortByField(source, selector, order.Equals("asc", StringComparison.OrdinalIgnoreCase)); //condition here can be improved, just as a sample of how to do it
}

Шаг 2: Наслаждайтесь:

 var samples = new List<Sample>().AsQueryable(); //you can of course use LINQ to SQL or EF, but I am lazy
 samples.SortByField(t => t.NumberForSort, false); //or "asc"

Я думаю, что улучшение вашего объекта «команда» / запрос поможет очистить код.

Рэнт: «Дело» является для меня последним средством, оно почти всегда означает, что есть как минимум два места, где я должен изменить код, которые не всегда могут находиться в одной сборке, и почти во всех случаях слова «case» можно заменить на словарь или шаблон «Strategy».

64
задан Community 26 June 2013 в 20:08
поделиться

3 ответа

Хорошо,

Одно из более трудных понятий для схватывания о программировании Excel VSTO - то, что Вы не обращаетесь к ячейкам как массив, Worksheet[0][0] не даст Вам ячейку A1, это будет ошибка на Вас. Даже когда Вы вводите в A1, когда Excel открыт, Вы на самом деле вводите данные в Диапазон A1. Поэтому Вы называете ячейки Именованными Диапазонами. Вот пример:

Excel.Worksheet sheet = workbook.Sheets["Sheet1"] as Excel.Worksheet; 
Excel.Range range = sheet.get_Range("A1", Missing.Value)

можно теперь буквально ввести:

range.Text // this will give you the text the user sees
range.Value2 // this will give you the actual value stored by Excel (without rounding)

, Если Вы хотите сделать что-то вроде этого:

Excel.Range range = sheet.get_Range("A1:A5", Missing.Value)

if (range1 != null)
     foreach (Excel.Range r in range1)
     {
         string user = r.Text
         string value = r.Value2

     }

мог бы быть лучший путь, но это работало на меня.

причина необходимо использовать Value2, а не Value то, потому что Value свойство является параметрическим, и C# еще не поддерживает их.

Что касается кода очистки, я отправлю это, когда я возьмусь за работу завтра, у меня нет кода со мной, но это - очень шаблон. Вы просто закрываете и выпускаете объекты в обратном порядке, Вы создали их. Вы не можете использовать Using() блок потому что Excel. Приложение или Excel. Рабочая книга не реализует IDisposable, и если Вы не сделаете очистки, то Вас оставят с зависающим Excel объекты в памяти.

Примечание:

  • , Если Вы не устанавливаете Visibility, свойство Excel не отображается, который может быть дезориентирующим Вашим пользователям, но если Вы хотите просто сорвать данные, которые являются, вероятно, достаточно хороши
  • , Вы могли OleDb, который будет работать также.

я надеюсь, что это запустило Вас, сообщите мне, нужно ли Вам дальнейшее разъяснение. Я отправлю полное

, вот полная выборка:

using System;
using System.IO;
using System.Reflection;
using NUnit.Framework;
using ExcelTools = Ms.Office;
using Excel = Microsoft.Office.Interop.Excel;

namespace Tests
{
    [TestFixture]
    public class ExcelSingle
    {
        [Test]
        public void ProcessWorkbook()
        {
            string file = @"C:\Users\Chris\Desktop\TestSheet.xls";
            Console.WriteLine(file);

            Excel.Application excel = null;
            Excel.Workbook wkb = null;

            try
            {
                excel = new Excel.Application();

                wkb = ExcelTools.OfficeUtil.OpenBook(excel, file);

                Excel.Worksheet sheet = wkb.Sheets["Data"] as Excel.Worksheet;

                Excel.Range range = null;

                if (sheet != null)
                    range = sheet.get_Range("A1", Missing.Value);

                string A1 = String.Empty;

                if( range != null )
                    A1 = range.Text.ToString();

                Console.WriteLine("A1 value: {0}", A1);

            }
            catch(Exception ex)
            {
                //if you need to handle stuff
                Console.WriteLine(ex.Message);
            }
            finally
            {
                if (wkb != null)
                    ExcelTools.OfficeUtil.ReleaseRCM(wkb);

                if (excel != null)
                    ExcelTools.OfficeUtil.ReleaseRCM(excel);
            }
        }
    }
}

я отправлю функции от ExcelTools завтра, у меня нет того кода со мной также.

Редактирование: Как обещано, вот Функции от ExcelTools, в котором Вы, возможно, нуждались бы.

public static Excel.Workbook OpenBook(Excel.Application excelInstance, string fileName, bool readOnly, bool editable,
        bool updateLinks) {
        Excel.Workbook book = excelInstance.Workbooks.Open(
            fileName, updateLinks, readOnly,
            Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing,
            Type.Missing, editable, Type.Missing, Type.Missing, Type.Missing,
            Type.Missing, Type.Missing);
        return book;
    }

public static void ReleaseRCM(object o) {
        try {
            System.Runtime.InteropServices.Marshal.ReleaseComObject(o);
        } catch {
        } finally {
            o = null;
        }
    }

, Чтобы быть откровенным, этот материал намного легче при использовании VB.NET. Это находится в C#, потому что я не записал это. VB.NET делает опциональные параметры хорошо, C# не делает, следовательно Тип. Пропавшие без вести. Как только Вы ввели Тип. Отсутствуя дважды подряд, Вы выполняете крик из комнаты!

Что касается Вас вопрос, можно попробовать к следующему:

http://msdn.microsoft.com/en-us/library/microsoft.office.interop.excel.range.find (По сравнению с 80) .aspx

я отправлю пример, когда я возвращусь из своей встречи... приветствует

Редактирование: Вот пример

range = sheet.Cells.Find("Value to Find",
                                                 Type.Missing,
                                                 Type.Missing,
                                                 Type.Missing,
                                                 Type.Missing,
                                                 Excel.XlSearchDirection.xlNext,
                                                 Type.Missing,
                                                 Type.Missing, Type.Missing);

range.Text; //give you the value found

, Вот другой пример, вдохновленный этим сайт :

 range = sheet.Cells.Find("Value to find", Type.Missing, Type.Missing,Excel.XlLookAt.xlWhole,Excel.XlSearchOrder.xlByColumns,Excel.XlSearchDirection.xlNext,false, false, Type.Missing);

Это помогает понять параметры.

P.S. Я - один из тех странных людей, который любит изучать автоматизацию COM. Весь этот код двигался от инструмента, который я записал для работы, которая потребовала, чтобы я обрабатывал более чем 1 000 + электронные таблицы из лаборатории каждый понедельник.

85
ответ дан Paul Fleming 24 November 2019 в 15:49
поделиться

Почему Вы не создаете OleDbConnection? Существует много имеющихся ресурсов в Интернете. Вот пример

OleDbConnection con = new OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source="+filename+";Extended Properties=Excel 8.0");
con.Open();
try
{
     //Create Dataset and fill with imformation from the Excel Spreadsheet for easier reference
     DataSet myDataSet = new DataSet();
     OleDbDataAdapter myCommand = new OleDbDataAdapter(" SELECT * FROM ["+listname+"$]" , con);
     myCommand.Fill(myDataSet);
     con.Close();
     richTextBox1.AppendText("\nDataSet Filled");

     //Travers through each row in the dataset
     foreach (DataRow myDataRow in myDataSet.Tables[0].Rows)
     {
          //Stores info in Datarow into an array
          Object[] cells = myDataRow.ItemArray;
          //Traverse through each array and put into object cellContent as type Object
          //Using Object as for some reason the Dataset reads some blank value which
          //causes a hissy fit when trying to read. By using object I can convert to
          //String at a later point.
          foreach (object cellContent in cells)
          {
               //Convert object cellContect into String to read whilst replacing Line Breaks with a defined character
               string cellText = cellContent.ToString();
               cellText = cellText.Replace("\n", "|");
               //Read the string and put into Array of characters chars
               richTextBox1.AppendText("\n"+cellText);
          }
     }
     //Thread.Sleep(15000);
}
catch (Exception ex)
{
     MessageBox.Show(ex.ToString());
     //Thread.Sleep(15000);
}
finally
{
     con.Close();
}
17
ответ дан Pikoh 24 November 2019 в 15:49
поделиться

В первую очередь, важно знать то, под чем Вы подразумеваете, "открывают файл Excel для чтения и копируют его в буфер обмена..."

Это очень важно, потому что существует много способов, которыми Вы могли сделать это зависящее только от того, что Вы намереваетесь сделать. Позвольте мне объяснить:

  1. , Если Вы хотите считать ряд данных и копии, что в буфере обмена и Вы знаете формат данных (например, имена столбцов), я предлагаю, чтобы Вы использовали OleDbConnection для открытия файла, этот способ, которым можно рассматривать xls содержание файла как Таблицу базы данных, таким образом, можно считать данные с инструкцией по SQL и рассматривать данные, как Вы хотите.

  2. , Если Вы хотите сделать, операции на данных с объектной моделью Excel тогда открывают его в способе, которым Вы начали.

  3. Некоторое время возможно рассматривать xls файл как своего рода файл CSV, существуют инструменты как Помощники Файла , которые разрешают Вам рассматривать и открывать xls файл простым способом путем отображения структуры на произвольном объекте.

Другой важный момент находится, в котором версия Excel файл.

я имею, к сожалению, я говорю, большой опыт, работающий с Автоматизацией делопроизводства во всех отношениях, даже если ограниченный в понятиях как Автоматизация Приложения, управление данными и Плагины, и обычно я предлагаю только в качестве последнего средства к использованию автоматизации Excel или Автоматизации делопроизводства считать данные; просто, если нет лучших способов выполнить ту задачу.

Работа с автоматизацией могла быть тяжелой в производительности, с точки зрения стоимости ресурса, могла вовлечь в другие проблемы, связанные, например, с безопасностью и больше, и продлиться, но не, по крайней мере, работающий со взаимодействующим с COM, это не настолько "свободно".. Таким образом, мое предложение, думают и анализируют ситуацию в Ваших потребностях и затем берут лучший путь.

5
ответ дан Lance Roberts 24 November 2019 в 15:49
поделиться
Другие вопросы по тегам:

Похожие вопросы: