Генератор отчетов на C# - Часть 4 (Сохранение dataGridView в файл XLS)

Финальная часть проекта заключается в написании метода для сохранения данных из двух полученных dataGridView в файл XLS (MS Excel 2003). Для этого мы воспользуемся возможностями сторонней библиотеки ExcelLibrary. Также в этой части мы сохраним полученные в процессе работы программы логи в файл.


Собственно, вот сам код метода сохранения отчета в XLS-файл с помощью ExcelLibrary:

public void SaveReport(string pathToSaveRep) // Метод сохранения отчета в XLS-файл
{
    progressBar.Value = 0;
    progressBar.Minimum = 0;
    progressBar.Maximum = dgvWorkTable.ColumnCount + dgvWorkTable.RowCount + dgvSummary.ColumnCount + dgvSummary.RowCount + 10;
    DataSet ds = new DataSet();

    DataTable Work = new DataTable("Выгрузка");
    // Заполняем столбцы рабочей таблицы
    for (int i = 0; i < dgvWorkTable.ColumnCount; i++)
    {
        Work.Columns.Add(dgvWorkTable.Columns[i].HeaderText);
        progressBar.Value++;
    }

    // Заполняем строки рабочей таблицы
    foreach (DataGridViewRow row in dgvWorkTable.Rows)
    {
        DataRow datarw = Work.NewRow();

        for (int iCol = 0; iCol < dgvWorkTable.ColumnCount; iCol++)
        {
            datarw[iCol] = row.Cells[iCol].Value;
        }

        Work.Rows.Add(datarw);
        progressBar.Value++;
    }

    Work.Columns["Код АТЕ"].SetOrdinal(2);
    Work.Columns["Наименование АТЕ"].SetOrdinal(3);

    DataTable Summary = new DataTable("Сводная таблица");
    // Заполняем столбцы сводной таблицы
    for (int i = 0; i < dgvSummary.ColumnCount; i++)
    {
        Summary.Columns.Add(dgvSummary.Columns[i].HeaderText);
        progressBar.Value++;
    }

    // Заполняем строки сводной таблицы
    foreach (DataGridViewRow row in dgvSummary.Rows)
    {
        DataRow datarw = Summary.NewRow();

        for (int iCol = 0; iCol < dgvSummary.ColumnCount; iCol++)
        {
            datarw[iCol] = row.Cells[iCol].Value;
        }

        Summary.Rows.Add(datarw);
        progressBar.Value++;
    }
    // Добавляем в DataSet полученные DataTable
    ds.Tables.Add(Work);
    ds.Tables.Add(Summary);
    // Используем библиотеку ExcelLibrary для экспорта в XLS файл
    DataSetHelper.CreateWorkbook(pathToSaveRep, ds);

    progressBar.Value += 10;
    tbLogs.Text += Environment.NewLine + Environment.NewLine + DateTime.Now + ": Отчет успешно сохранен: " + pathToSaveRep;
}

Алгоритм работы кода:

  • Метод принимает один аргумент типа string, который должен содержать путь для сохранения файла.
  • Устанавливаем значения для progressBar (Максимальное значение берется из суммарного количества итераций циклов по dataGridView в теле метода + 10 для сохранения DataSet в файл XLS).
  • Инициализируем экземпляр DataSet.
  • Инициализируем DataTable Work для таблицы обработки выгрузки, в конструкторе экземпляра даем имя таблице "Выгрузка" - имя будет использовано как имя листа в книге Excel.
  • С помощью цикла for копируем столбцы из dgvWork в DataTable Work, а с при помощи цикла foreach копируем все строки dataGridView в DataTable.
  • С помощью метода SetOrdinal() переносим столбцы с кодом и наименованием района на нужные нам индексы.
  • Аналогичным образом создаем DataTable для сводной таблицы и заносим в неё данные.
  • Добавляем полученные DataTable в DataSet.
  • Используем метод DataSetHelper.CreateWorkbook() библиотеки ExcelLibrary для создания XLS-файла и заполнения его содержимым DataSet.
  • Отписываемся в tbLogs об успешном сохранении отчета с указанием пути к нему.

Для кнопки сохранения отчета пишем следующий код:


private void butSaveReport_Click(object sender, EventArgs e) // Сохранение отчета
{
    SaveFileDialog saveRep = new SaveFileDialog();
    saveRep.Filter = "Файл Excel (2003) |*.xls";
    saveRep.Title = "Сохранить отчет в файл";
    saveRep.FileName = "Отчет от " + DateTime.Today.ToShortDateString();
    if (saveRep.ShowDialog() == DialogResult.OK) SaveReport(saveRep.FileName);
}


Теперь программа умеет сохранять созданный отчет и основная работа над ней закончена. На случай, если при разработке я чего-то не предусмотрел и всегда можно было отследить ошибку - я создал вкладку с textBox, в который записываются все действия в приложении за последнюю сессию, а также это поле полезно и для простого пользователя, так как приложение мгновенно в него напишет, если возникли проблемы с целостностью. Тем не менее, логи не полноценны, если они не сохраняются автоматически. Для этого было решено создать событие перед закрытием MainForm:


private void MainForm_FormClosing(object sender, FormClosingEventArgs e) // Событие при закрытии программы (ДО закрытия формы)
{
    // Создаем/Перезаписываем файл logs.txt в корневой папке программы с данными о прошедшей сессии.
    FileStream stream = File.Open(Application.StartupPath + "\\logs.txt", FileMode.Create, FileAccess.ReadWrite);
    StreamWriter write = new StreamWriter(stream, Encoding.Default);
    write.Write(tbLogs.Text);
    write.Close();
    stream.Close();
}


Данный код создает (либо перезаписывает) файл logs.txt в корневой папке приложения в конце каждой сессии работы с программой.

Для создания формы с информацией о программе была использована готовая форма "AboutBox", доступная для создания любому пользователю студии. Все данные для нее берутся из свойств проекта.

На этом создание проекта завершается. Спасибо за внимание! Готовый проект, как всегда, можно скачать на соответствующей странице блога.