Оптимальный способ чтения файла Excel (.xls/.xlsx)
Я знаю, что есть разные способы чтения файла Excel:
-
Iterop
-
Oledb
-
Open Xml SDK
Совместимость не является вопросом, потому что программа будет выполнена в контролируемой среде.
Мои требования:
Прочитайте файл в DataTable
/CUstom Entitie
(я не знаю, как сделать динамические свойства/поля для объекта [имена столбцов будут изменяться в файле Excel])
Используйте DataTable/Custom Entities
для выполнения некоторых операций с использованием своих данных.
Обновить DataTable
с результатами операций
Запишите его обратно в excel file
.
Что было бы проще.
Также, если возможно, посоветуйте мне на пользовательских объектах (динамически добавляя свойства/поля к объекту)
Ответы
Ответ 1
Посмотрите Linq-to-Excel. Это довольно аккуратно.
var book = new LinqToExcel.ExcelQueryFactory(@"File.xlsx");
var query =
from row in book.Worksheet("Stock Entry")
let item = new
{
Code = row["Code"].Cast<string>(),
Supplier = row["Supplier"].Cast<string>(),
Ref = row["Ref"].Cast<string>(),
}
where item.Supplier == "Walmart"
select item;
Он также позволяет использовать строго типизированный доступ к строке.
Ответ 2
Используя OLE Query, это довольно просто (например, sheetName - это Sheet1):
DataTable LoadWorksheetInDataTable(string fileName, string sheetName)
{
DataTable sheetData = new DataTable();
using (OleDbConnection conn = this.returnConnection(fileName))
{
conn.Open();
// retrieve the data using data adapter
OleDbDataAdapter sheetAdapter = new OleDbDataAdapter("select * from [" + sheetName + "$]", conn);
sheetAdapter.Fill(sheetData);
conn.Close();
}
return sheetData;
}
private OleDbConnection returnConnection(string fileName)
{
return new OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + fileName + "; Jet OLEDB:Engine Type=5;Extended Properties=\"Excel 8.0;\"");
}
Для более новых версий Excel:
return new OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + fileName + ";Extended Properties=Excel 12.0;");
Вы также можете использовать Excel Data Reader с открытым исходным кодом в CodePlex. Его очень хорошо работает для экспорта данных из листов Excel.
Пример кода приведен по указанной ссылке:
FileStream stream = File.Open(filePath, FileMode.Open, FileAccess.Read);
//1. Reading from a binary Excel file ('97-2003 format; *.xls)
IExcelDataReader excelReader = ExcelReaderFactory.CreateBinaryReader(stream);
//...
//2. Reading from a OpenXml Excel file (2007 format; *.xlsx)
IExcelDataReader excelReader = ExcelReaderFactory.CreateOpenXmlReader(stream);
//...
//3. DataSet - The result of each spreadsheet will be created in the result.Tables
DataSet result = excelReader.AsDataSet();
//...
//4. DataSet - Create column names from first row
excelReader.IsFirstRowAsColumnNames = true;
DataSet result = excelReader.AsDataSet();
//5. Data Reader methods
while (excelReader.Read())
{
//excelReader.GetInt32(0);
}
//6. Free resources (IExcelDataReader is IDisposable)
excelReader.Close();
Справка: Как импортировать из Excel в набор данных с помощью Microsoft.Office.Interop.Excel?
Ответ 3
Я понимаю, что этот вопрос задавался почти 7 лет назад, но он по-прежнему является лучшим результатом поиска Google по определенным ключевым словам, касающимся импорта данных Excel с С#, поэтому я хотел предоставить альтернативу, основанную на некоторых последних технических разработках.
Импорт данных Excel стал настолько распространенной задачей в моих повседневных обязанностях, что я упростил процесс и задокументировал метод в своем блоге: лучший способ прочитать файл Excel в c #.
Я использую NPOI, потому что он может читать/записывать файлы Excel без установленного Microsoft Office и не использует COM+ или какие-либо операции. Это означает, что он может работать в облаке!
Но настоящая магия заключается в сопряжении с NPOI Mapper от Donny Tian, потому что это позволяет мне сопоставлять столбцы Excel со свойствами в моих классах С# без написания какого-либо кода. Это красиво.
Вот основная идея:
Я создаю класс .net, который соответствует/сопоставляет интересующие меня столбцы Excel:
class CustomExcelFormat
{
[Column("District")]
public int District { get; set; }
[Column("DM")]
public string FullName { get; set; }
[Column("Email Address")]
public string EmailAddress { get; set; }
[Column("Username")]
public string Username { get; set; }
public string FirstName
{
get
{
return Username.Split('.')[0];
}
}
public string LastName
{
get
{
return Username.Split('.')[1];
}
}
}
Обратите внимание, это позволяет мне отображать на основе имени столбца, если я хочу!
Затем, когда я обрабатываю файл Excel, все, что мне нужно сделать, это примерно так:
public void Execute(string localPath, int sheetIndex)
{
IWorkbook workbook;
using (FileStream file = new FileStream(localPath, FileMode.Open, FileAccess.Read))
{
workbook = WorkbookFactory.Create(file);
}
var importer = new Mapper(workbook);
var items = importer.Take<CustomExcelFormat>(sheetIndex);
foreach(var item in items)
{
var row = item.Value;
if (string.IsNullOrEmpty(row.EmailAddress))
continue;
UpdateUser(row);
}
DataContext.SaveChanges();
}
Теперь, по общему признанию, мой код не изменяет сам файл Excel. Вместо этого я сохраняю данные в базе данных, используя Entity Framework (вот почему вы видите "UpdateUser" и "SaveChanges" в моем примере). Но на SO уже идет хорошее обсуждение того, как сохранить/изменить файл с помощью NPOI.
Ответ 4
Попробуйте воспользоваться этим бесплатным способом, https://freenetexcel.codeplex.com
Workbook workbook = new Workbook();
workbook.LoadFromFile(@"..\..\parts.xls",ExcelVersion.Version97to2003);
//Initialize worksheet
Worksheet sheet = workbook.Worksheets[0];
DataTable dataTable = sheet.ExportDataTable();
Ответ 5
Если вы можете ограничить его просто (формат Open Office XML) *.xlsx, то, вероятно, наиболее популярной библиотекой будет EPPLus.
Бонус есть, других зависимостей нет. Просто установите с помощью nuget:
Install-Package EPPlus
Ответ 6
Лично я нашел с открытым исходным кодом & бесплатно ExcelMapper проще всего работать.
Он обеспечивает гораздо более краткий (то есть читаемый) способ чтения файлов Excel по сравнению с обычным Microsoft.Interop & OLE-запросы.
1. Имеется файл Excel:
![enter image description here]()
2. Создайте объект Person С#:
public class Person
{
public string FirstName { get; set; }
public string LastName { get; set; }
public string Email { get; set; }
}
3. Прочтите его, используя ExcelMapper
var fileName = @"C:\Temp\Names.xlsx"; // your excel file
List<Person> people = new ExcelMapper(fileName).Fetch<Person>();
Вы также можете читать из других таблиц, просто передав дополнительный аргумент листа:
var fileName = @"C:\Temp\Names.xlsx"; // your excel file
List<Person> people = new ExcelMapper(fileName).Fetch<Person>("Sheet2");
Вы можете установить его с помощью NuGet
Install-Package ExcelMapper
Отказ от ответственности: я не связан с ExcelMapper, но, попробовав различные библиотеки, я нашел, что с этой библиотекой проще всего работать.
Вот короткое видео, демонстрирующее вышеизложенное.
Ответ 7
Попробуйте использовать библиотеку Aspose.cells, это неплохо.
Install-package Aspose.cells
Пример кода:
using Aspose.Cells;
using System;
namespace ExcelReader
{
class Program
{
static void Main(string[] args)
{
// Replace path for your file
readXLS(@"C:\MyExcelFile.xls"); // or "*.xlsx"
Console.ReadKey();
}
public static void readXLS(string PathToMyExcel)
{
//Open your template file.
Workbook wb = new Workbook(PathToMyExcel);
//Get the first worksheet.
Worksheet worksheet = wb.Worksheets[0];
//Get cells
Cells cells = worksheet.Cells;
// Get row and column count
int rowCount = cells.MaxDataRow;
int columnCount = cells.MaxDataColumn;
// Current cell value
string strCell = "";
Console.WriteLine(String.Format("rowCount={0}, columnCount={1}", rowCount, columnCount));
for (int row = 0; row <= rowCount; row++) // Numeration starts from 0 to MaxDataRow
{
for (int column = 0; column <= columnCount; column++) // Numeration starts from 0 to MaxDataColumn
{
strCell = "";
strCell = Convert.ToString(cells[row, column].Value);
if (String.IsNullOrEmpty(strCell))
{
continue;
}
else
{
// Do your staff here
Console.WriteLine(strCell);
}
}
}
}
}
}