Обработка больших объемов данных из Excel - C#
Формулировка задачи:
Здравствуйте!
Есть огромных размеров excel файл, пусть для простоты, в нем хранятся сведения о погоде: дата, температура в этот день (разница между измерениями 10 минут). Встала задача написания на C# программы которая будет:
1) считывать сведения из файла и представлять их в табличном виде;
2) оперировать данными: искать среднее значение в такой-то день и т.п. не важно;
3) создавать новую таблицу с обработанными данными и сохранять её в новом excel файле;
Опционально:
4) хранить обработанные данные в виде БД.
Прочёл где-то на форуме, что обращаться к excel можно с OLE (но сейчас с этой технологией напрямую мало кто работает). Мне не ясно с помощью какого аппарата можно добиться достойного результата.
Если получиться вытащить данные из файла, то каким образом хранить этот огромный набор информации в программе - как много памяти она будет поглощать? как оптимизировать работу? м.б. используя динамические списки, то какая структура оптимальна?
Как быть с БД? тут мне совсем не понятно что делать.
Надеюсь на вашу помощь! Спасибо!
Решение задачи: «Обработка больших объемов данных из Excel»
textual
Листинг программы
namespace ExcelRead_ver_0.1.8
{
public static class ReadTZExcel
{
public static void XLReadTZ(FileStream fileStream, ref DataTable tableScenarios)
{
SLExcelData mExcelData = new SLExcelData();
mExcelData = ReadExcel(fileStream, ref tableScenarios);
}
private static string GetColumnName(string cellReference)
{
var regex = new Regex("[A-Za-z]+");
var match = regex.Match(cellReference);
return match.Value;
}
private static int ConvertColumnNameToNumber(string columnName)
{
var alpha = new Regex("^[A-Z]+$");
if (!alpha.IsMatch(columnName)) throw new ArgumentException();
char[] colLetters = columnName.ToCharArray();
Array.Reverse(colLetters);
var convertedValue = 0;
for (int i = 0; i < colLetters.Length; i++)
{
char letter = colLetters[i];
int current = i == 0 ? letter - 65 : letter - 64; // ASCII 'A' = 65
convertedValue += current * (int)Math.Pow(26, i);
}
return convertedValue;
}
private static string ReadExcelCell(Cell cell, WorkbookPart workbookPart)
{
var cellValue = cell.CellValue;
var text = (cellValue == null) ? cell.InnerText : cellValue.Text;
if ((cell.DataType != null) && (cell.DataType == CellValues.SharedString))
{
text = workbookPart.SharedStringTablePart.SharedStringTable.Elements<SharedStringItem>().ElementAt(
Convert.ToInt32(cell.CellValue.Text)).InnerText;
}
return (text ?? string.Empty).Trim();
}
private static IEnumerator<Cell> GetExcelCellEnumerator(Row row)
{
int currentCount = 0;
foreach (Cell cell in row.Descendants<Cell>())
{
string columnName = GetColumnName(cell.CellReference);
int currentColumnIndex = ConvertColumnNameToNumber(columnName);
for (; currentCount < currentColumnIndex; currentCount++)
{
var emptycell = new Cell() { DataType = null, CellValue = new CellValue(string.Empty) };
yield return emptycell;
}
yield return cell;
currentCount++;
}
}
public static SLExcelData ReadExcel(FileStream file, ref DataTable tableScenarios)
{
var data = new SLExcelData();
// Открыть excel документ
WorkbookPart workbookPart; List<Row> rows;
try
{
var document = SpreadsheetDocument.Open(file, false);
workbookPart = document.WorkbookPart;
var sheets = workbookPart.Workbook.Descendants<Sheet>();
var sheet = sheets.First();
data.SheetName = sheet.Name;
var workSheet = ((WorksheetPart)workbookPart.GetPartById(sheet.Id)).Worksheet;
var columns = workSheet.Descendants<Columns>().FirstOrDefault();
data.ColumnConfigurations = columns;
var sheetData = workSheet.Elements<SheetData>().First();
rows = sheetData.Elements<Row>().ToList();
}
catch (Exception e)
{
data.Status.Message = "Unable to open the file";
return data;
}
// Прочитать заголовок
int columnsCount = 0; // Получили колонок в таблице
if (rows.Count > 0)
{
var row = rows[0];
var cellEnumerator = GetExcelCellEnumerator(row);
while (cellEnumerator.MoveNext())
{
var cell = cellEnumerator.Current;
var text = ReadExcelCell(cell, workbookPart).Trim();
if (text == "") continue;
data.Headers.Add(text);
tableScenarios.Columns.Add(text);
columnsCount++;
}
}
// Прочитать данные
if (rows.Count > 1)
{
string[] rowText = new string[columnsCount];
for (var i = 1; i < rows.Count; i++)
{
var dataRow = new List<string>();
data.DataRows.Add(dataRow);
var row = rows[i];
if (row.InnerText == "") break;
var cellEnumerator = GetExcelCellEnumerator(row);
int tmpCount = 0;
while (cellEnumerator.MoveNext())
{
var cell = cellEnumerator.Current;
var text = ReadExcelCell(cell, workbookPart).Trim();
dataRow.Add(text);
if (((text == "")&&(tmpCount==0)))
continue;
rowText[tmpCount] = text;
tmpCount++;
}
tableScenarios.Rows.Add(rowText);
Array.Clear(rowText, 0, rowText.Length);
}
}
return data;
}
}
}