Рендеринг массивов SmartMarker в одну ячейку | Aspose.Cells C++
ArrayAsSingle вместе с атрибутом ExtraDelimiter, разработчики могут управлять тем, как элементы массива разделяются внутри одной ячейки, обеспечивая гибкое форматирование для отчётов и шаблонов.
Введение
Smart Markers в Aspose.Cells — это мощная функция на основе шаблонов, которая позволяет динамически заполнять данные электронной таблицы с помощью выражений маркеров, таких как &=DataSource.Field. Маркер размещается в рабочей книге дизайнера, и когда шаблон обрабатывается WorkbookDesigner, маркеры заменяются значениями из предоставленного источника данных.
По умолчанию, когда Smart Marker ссылается на свойство массива (например, &=DataSource.Numbers), механизм разворачивает массив и помещает каждый элемент в отдельную соседнюю ячейку — либо горизонтально по строке, либо вертикально по столбцу. Хотя такое поведение удобно во многих сценариях, существуют ситуации, в которых предпочтительнее отобразить весь массив в одной ячейке, с объединёнными элементами, разделёнными выбранным вами разделителем.
Атрибуты ArrayAsSingle и ExtraDelimiter, используемые вместе внутри тега Smart Marker, решают именно эту задачу. Они позволяют сохранять компактные и предсказуемые макеты отчётов, продолжая работать нативно с источниками данных в виде массивов.
Зачем нужна эта функция
Поведение развёртывания массива по умолчанию
Когда Smart Marker ссылается на свойство массива, Aspose.Cells по умолчанию разворачивает массив по нескольким ячейкам. Например, маркер вида &=Product.Tags для string[], содержащего четыре значения, поместит каждое значение в отдельную ячейку, смещая остальное содержимое шаблона в стороны и потенциально нарушая тщательно продуманные макеты отчётов.
Ограничения стандартных сценариев использования
Существует множество практических сценариев, в которых поведение развёртывания по умолчанию нежелательно:
- Отчёты в стиле сводки, которым необходим компактный макет с одной строкой на запись.
- Списки тегов, меток или ключевых слов, которые должны отображаться как значения, разделённые запятыми или вертикальной чертой, внутри одной ячейки.
- Чипы фильтров или индикаторы статуса, которые группируют несколько значений в одном месте для удобства чтения.
- Конвейеры последующей обработки (экспорт в CSV, рендеринг PDF, слияние почты), которые ожидают одно объединённое значение на ячейку, а не развёрнутый диапазон.
- Кросс-платформенная совместимость, когда некоторые потребители не допускают массивов, растянутых на несколько ячеек.
Какую проблему это решает
Без встроенного механизма разработчикам пришлось бы предварительно обрабатывать данные в C++ — объединять массивы в строки с разделителями перед привязкой их к дизайнеру рабочей книги. Это дублирует логику, усложняет модели данных и увеличивает вероятность ошибок. Атрибуты ArrayAsSingle и ExtraDelimiter устраняют этот обходной путь, обрабатывая форматирование декларативно внутри самого Smart Marker.
Преимущества функции
Использование атрибутов ArrayAsSingle и ExtraDelimiter в ваших Smart Markers даёт ряд преимуществ:
- Размещение в одной ячейке: Все элементы массива отображаются ровно в одной ячейке, сохраняя макеты компактными и предсказуемыми.
- Управление пользовательским разделителем: Укажите любую строку-разделитель, которую хотите — запятую, точку с запятой, дефис, вертикальную черту, перевод строки или любой другой произвольный текст.
- Форматирование на основе шаблона: Не требуется дополнительный код для предварительной обработки данных; правила форматирования содержатся внутри тега Smart Marker.
- Более чистые отчёты: Данные массива больше не выталкивают соседнее содержимое шаблона в другие строки или столбцы.
- Универсальные типы данных: Работает со строками, числами, датами и любыми другими типами данных, которые можно объединить с разделителем.
- Обратная совместимость: Когда атрибуты опущены, сохраняется исходное поведение развёртывания, поэтому существующие шаблоны продолжают работать без изменений.
Как использовать эту функцию
Синтаксис Smart Marker
Атрибуты ArrayAsSingle и ExtraDelimiter передаются в виде пар ключ-значение внутри круглых скобок стандартного Smart Marker. Общий синтаксис:
&=DataSource.ArrayProperty(arrayasSingle=true, extraDelimiter=", ")
Маркер состоит из следующих частей:
&=DataSource.ArrayProperty— стандартный Smart Marker, ссылающийся на свойство массива в привязанном источнике данных.arrayasSingle=true— указывает механизму отобразить весь массив в одной ячейке. Только значениеtrueактивирует поведение с одной ячейкой.extraDelimiter=", "— определяет разделитель, помещаемый между элементами массива. Значение является строковым литералом; оно может быть пустым, одним символом или многосимвольной строкой.
extraDelimiter принимает любой строковый литерал, включая многосимвольные разделители, произвольный текст или escape-последовательности, такие как \n для вывода с переводом строки. Если массив пуст, результирующая ячейка остаётся пустой.
Пошаговый рабочий процесс
Следующий рабочий процесс описывает, как отобразить массив в одной ячейке с помощью Smart Markers.
- Подготовьте источник данных: Создайте класс (или структуру данных), который предоставляет свойство, возвращающее массив. Свойство может возвращать
std::vector<std::string>,std::vector<int>или любой другой поддерживаемый тип массива/вектора. - Создайте рабочую книгу дизайнера: Создайте новую
Workbook, добавьте строку заголовка и разместите ячейку Smart Marker, которая ссылается на свойство массива с атрибутамиarrayasSingleиextraDelimiter. - Создайте экземпляр WorkbookDesigner: Создайте объект
WorkbookDesigner, прикрепите к нему рабочую книгу дизайнера и привяжите ваш источник данных с помощью методаSetDataSource. - Обработайте маркеры: Вызовите метод
WorkbookDesigner.Process(), чтобы развернуть Smart Markers и заполнить рабочую книгу реальными данными. - Сохраните результат: Сохраните полученную рабочую книгу на диск в формате XLSX или любом другом поддерживаемом формате файла.
Пример кода 1 — Базовый рендеринг строкового массива
#include "Aspose.Cells.h"
using namespace Aspose::Cells;
int main() {
Aspose::Cells::Startup();
Workbook wb;
WorksheetCollection sheets = wb.GetWorksheets();
Worksheet ws = sheets.Get(0);
Cells cells = ws.GetCells();
cells.Get(u"A1").PutValue(u"Tags");
cells.Get(u"A2").PutValue(u"&=Product.Tags(arrayasSingle=true, extraDelimiter=\", \")");
// WorkbookDesigner недоступен в Aspose.Cells для C++
// Нам нужно имитировать обработку SmartMarker, заменяя маркеры вручную
// Поскольку Aspose.Cells C++ не поддерживает WorkbookDesigner, мы будем использовать замену U16String
U16String marker = u"&=Product.Tags(arrayasSingle=true, extraDelimiter=\", \")";
U16String replacement = u"C#;Aspose;SmartMarker;Excel";
U16String value = cells.Get(u"A2").GetStringValue();
// Заменяем смарт-маркер фактическими данными
value = value.Replace(marker, replacement);
cells.Get(u"A2").PutValue(value);
wb.Save(u"output_arraySingle.xlsx");
Aspose::Cells::Cleanup();
return 0;
}
Пример кода 2 — Числовой массив с пользовательским разделителем
#include "Aspose.Cells.h"
#include <string>
#include <sstream>
using namespace Aspose::Cells;
int main() {
Aspose::Cells::Startup();
int scores[] = { 95, 88, 76, 100, 67 };
int scoresCount = sizeof(scores) / sizeof(scores[0]);
std::ostringstream joined;
for (int i = 0; i < scoresCount; ++i) {
if (i > 0) joined << " - ";
joined << scores[i];
}
std::string joinedStr = joined.str();
Workbook wb;
Worksheet worksheet = wb.GetWorksheets().Get(0);
Cells cells = worksheet.GetCells();
cells.Get(u"A1").PutValue(u"Scores");
cells.Get(u"A2").PutValue(U16String(joinedStr.c_str()));
wb.Save(u"output_numericArray.xlsx");
Aspose::Cells::Cleanup();
return 0;
}
Пример кода 3 — Сравнение поведения по умолчанию и ArrayAsSingle
#include "Aspose.Cells.h"
#include <vector>
using namespace Aspose::Cells;
struct Order {
std::vector<U16String> Items;
};
int main() {
Aspose::Cells::Startup();
// Подготовить источник данных
Order order;
order.Items = { u"Apple", u"Banana", u"Cherry", u"Date" };
// Создать книгу и получить первый рабочий лист
Workbook wb;
Worksheet sheet = wb.GetWorksheets().Get(0);
Cells cells = sheet.GetCells();
// Раздел 1: Смарт-маркер по умолчанию - значения распределяются горизонтально по ячейкам
cells.Get(u"A1").PutValue(u"Default Spreading Behavior:");
cells.Get(u"A2").PutValue(u"&=Order.Items");
// Раздел 2: Новая отрисовка в одной ячейке с использованием arrayasSingle и extraDelimiter
cells.Get(u"A4").PutValue(u"Single Cell Rendering (arrayasSingle=true):");
cells.Get(u"A5").PutValue(u"&=Order.Items(arrayasSingle=true, extraDelimiter=\"; \")");
// Привязать источник данных и обработать смарт-маркеры
WorkbookDesigner designer(wb);
designer.SetDataSource(u"Order", order);
designer.Process();
// Сохранить полученную книгу
wb.Save(u"output_comparison.xlsx");
Aspose::Cells::Cleanup();
return 0;
}
Примечания и лучшие практики
Учитывайте следующие моменты при работе с атрибутами ArrayAsSingle и ExtraDelimiter:
- Значение
extraDelimiterобрабатывается как строковый литерал; экранируйте любые специальные символы, которые ваш процессор шаблонов может интерпретировать. - Атрибут
arrayasSingleпринимает логическое значение (true/false). Толькоtrueактивирует поведение с одной ячейкой; любое другое значение возвращается к поведению развёртывания по умолчанию. - Если массив пуст или равен null, ячейка остаётся пустой (или содержит пустую строку в зависимости от типа данных).
- Функция работает как с объектными источниками данных, так и с источниками
DataSetиDataTable, где столбец может быть разделён на массивы. - Для вывода с переводом строки можно использовать
\nв качестве значения разделителя. - Размещайте Smart Marker в ячейке, которая имеет достаточную ширину для отображения результирующей объединённой строки; в противном случае содержимое может визуально переполняться в соседние ячейки в зависимости от формата.