Генерация красивых Excel-отчётов по шаблону

ParadoxRU

Client
Регистрация
04.09.2019
Сообщения
19
Благодарностей
6
Баллы
3

ZSHab

Client
Регистрация
29.10.2014
Сообщения
220
Благодарностей
22
Баллы
18
LaGir, Спасибо за статью!
Может сталкивался кто-нибудь с похожей задачей?
Коротко: "Нужно сделать добавление данные в таблицы с ожиданием окончания записи"

Есть файл "Тест.xlsx"
Записываю в него данные. (больше 5 разных ячеек)
Следующим действием идёт отправка файла POST запросом.
Часто, так как отправка файла идёт сразу после действий по "записи данных", то файл отправляется без фактически записанных данных и после этого данные записываются на локальном файле. (а POST запросом отправился недописанный файл).

Как сделать ожидание записи всех данных в файл?

Заранее спасибо за помощь!
 

Phoenix78

Client
Read only
Регистрация
06.11.2018
Сообщения
11 789
Благодарностей
5 727
Баллы
113
LaGir, Спасибо за статью!
Может сталкивался кто-нибудь с похожей задачей?
Коротко: "Нужно сделать добавление данные в таблицы с ожиданием окончания записи"

Есть файл "Тест.xlsx"
Записываю в него данные. (больше 5 разных ячеек)
Следующим действием идёт отправка файла POST запросом.
Часто, так как отправка файла идёт сразу после действий по "записи данных", то файл отправляется без фактически записанных данных и после этого данные записываются на локальном файле. (а POST запросом отправился недописанный файл).

Как сделать ожидание записи всех данных в файл?

Заранее спасибо за помощь!
паузу поставь 60-90 секунд, должно хватить.
 
  • Спасибо
Реакции: ZSHab

ZSHab

Client
Регистрация
29.10.2014
Сообщения
220
Благодарностей
22
Баллы
18
паузу поставь 60-90 секунд, должно хватить.
Спасибо,
Phoenix78
Сделал дополнительную таблицу, которую "привязывал к файлу" и проверял фактическую запись данных в локальный файл.
По тестам, хватало до 30 - 40 секунд для записи.
 

nik-n

Client
Регистрация
05.11.2016
Сообщения
246
Благодарностей
21
Баллы
18
Компиляция кода Ошибка в действии "CS0246" "The type or namespace name 'ExcelPackage' could not be found (are you missing a using directive or an assembly reference?)". [Строка: 34; Cтолбец: 8]

Компиляция кода Ошибка в действии "CS0246" "The type or namespace name 'ExcelPackage' could not be found (are you missing a using directive or an assembly reference?)". [Строка: 34; Cтолбец: 34]

Компиляция кода Ошибка в действии "CS0246" "The type or namespace name 'ExcelWorksheet' could not be found (are you missing a using directive or an assembly reference?)". [Строка: 37; Cтолбец: 2]

либа с гитхаба(тоже самое и с другими с других мест в том числе тут в теме на 1 странице кто то прикреплял dll готовый), не пойму че надо
Зенно Постерович v 7.4.0.0
 

Вложения

ZSharp

Client
Регистрация
29.09.2013
Сообщения
400
Благодарностей
129
Баллы
43
либа с гитхаба(тоже самое и с другими с других мест в том числе тут в теме на 1 странице кто то прикреплял dll готовый), не пойму че надо
Зенно Постерович v 7.4.0.0
Добавлена библиотека в "Ссылки из GAS"?
И прописаны using-и в "Директивы using и общий код"?
 

nik-n

Client
Регистрация
05.11.2016
Сообщения
246
Благодарностей
21
Баллы
18
Добавлена библиотека в "Ссылки из GAS"?
И прописаны using-и в "Директивы using и общий код"?
конечно

79991


79992


и сам dll в папку ExternalAssemblies тоже добавлен

не работает ни в моем шаблоне ни в шаблоне который в стартовом посте автор прикрепил. одна и та же ошибка.
 

braind

Client
Регистрация
10.10.2012
Сообщения
119
Благодарностей
12
Баллы
18
Ребят помогите человеку, не разбирающемуся в C#)

У меня основная задача - писать данные в нужном формате. Всякие красивости не нужны.
Я в цикле готовлю данные и потом пишу в таблицу сразу всю строку, например
{-Variable.date-}{-String.Tab-}{-Variable.var1-}{-String.Tab-}{-Variable.var2-}
в строке разные данные - и дата и простые числа и double

Подскажите как адаптировать код, чтобы записывать данные в нужном формате. Формат парсить не нужно, я могу указать в явном виде, структура таблицы не меняется.
 

radv

Client
Регистрация
11.05.2015
Сообщения
3 855
Благодарностей
2 087
Баллы
113
Я в цикле готовлю данные и потом пишу в таблицу сразу всю строку, например
{-Variable.date-}{-String.Tab-}{-Variable.var1-}{-String.Tab-}{-Variable.var2-}
в строке разные данные - и дата и простые числа и double
если ты работаешь с одним листом, так может тебе просто использовать CSV файл, тогда через разделитель формируешь строку и записываешь, как в обычный текстовый файл.
А при просмотре CSV файл можно открывать как таблицу указав разделитель при открытии файла. :az:
 

braind

Client
Регистрация
10.10.2012
Сообщения
119
Благодарностей
12
Баллы
18
если ты работаешь с одним листом, так может тебе просто использовать CSV файл, тогда через разделитель формируешь строку и записываешь, как в обычный текстовый файл.
А при просмотре CSV файл можно открывать как таблицу указав разделитель при открытии файла. :az:
Да у меня в этом же файле сводная хранится, данные постоянно прибавляются, в сводной анализирую. Если писать в CSV, то нужно будет пересохранять в xls, лишние действия.
 

braind

Client
Регистрация
10.10.2012
Сообщения
119
Благодарностей
12
Баллы
18
Ребят помогите человеку, не разбирающемуся в C#)

У меня основная задача - писать данные в нужном формате. Всякие красивости не нужны.
Я в цикле готовлю данные и потом пишу в таблицу сразу всю строку, например
{-Variable.date-}{-String.Tab-}{-Variable.var1-}{-String.Tab-}{-Variable.var2-}
в строке разные данные - и дата и простые числа и double

Подскажите как адаптировать код, чтобы записывать данные в нужном формате. Формат парсить не нужно, я могу указать в явном виде, структура таблицы не меняется.
Никто помочь не желает?)
 

radv

Client
Регистрация
11.05.2015
Сообщения
3 855
Благодарностей
2 087
Баллы
113

che100

Client
Регистрация
18.04.2017
Сообщения
808
Благодарностей
505
Баллы
93
  • Спасибо
Реакции: ZSHab

stanar

Client
Регистрация
19.12.2015
Сообщения
315
Благодарностей
157
Баллы
43
Доброго дня. Подскажите, как в коде реализовать аналог нажатия этой вот кнопки?
93869
 

Phoenix78

Client
Read only
Регистрация
06.11.2018
Сообщения
11 789
Благодарностей
5 727
Баллы
113

djaga

Administrator
Команда форума
Регистрация
26.04.2020
Сообщения
562
Благодарностей
1 145
Баллы
93
Доброго дня. Подскажите, как в коде реализовать аналог нажатия этой вот кнопки?
Посмотреть вложение 93869
Насколько я помню, запуск макросов VBA с помощью C# (EPPlus) не возможен.
Можно только записывать, удалять и изменять. исток

Как вариант вы можете воспользоваться вот этим кодом, чтобы при открытии книги было автоматическое обновление всех связей. исток
Вот так можно записать макрос в таблицу. (пример внутри)
Обновление всех связей при открытии книги:
'Язык VBA (форум не поддерживает этот язык)

Private Sub Workbook_Open()
'Используйте метод RefreshAll
Workbooks(ThisWorkbook.Name).RefreshAll
End Sub
upd:
Как вариант можно попробовать ещё так, но это не во всех случаях подходит:
Перезагрузка таблицы:
project.Tables["BookName"].Reload();
Плюс не описан в zenno addemblies. =/
Очень надеюсь, что помог. :az:
 
Последнее редактирование:
  • Спасибо
Реакции: stanar

stanar

Client
Регистрация
19.12.2015
Сообщения
315
Благодарностей
157
Баллы
43
Насколько я помню, запуск макросов VBA с помощью C# (EPPlus) не возможен.
Можно только записывать, удалять и изменять. исток

Как вариант вы можете воспользоваться вот этим кодом, чтобы при открытии книги было автоматическое обновление всех связей. исток
Вот так можно записать макрос в таблицу. (пример внутри)
Обновление всех связей при открытии книги:
'Язык VBA (форум не поддерживает этот язык)

Private Sub Workbook_Open()
'Используйте метод RefreshAll
Workbooks(ThisWorkbook.Name).RefreshAll
End Sub
upd:
Как вариант можно попробовать ещё так, но это не во всех случаях подходит:
Перезагрузка таблицы:
project.Tables["BookName"].Reload();
Плюс не описан в zenno addemblies. =/
Очень надеюсь, что помог. :az:

Спасибо. Пользуюсь вот этим, но тяжелые запросы не всегда обновляет. Может времени не хватает, конечно. Думал в этой библиотеке есть что-то похожее
var path = project.Variables["path"].Value;
Microsoft.Office.Interop.Excel.Application excelApp = new Microsoft.Office.Interop.Excel.Application();
excelApp.DisplayAlerts = false;
Workbook theWorkbook = excelApp.Workbooks._Open(path, 0, false, 5, System.Reflection.Missing.Value, System.Reflection.Missing.Value, false, System.Reflection.Missing.Value, System.Reflection.Missing.Value, true, false, System.Reflection.Missing.Value, false);
theWorkbook.RefreshAll();
 

Surok

Client
Регистрация
09.10.2018
Сообщения
23
Благодарностей
9
Баллы
3
Второй кубик из примера не запускается, выдает ошибку: "
Выполнение действия CSharp OwnCode: Генерация Excel. [Строка: 162; Cтолбец: 0] Не удалось загрузить файл или сборку "EPPlus, Version=4.1.0.0, Culture=neutral, PublicKeyToken=ea159fdaa78159a1" либо одну из их зависимостей. Найденное определение манифеста сборки не соответствует ссылке на сборку. (Исключение из HRESULT: 0x80131040)"

Как-то можно победить или библиотека устарела?
 

radv

Client
Регистрация
11.05.2015
Сообщения
3 855
Благодарностей
2 087
Баллы
113
Второй кубик из примера не запускается, выдает ошибку: "
Выполнение действия CSharp OwnCode: Генерация Excel. [Строка: 162; Cтолбец: 0] Не удалось загрузить файл или сборку "EPPlus, Version=4.1.0.0, Culture=neutral, PublicKeyToken=ea159fdaa78159a1" либо одну из их зависимостей. Найденное определение манифеста сборки не соответствует ссылке на сборку. (Исключение из HRESULT: 0x80131040)"

Как-то можно победить или библиотека устарела?
ругается на версию библиотеки. попробуйте другую версию. Новые версии могут выдавать ошибки
 

Surok

Client
Регистрация
09.10.2018
Сообщения
23
Благодарностей
9
Баллы
3
ругается на версию библиотеки. попробуйте другую версию. Новые версии могут выдавать ошибки
Пробовал все, что нашел на форуме.

Проблема с версией так решается: https://zennolab.com/discussion/threads/ne-sozdaetsja-excel-tablica.104712/#post-702775
Но там другая, пока не понимаю, как решить.
 

Duser

Client
Регистрация
11.08.2013
Сообщения
320
Благодарностей
217
Баллы
43
Часто получается, что строка, которая заносится в ячейку, длинная. Как в самом экселе сделать, так чтобы данные не вылазили за границу ячейки?
 

che100

Client
Регистрация
18.04.2017
Сообщения
808
Благодарностей
505
Баллы
93
Часто получается, что строка, которая заносится в ячейку, длинная. Как в самом экселе сделать, так чтобы данные не вылазили за границу ячейки?
shrink - ануть.
 
  • Спасибо
Реакции: Duser

lazy_bones

Client
Регистрация
16.10.2010
Сообщения
4
Благодарностей
0
Баллы
1
101028


Здравствуйте, подскажите пожалуйста, есть ли способ как то ускорить заполнение? В данном варианте отчет, примерно 60 тыс строк. Из приведенного сниппета убран второй лист и убрано распознавание дат, оставлено только распознавание целого и дробного числа. Отчет забирается по апишке, сам зеннопостер парсит его в таблицу примерно за 5 минут. И больше 4х часов происходит заполнение именно сниппетом. Причем эту же самую таблицу в 10 тыс строк, сниппет заполняет примерно за 10 минут.
 

Redsmokky

Client
Регистрация
06.10.2015
Сообщения
318
Благодарностей
196
Баллы
43
Подскажите как закрасить 1 ячейку, в шаблоне все через условия, не разобрался :D
 

lx2003

Client
Регистрация
15.02.2021
Сообщения
742
Благодарностей
150
Баллы
43
Приветствую всех!

Наверняка многие из вас создавали шаблоны-парсеры. И, как правило, результаты в этом случае на выходе помещали в Excel-таблицы. Функционала ZennoPoster хватает для осуществления этих задач, за исключением несколько нюансов. Например, отсутствуют возможности для стилизации выходных таблиц, работать можно исключительно с первым листом, записывать данные можно только в строковом формате. Нет прочих различных плюшек, доступных в Excel.

Согласитесь, куда приятнее, когда на выходе получаешь вторую табличку, а не первую (см. скриншоты ниже). А если делаем парсер на заказ, а не для своих личных целей – и говорить нечего. Именно об этом и пойдёт речь в статье – как максимально просто получить красивый Excel-отчёт в ZennoPoster, с нуля до конкретного результата.

Посмотреть вложение 17266 Посмотреть вложение 17267

Давайте рассмотрим возможные способы реализации.

Недавно, с версии 5.10.0.0, со стороны ZennoPoster лёд чуть-чуть тронулся – появились методы для редактирования стилей ячеек через C#-сниппеты. Однако, пока сложно сказать, что это хотя бы отчасти решило проблему. Возможности самые базовые, опять же только стили, и в любом случае их надо задавать через код – для тех, кто использует чисто кубики, по сути ничего не изменилось.

Поэтому, данный способ нам не совсем подходит. Что же делать?

Думаю, многим из вас известен альтернативный метод – использование сторонней dll-библиотеки, с помощью которой можно воплотить большую часть возможностей Excel. Однако, есть одна существенная проблема – всё оформление таблиц опять же надо писать через C#-код, и даже для той сравнительно простой желанной таблички с картинки выше – его нужно написать достаточно много. Ну и конечно, для этого надо уметь в нём неплохо разбираться. На форуме, кстати, есть статья об использовании такой библиотеки, но, к сожалению, там опять же описаны только самые азы применения стилей и форматирования – те же, которые появились в ZP v5.10.

Тем не менее, мы остановимся именно на этом способе – так как у библиотеки, которую мы будем использовать (а именно известный и могучий EPPlus), есть одна шикарная фича – создание таблиц по шаблону.

Что это значит? То, что мы можем создать xlsx-файл, нарисовать в нём вручную в Excel всё оформление – а в ZennoPoster использовать его как шаблон стилей для результирующего файла. Всё, что нам останется – вставить в область данных результаты парсинга.

Посмотреть вложение 17268

Без кода тут, конечно, всё равно не обойтись, но его совсем немного. Главное и самое сложное - оформление - мы делаем руками в Excel, соответственно - нам не потребуются программерские способности и не придётся убить кучу времени на копание в документации библиотеки.

Вводную часть закончили, приступим к делу.


Подготовка шаблона оформления

Собственно, рисуем в Excel заголовки и их стили, выравниваем всё, добавляем другие вещи по желанию (например, строку фильтра).

Так как стандартными средствами ZennoPoster можно работать только с первым листом Excel-файла (тоже порой весьма неприятное ограничение), рассмотрим пример с заполнением 2 листов.

Для примера нарисовал такие таблички. Также сразу добавил фильтры, закрепил области заголовков, кое-где добавил примечания. Над тематикой содержимого особо не заморачивался и взял первое что пришло в голову, соответственно, по этому поводу просьба не пинаться – всё это чисто для примера. :-)
Посмотреть вложение 17269 Посмотреть вложение 17270

Сохраняем файл в папке с проектом, я назвал его Template.xlsx.


Подключение библиотеки

Теперь нам нужно подключить к нашему проекту саму библиотеку EPPlus.
Наверняка многие умеют подключать dll-библиотеки, но на всякий случай разберём под спойлером по шагам.
1. Скачиваем библиотеку с её официальной странички, http://epplus.codeplex.com/.
Посмотреть вложение 17271

2. Находим в архиве нужный файл EPPlus.dll, кидаем в папку ExternalAssemblies в директории с установленным ZennoPoster.
Посмотреть вложение 17272
Посмотреть вложение 17273

3. Открываем наш шаблон, добавляем блоки «Ссылки из GAC» и «Директивы using»
Посмотреть вложение 17274

4. Заходим в «Ссылки из GAC» и добавляем библиотеку.
Посмотреть вложение 17275

5. Заходим в «Директивы using» и вписываем туда директивы со скриншота.
Посмотреть вложение 17276


Сниппет создания 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);
  }
}
…но мы этого делать не будем, так как в этом случае все данные запишутся в обычном строковом формате (все данные стандартных таблиц Zenno хранятся как строки). Библиотека позволяет нам записывать в Excel-файл данные именно тех типов, которые нам нужны, и мы этим воспользуемся.
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();
Библиотека поддерживает большинство других формул Excel, единственное, рекомендуется их писать в английском варианте и без знака «=».

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);
Вот, собственно, и всё. После выполнения такого сниппета в папке с проектом появится итоговый файл. В тестовом проекте для этой статьи получаем такие таблички.

Посмотреть вложение 17278
Посмотреть вложение 17279

Данный проект-пример прикрепляю во вложения к посту.
Здравствуйте!
Есть в Эксель обединение смежных строк, смежных столбцов. Но Зеннопостер предпочитает сохранять в формате csv даже если в формате xls. Как бы сохранять csv или xls с указанием на объединенные строки или объединенные столбцы?

Пробовал прописывать параметрыдля строк и столбцов (row=3;col=3). Примерно так.
Какой есть способ, чтобы дополнительно не прописывать такое?


Как-то может использовать открый формат подобие xls, а потом пересохранить в xls?
 
Последнее редактирование:

LaGir

Client
Регистрация
01.10.2015
Сообщения
238
Благодарностей
972
Баллы
93
Здравствуйте!
Есть в Эксель обединение смежных строк, смежных столбцов. Но Зеннопостер предпочитает сохранять в формате csv даже если в формате xls. Как бы сохранять csv или xls с указанием на объединенные строки или объединенные столбцы?

Пробовал прописывать параметрыдля строк и столбцов (row=3;col=3). Примерно так.
Какой есть способ, чтобы дополнительно не прописывать такое?


Как-то может использовать открый формат подобие xls, а потом пересохранить в xls?
Приветствую!
Честно говоря пока не очень понял, какие и с какой целью объединять столбцы/строки. Не могли бы привести конкретный пример, по типу "вот такую-то таблицу имеем, а надо получить вот такую-то" (т.е. примеры файлов с абсолютно любыми тестовыми данными).

А в общих чертах - если нужно объединение ячеек ровно как в Excel, то действительно придётся делать через внешние dll, по типу как в этой статье. Если же по известному принципу нужно объединить целиком какие-то определённые строки или столбцы - лучше делать встроенным функционалом Zenno, формат файла как правило тут не должен создавать проблем.
 
  • Спасибо
Реакции: djaga

lx2003

Client
Регистрация
15.02.2021
Сообщения
742
Благодарностей
150
Баллы
43
Приветствую!
Честно говоря пока не очень понял, какие и с какой целью объединять столбцы/строки. Не могли бы привести конкретный пример, по типу "вот такую-то таблицу имеем, а надо получить вот такую-то" (т.е. примеры файлов с абсолютно любыми тестовыми данными).

А в общих чертах - если нужно объединение ячеек ровно как в Excel, то действительно придётся делать через внешние dll, по типу как в этой статье. Если же по известному принципу нужно объединить целиком какие-то определённые строки или столбцы - лучше делать встроенным функционалом Zenno, формат файла как правило тут не должен создавать проблем.
Название публикации - Красивые отчеты в Эксель. Как красивые отчеты могут быть без объединения столбцов или строк. Пример простейший из Эксель вот такой - без ввода данных каких-либо.
 

Вложения

LaGir

Client
Регистрация
01.10.2015
Сообщения
238
Благодарностей
972
Баллы
93
Название публикации - Красивые отчеты в Эксель. Как красивые отчеты могут быть без объединения столбцов или строк. Пример простейший из Эксель вот такой - без ввода данных каких-либо.
В этом случае да, надо использовать стороннюю dll. Если говорить о той, которая используется в этой статье, то примерно так должно работать, если брать в пример ваш скриншот:
C#:
// Так
ws1.Cells["B2:C2"].Merge = true;
ws1.Cells["E4:E9"].Merge = true;

// Или так
ws1.Cells[2, 2, 2, 3].Merge = true;
ws1.Cells[4, 5, 9, 5].Merge = true;
 
  • Спасибо
Реакции: lx2003

lx2003

Client
Регистрация
15.02.2021
Сообщения
742
Благодарностей
150
Баллы
43
В этом случае да, надо использовать стороннюю dll. Если говорить о той, которая используется в этой статье, то примерно так должно работать, если брать в пример ваш скриншот:
C#:
// Так
ws1.Cells["B2:C2"].Merge = true;
ws1.Cells["E4:E9"].Merge = true;

// Или так
ws1.Cells[2, 2, 2, 3].Merge = true;
ws1.Cells[4, 5, 9, 5].Merge = true;
Очень здорово, что есть такое решение! Спасибо!
 
  • Спасибо
Реакции: LaGir

lx2003

Client
Регистрация
15.02.2021
Сообщения
742
Благодарностей
150
Баллы
43
В этом случае да, надо использовать стороннюю dll. Если говорить о той, которая используется в этой статье, то примерно так должно работать, если брать в пример ваш скриншот:
C#:
// Так
ws1.Cells["B2:C2"].Merge = true;
ws1.Cells["E4:E9"].Merge = true;

// Или так
ws1.Cells[2, 2, 2, 3].Merge = true;
ws1.Cells[4, 5, 9, 5].Merge = true;
А как это перенести в файл потом? В этом суть вопроса. Через эту же библиотеку?
 

Кто просматривает тему: (Всего: 1, Пользователи: 0, Гости: 1)