можно не только через Epplus
Вот пример
Этим c#получаем названия всех листов в xlsx(работает 100%) или xls (не пробовал, но вроде может) в Список 2
в переменной put(пардон за мой француский) путь к файлу
// === Читаем путь ===
string excelFilePath = project.Variables["put"].Value?.Trim() ?? "";
if (string.IsNullOrEmpty(excelFilePath) || !File.Exists(excelFilePath))
{
project.SendErrorToLog("Excel-файл не найден или путь пуст: " + excelFilePath);
return -1;
}
// === Очищаем Список 2 ===
project.Lists["Список 2"].Clear();
// === Определяем расширение ===
string ext = System.IO.Path.GetExtension(excelFilePath).ToLower().Trim();
// === Формируем строку подключения ===
string connString = "";
if (ext == ".xlsx")
{
connString =
"Provider=Microsoft.ACE.OLEDB.12.0;" +
"Data Source=" + excelFilePath + ";" +
"Extended Properties=\"Excel 12.0 Xml;HDR=NO\";";
}
else if (ext == ".xls")
{
connString =
"Provider=Microsoft.Jet.OLEDB.4.0;" +
"Data Source=" + excelFilePath + ";" +
"Extended Properties=\"Excel 8.0;HDR=NO\";";
}
else
{
project.SendErrorToLog("Неизвестный формат файла: " + ext);
return -1;
}
try
{
System.Data.OleDb.OleDbConnection conn =
new System.Data.OleDb.OleDbConnection(connString);
conn.Open();
System.Data.DataTable schema =
conn.GetOleDbSchemaTable(System.Data.OleDb.OleDbSchemaGuid.Tables, null);
if (schema == null || schema.Rows.Count == 0)
{
project.SendErrorToLog("Не удалось получить названия листов.");
conn.Close();
return -1;
}
for (int i = 0; i < schema.Rows.Count; i++)
{
string name = schema.Rows[i]["TABLE_NAME"].ToString();
// === Убираем внешние кавычки ===
name = name.Trim('\'');
// === Убираем скрытые символы Excel (редкий случай) ===
name = name.Replace("\u0001", "").Trim();
// === Проверяем, что это реальный лист ===
if (!name.EndsWith("$")) continue;
// === Гарантированно корректное имя для SQL-запроса ===
// На этом этапе имя 100% подходит под SELECT * FROM [имя]
project.Lists["Список 2"].Add(name);
project.SendInfoToLog("Лист: " + name);
}
conn.Close();
if (project.Lists["Список 2"].Count == 0)
{
project.SendErrorToLog("Не найдено реальных листов.");
return -1;
}
}
catch (Exception ex)
{
project.SendErrorToLog("Ошибка OleDb: " + ex.Message);
return -1;
}
project.SendInfoToLog("Список 2 заполнен. Листов найдено: " + project.Lists["Список 2"].Count);
return 1;
Затем из списка беру строку и этим кодом получаю данные с нужного листа по имени
// === 0. Входные данные ===
string excelFilePath = project.Variables["put"].Value?.Trim() ?? "";
string sheetNameInput = project.Variables["list"].Value?.Trim() ?? "";
string shetStr = project.Variables["shet"].Value?.Trim() ?? "0";
// === 1. Проверки пути ===
if (string.IsNullOrEmpty(excelFilePath) || !System.IO.File.Exists(excelFilePath))
{
project.SendErrorToLog("Excel-файл не найден или пустой путь: " + excelFilePath);
return -1;
}
// === 2. Парсим shet (0 → первая строка) ===
int shet;
if (!int.TryParse(shetStr, out shet))
{
project.SendErrorToLog("shet не число: " + shetStr);
return -1;
}
if (shet < 0) shet = 0;
// === 3. Нормализуем имя листа ===
// убираем внешние одинарные кавычки (OleDb иногда их даёт)
string sheetName = sheetNameInput.Trim('\'').Trim();
// если забыли $, добавим — для OleDb лист в виде "ИмяЛиста$"
if (!sheetName.EndsWith("$"))
{
sheetName = sheetName + "$";
}
project.SendInfoToLog("Работаем с листом: " + sheetName + ", строка (shet) = " + shet);
// === 4. Подготовка переменных проекта ===
project.Variables["postavshik_offer"].Value = "";
project.Variables["artikul"].Value = "";
project.Variables["price"].Value = "";
// === 5. Определяем расширение и строку подключения ===
string ext = System.IO.Path.GetExtension(excelFilePath).ToLower().Trim();
string connString = "";
if (ext == ".xlsx")
{
connString =
"Provider=Microsoft.ACE.OLEDB.12.0;" +
"Data Source=" + excelFilePath + ";" +
"Extended Properties=\"Excel 12.0 Xml;HDR=NO\";";
}
else if (ext == ".xls")
{
connString =
"Provider=Microsoft.Jet.OLEDB.4.0;" +
"Data Source=" + excelFilePath + ";" +
"Extended Properties=\"Excel 8.0;HDR=NO\";";
}
else
{
project.SendErrorToLog("Неизвестный формат файла: " + ext);
return -1;
}
// === 6. Чтение строки с нужного листа ===
try
{
System.Data.OleDb.OleDbConnection conn =
new System.Data.OleDb.OleDbConnection(connString);
conn.Open();
// Формируем запрос к конкретному листу
string query = "SELECT * FROM [" + sheetName + "]";
System.Data.OleDb.OleDbDataAdapter adapter =
new System.Data.OleDb.OleDbDataAdapter(query, conn);
System.Data.DataTable table = new System.Data.DataTable();
adapter.Fill(table);
if (table.Rows.Count == 0)
{
project.SendErrorToLog("Лист пуст: " + sheetName);
conn.Close();
return -1;
}
if (shet >= table.Rows.Count)
{
project.SendErrorToLog(
"Строка с индексом shet=" + shet +
" отсутствует. Всего строк: " + table.Rows.Count
);
conn.Close();
return -1;
}
System.Data.DataRow row = table.Rows[shet];
string col1 = (row.ItemArray.Length > 0 && row[0] != null)
? row[0].ToString().Trim()
: "";
string col2 = (row.ItemArray.Length > 1 && row[1] != null)
? row[1].ToString().Trim()
: "";
string col3 = (row.ItemArray.Length > 2 && row[2] != null)
? row[2].ToString().Trim()
: "";
project.Variables["postavshik_offer"].Value = col1;
project.Variables["artikul"].Value = col2;
project.Variables["price"].Value = col3;
project.SendInfoToLog(
"Строка shet=" + shet +
" → postavshik_offer='" + col1 +
"', artikul='" + col2 +
"', price='" + col3 + "'"
);
conn.Close();
}
catch (Exception ex)
{
project.SendErrorToLog("Ошибка при чтении Excel: " + ex.Message);
return -1;
}
return 1;
Но есть недостаток, у меня exel с 20 листами и тысячами строк, так открытие листа примерно 10 сек. Для одной строки, долго. Но если открыть и обработать весь лист или всю таблицу, будет быстро, так как время тратится на запуск, а уже когда файл весь прочитан, остальное работает шустро (только что проверил нет разницы по времени что получить все вкладки exel, что обработать лист 1000 строк).