- Регистрация
- 01.10.2015
- Сообщения
- 256
- Реакции
- 1 058
- Баллы
- 93
Приветствую всех!
Наверняка многие из вас создавали шаблоны-парсеры. И, как правило, результаты в этом случае на выходе помещали в Excel-таблицы. Функционала ZennoPoster хватает для осуществления этих задач, за исключением несколько нюансов. Например, отсутствуют возможности для стилизации выходных таблиц, работать можно исключительно с первым листом, записывать данные можно только в строковом формате. Нет прочих различных плюшек, доступных в Excel.
Согласитесь, куда приятнее, когда на выходе получаешь вторую табличку, а не первую (см. скриншоты ниже). А если делаем парсер на заказ, а не для своих личных целей – и говорить нечего. Именно об этом и пойдёт речь в статье – как максимально просто получить красивый Excel-отчёт в ZennoPoster, с нуля до конкретного результата.
Давайте рассмотрим возможные способы реализации.
Недавно, с версии 5.10.0.0, со стороны ZennoPoster лёд чуть-чуть тронулся – появились методы для редактирования стилей ячеек через C#-сниппеты. Однако, пока сложно сказать, что это хотя бы отчасти решило проблему. Возможности самые базовые, опять же только стили, и в любом случае их надо задавать через код – для тех, кто использует чисто кубики, по сути ничего не изменилось.
Поэтому, данный способ нам не совсем подходит. Что же делать?
Думаю, многим из вас известен альтернативный метод – использование сторонней dll-библиотеки, с помощью которой можно воплотить большую часть возможностей Excel. Однако, есть одна существенная проблема – всё оформление таблиц опять же надо писать через C#-код, и даже для той сравнительно простой желанной таблички с картинки выше – его нужно написать достаточно много. Ну и конечно, для этого надо уметь в нём неплохо разбираться. На форуме, кстати, есть статья об использовании такой библиотеки, но, к сожалению, там опять же описаны только самые азы применения стилей и форматирования – те же, которые появились в ZP v5.10.
Тем не менее, мы остановимся именно на этом способе – так как у библиотеки, которую мы будем использовать (а именно известный и могучий EPPlus), есть одна шикарная фича – создание таблиц по шаблону.
Что это значит? То, что мы можем создать xlsx-файл, нарисовать в нём вручную в Excel всё оформление – а в ZennoPoster использовать его как шаблон стилей для результирующего файла. Всё, что нам останется – вставить в область данных результаты парсинга.
Без кода тут, конечно, всё равно не обойтись, но его совсем немного. Главное и самое сложное - оформление - мы делаем руками в Excel, соответственно - нам не потребуются программерские способности и не придётся убить кучу времени на копание в документации библиотеки.
Вводную часть закончили, приступим к делу.
Собственно, рисуем в Excel заголовки и их стили, выравниваем всё, добавляем другие вещи по желанию (например, строку фильтра).
Так как стандартными средствами ZennoPoster можно работать только с первым листом Excel-файла (тоже порой весьма неприятное ограничение), рассмотрим пример с заполнением 2 листов.
Для примера нарисовал такие таблички. Также сразу добавил фильтры, закрепил области заголовков, кое-где добавил примечания. Над тематикой содержимого особо не заморачивался и взял первое что пришло в голову, соответственно, по этому поводу просьба не пинаться – всё это чисто для примера.
Сохраняем файл в папке с проектом, я назвал его Template.xlsx.
Теперь нам нужно подключить к нашему проекту саму библиотеку EPPlus.
Наверняка многие умеют подключать dll-библиотеки, но на всякий случай разберём под спойлером по шагам.
Переходим к основным действиям. В первую очередь, создаём кубик C#-кода, в который поместим весь описанный ниже код.
1. Получаем внутренние таблицы проекта, предварительно заполненные нужными данными (которые спарсили/сгенерировали/получили из БД/ещё от куда-либо).
2. Определяем значения стартовых рядов и столбцов. Например, если первый ряд листа занимают заголовки столбцов, а со второго начинаются сами данные – значением стартового ряда будет 2. Со столбцами аналогично.
Если нужно получить начальный ряд или столбец из переменной проекта, определяем переменные следующим образом:
3. Объявляем вспомогательные переменные для типов данных в ячейках итоговой таблицы – они понадобятся нам чуть позже.
4. Получаем наш файл-шаблон Template.xlsx из директории проекта. Сразу делаем проверку на его наличие.
5. Создаём объект нашего Excel-документа на базе Template.xlsx. Отныне весь дальнейший код будем писать внутри данных фигурных скобок.
6. Прежде чем начать работу с листами, их нужно определить/получить из шаблона. Сделаем это по их порядковым номерам.
7. Далее, нам нужно записать в первый лист данные из первой таблицы проекта. Это можно сделать в двойном цикле, вот так:
…но мы этого делать не будем, так как в этом случае все данные запишутся в обычном строковом формате (все данные стандартных таблиц Zenno хранятся как строки). Библиотека позволяет нам записывать в Excel-файл данные именно тех типов, которые нам нужны, и мы этим воспользуемся.
Получилось слегка посложнее, но зато теперь у нас корректно будут записываться данные.
8. Отформатируем полученную табличку в более приглядный вид. Стили таблиц аналогичны тем, которые можно увидеть в Excel, только английскими названиями. «Light1» соответствует «Светлый1», «Medium1» – «Средний1», «Dark1» – «Темный1». Конкретно для первого листа я посчитал подходящим стиль «Светлый19».
9. Переходим ко второму листу. По аналогии вставляем в него данные из второй таблицы.
По уму, конечно, стоит оформлять подобные вещи в метод/процедуру, но у нас сейчас задача показать именно работу с функционалом библиотеки.
Для разнообразия выберем немного иной формат даты.
10. Как вы могли заметить, в нарисованных заголовках второго листа был последний столбец под названием «Всего», и для него я не создал данных для заполнения. Рассмотрим такую ситуацию, что в ячейки этого столбца нужно получить суммы чисел для каждой из строк.
Для этого мы воспользуемся формулами – иными словами, зададим столбцу формулу, как мы это обычно делаем в Excel.
Библиотека поддерживает большинство других формул Excel, единственное, рекомендуется их писать в английском варианте и без знака «=».
11. По аналогии с первым листом делаем форматирование области данных, теперь только уже вместе со столбцом «Всего». Дополнительно для последнего включаем особое форматирование.
12. Сохраняем полученный файл в папку проекта, называем его Result.xlsx.
Вот, собственно, и всё. После выполнения такого сниппета в папке с проектом появится итоговый файл. В тестовом проекте для этой статьи получаем такие таблички.
Данный проект-пример прикрепляю во вложения к посту.
Наверняка многие из вас создавали шаблоны-парсеры. И, как правило, результаты в этом случае на выходе помещали в Excel-таблицы. Функционала ZennoPoster хватает для осуществления этих задач, за исключением несколько нюансов. Например, отсутствуют возможности для стилизации выходных таблиц, работать можно исключительно с первым листом, записывать данные можно только в строковом формате. Нет прочих различных плюшек, доступных в Excel.
Согласитесь, куда приятнее, когда на выходе получаешь вторую табличку, а не первую (см. скриншоты ниже). А если делаем парсер на заказ, а не для своих личных целей – и говорить нечего. Именно об этом и пойдёт речь в статье – как максимально просто получить красивый Excel-отчёт в ZennoPoster, с нуля до конкретного результата.
Давайте рассмотрим возможные способы реализации.
Недавно, с версии 5.10.0.0, со стороны ZennoPoster лёд чуть-чуть тронулся – появились методы для редактирования стилей ячеек через C#-сниппеты. Однако, пока сложно сказать, что это хотя бы отчасти решило проблему. Возможности самые базовые, опять же только стили, и в любом случае их надо задавать через код – для тех, кто использует чисто кубики, по сути ничего не изменилось.
Поэтому, данный способ нам не совсем подходит. Что же делать?
Думаю, многим из вас известен альтернативный метод – использование сторонней dll-библиотеки, с помощью которой можно воплотить большую часть возможностей Excel. Однако, есть одна существенная проблема – всё оформление таблиц опять же надо писать через C#-код, и даже для той сравнительно простой желанной таблички с картинки выше – его нужно написать достаточно много. Ну и конечно, для этого надо уметь в нём неплохо разбираться. На форуме, кстати, есть статья об использовании такой библиотеки, но, к сожалению, там опять же описаны только самые азы применения стилей и форматирования – те же, которые появились в ZP v5.10.
Тем не менее, мы остановимся именно на этом способе – так как у библиотеки, которую мы будем использовать (а именно известный и могучий EPPlus), есть одна шикарная фича – создание таблиц по шаблону.
Что это значит? То, что мы можем создать xlsx-файл, нарисовать в нём вручную в Excel всё оформление – а в ZennoPoster использовать его как шаблон стилей для результирующего файла. Всё, что нам останется – вставить в область данных результаты парсинга.
Без кода тут, конечно, всё равно не обойтись, но его совсем немного. Главное и самое сложное - оформление - мы делаем руками в Excel, соответственно - нам не потребуются программерские способности и не придётся убить кучу времени на копание в документации библиотеки.
Вводную часть закончили, приступим к делу.
Подготовка шаблона оформления
Собственно, рисуем в Excel заголовки и их стили, выравниваем всё, добавляем другие вещи по желанию (например, строку фильтра).
Так как стандартными средствами ZennoPoster можно работать только с первым листом Excel-файла (тоже порой весьма неприятное ограничение), рассмотрим пример с заполнением 2 листов.
Для примера нарисовал такие таблички. Также сразу добавил фильтры, закрепил области заголовков, кое-где добавил примечания. Над тематикой содержимого особо не заморачивался и взял первое что пришло в голову, соответственно, по этому поводу просьба не пинаться – всё это чисто для примера.

Сохраняем файл в папке с проектом, я назвал его Template.xlsx.
Подключение библиотеки
Теперь нам нужно подключить к нашему проекту саму библиотеку EPPlus.
Наверняка многие умеют подключать dll-библиотеки, но на всякий случай разберём под спойлером по шагам.
1. Скачиваем библиотеку с её официальной странички, http://epplus.codeplex.com/.
2. Находим в архиве нужный файл EPPlus.dll, кидаем в папку ExternalAssemblies в директории с установленным ZennoPoster.
3. Открываем наш шаблон, добавляем блоки «Ссылки из GAC» и «Директивы using»
4. Заходим в «Ссылки из GAC» и добавляем библиотеку.
5. Заходим в «Директивы using» и вписываем туда директивы со скриншота.
2. Находим в архиве нужный файл EPPlus.dll, кидаем в папку ExternalAssemblies в директории с установленным ZennoPoster.
3. Открываем наш шаблон, добавляем блоки «Ссылки из GAC» и «Директивы using»
4. Заходим в «Ссылки из GAC» и добавляем библиотеку.
5. Заходим в «Директивы using» и вписываем туда директивы со скриншота.
Сниппет создания Excel-файла по шаблону
Переходим к основным действиям. В первую очередь, создаём кубик C#-кода, в который поместим весь описанный ниже код.
1. Получаем внутренние таблицы проекта, предварительно заполненные нужными данными (которые спарсили/сгенерировали/получили из БД/ещё от куда-либо).
C#:
//Получаем временные таблицы с нужными данными
var table1 = project.Tables["Таблица 1"];
var table2 = project.Tables["Таблица 2"];
2. Определяем значения стартовых рядов и столбцов. Например, если первый ряд листа занимают заголовки столбцов, а со второго начинаются сами данные – значением стартового ряда будет 2. Со столбцами аналогично.
C#:
//Определяем ряд итоговой таблицы, с которого будем вставлять данные
int startRowT1 = 3; //Для первого листа
int startRowT2 = 4; //Для второго листа
//Определяем столбец итоговой таблицы, с которого будем вставлять данные
int startColT1 = 1; //Для первого листа
int startColT2 = 1; //Для второго листа
C#:
int startRowT1 = int.Parse(project.Variables["Peremennaya"].Value);
3. Объявляем вспомогательные переменные для типов данных в ячейках итоговой таблицы – они понадобятся нам чуть позже.
C#:
DateTime dt;
double d;
int i;
4. Получаем наш файл-шаблон Template.xlsx из директории проекта. Сразу делаем проверку на его наличие.
C#:
FileInfo template = new FileInfo(project.Directory + @"\Template.xlsx");
if (!template.Exists){ //Делаем проверку - если Template.xlsx отсутствует - выходим по красной ветке
project.SendErrorToLog("Упс! Файл Excel-шаблона 'Template.xlsx' отсутствует в директории проекта.", true);
return null;
}
5. Создаём объект нашего Excel-документа на базе Template.xlsx. Отныне весь дальнейший код будем писать внутри данных фигурных скобок.
C#:
using (ExcelPackage exPack = new ExcelPackage(template, true))
{
//Тут будет весь дальнейший код. А именно:
//Работа с 1 листом
//Работа со 2 листом
//Сохранение файла
}
6. Прежде чем начать работу с листами, их нужно определить/получить из шаблона. Сделаем это по их порядковым номерам.
C#:
ExcelWorksheet ws1 = exPack.Workbook.Worksheets[1];
ExcelWorksheet ws2 = exPack.Workbook.Worksheets[2];
7. Далее, нам нужно записать в первый лист данные из первой таблицы проекта. Это можно сделать в двойном цикле, вот так:
C#:
for (int row = startRowT1; row < table1.RowCount+startRowT1; row++){
for (int col = startColT1; col < table1.ColCount+startColT1; col++){
ws1.Cells[row,col].Value = table1.GetCell(col-startColT1, row-startRowT1);
}
}
C#:
for (int row = startRowT1; row < table1.RowCount+startRowT1; row++){
for (int col = startColT1; col < table1.ColCount+startColT1; col++){
//Пробуем распознать тип вставляемых данных - дату, целое число, дробное число
if (DateTime.TryParse(table1.GetCell(col-startColT1, row-startRowT1), out dt)){
//Если распознали, например, дату (тип DateTime) - сразу меняем формат ячейки
ws1.Cells[row,col].Style.Numberformat.Format = "dd.MM.yyyy";
//Вставляем распознанное значение в формате, заданном в предыдущей строчке
ws1.Cells[row,col].Value = dt;
}else if (int.TryParse(table1.GetCell(col-startColT1, row-startRowT1), out i)){
ws1.Cells[row,col].Style.Numberformat.Format = "0";
ws1.Cells[row,col].Value = i;
}else if (double.TryParse(table1.GetCell(col-startColT1, row-startRowT1), out d)){
ws1.Cells[row,col].Style.Numberformat.Format = "0.00";
ws1.Cells[row,col].Value = d;
}else //Если не распознали - записываем в общем формате
ws1.Cells[row,col].Value = table1.GetCell(col-startColT1, row-startRowT1);
}
}
8. Отформатируем полученную табличку в более приглядный вид. Стили таблиц аналогичны тем, которые можно увидеть в Excel, только английскими названиями. «Light1» соответствует «Светлый1», «Medium1» – «Средний1», «Dark1» – «Темный1». Конкретно для первого листа я посчитал подходящим стиль «Светлый19».
C#:
//Определяем диапазон области данных
ExcelRange rangeT1 = ws1.Cells[startRowT1, startColT1, table1.RowCount+startRowT1-1, table1.ColCount+startColT1-1];
//Определяем этот диапазон как таблицу
ExcelTable tableT1 = ws1.Tables.Add(rangeT1, ws1.Name.Replace(" ",String.Empty));
//Задаём стиль таблицы. Стили аналогичны стилям в Excel, только названия на английском
tableT1.TableStyle = TableStyles.Light19;
//Отключаем заголовки и фильтр, в нашем случае они не нужны
tableT1.ShowFilter = false;
tableT1.ShowHeader = false;
9. Переходим ко второму листу. По аналогии вставляем в него данные из второй таблицы.
По уму, конечно, стоит оформлять подобные вещи в метод/процедуру, но у нас сейчас задача показать именно работу с функционалом библиотеки.
Для разнообразия выберем немного иной формат даты.
C#:
for (int row = startRowT2; row < table2.RowCount+startRowT2; row++){
for (int col = startColT2; col < table2.ColCount+startColT2; col++){
if (DateTime.TryParse(table2.GetCell(col-startColT2, row-startRowT2), out dt)){
ws2.Cells[row,col].Style.Numberformat.Format = "d MMM yy";
ws2.Cells[row,col].Value = dt;
}else if (int.TryParse(table2.GetCell(col-startColT2, row-startRowT2), out i)){
ws2.Cells[row,col].Style.Numberformat.Format = "0";
ws2.Cells[row,col].Value = i;
}else if (double.TryParse(table2.GetCell(col-startColT2, row-startRowT2), out d)){
ws2.Cells[row,col].Style.Numberformat.Format = "0.00";
ws2.Cells[row,col].Value = d;
}else
ws2.Cells[row,col].Value = table2.GetCell(col-startColT2, row-startRowT2);
}
}
10. Как вы могли заметить, в нарисованных заголовках второго листа был последний столбец под названием «Всего», и для него я не создал данных для заполнения. Рассмотрим такую ситуацию, что в ячейки этого столбца нужно получить суммы чисел для каждой из строк.
Для этого мы воспользуемся формулами – иными словами, зададим столбцу формулу, как мы это обычно делаем в Excel.
C#:
//Определяем диапазон ячеек, в которой будет работать формула
ExcelRange formulaRange = ws2.Cells[startRowT2,table2.ColCount+startColT2,table2.RowCount+startRowT2-1,table2.ColCount+startColT2];
//Задаём в диапазоне саму формулу. Формулы пишутся как в самом Excel (англ. версии), только без знака "="
formulaRange.Formula = String.Format("SUM(B{0}:I{0})", startRowT2);
formulaRange.Calculate();
11. По аналогии с первым листом делаем форматирование области данных, теперь только уже вместе со столбцом «Всего». Дополнительно для последнего включаем особое форматирование.
C#:
ExcelRange rangeT2 = ws2.Cells[startRowT2, startColT2, table2.RowCount+startRowT2-1, table2.ColCount+startColT2];
ExcelTable tableT2 = ws2.Tables.Add(rangeT2, ws2.Name.Replace(" ",String.Empty));
tableT2.TableStyle = TableStyles.Light16;
tableT2.ShowFilter = false;
tableT2.ShowHeader = false;
tableT2.ShowLastColumn = true; //Для последнего столбца ("Всего") дополнительно включаем особый стиль
12. Сохраняем полученный файл в папку проекта, называем его Result.xlsx.
C#:
Byte[] bin = exPack.GetAsByteArray();
string resPath = project.Directory + @"\Result.xlsx";
File.WriteAllBytes(resPath, bin);
project.SendInfoToLog("Сохранили итоговый Excel-файл по адресу: "+resPath, true);
Вот, собственно, и всё. После выполнения такого сниппета в папке с проектом появится итоговый файл. В тестовом проекте для этой статьи получаем такие таблички.
Данный проект-пример прикрепляю во вложения к посту.
- Номер конкурса статей
- Шестой конкурс статей
- Тема статьи
- Генерация






