Отчет MATLAB Report Generator генерации API поддерживает создание искателей, которые ищут контейнеры данных для заданных объектов и возвращают результаты в отчетной форме. Поиск позволяет вам отделить логику поиска от логики отчета в генераторах отчетов. Искатели также способствуют повторному использованию логики поиска, тем самым ускоряя разработку генераторов отчетов. В этом примере показано, как разработать и использовать средство поиска для создания отчета.
Создание искателя влечет за собой создание класса MATLAB, который определяет свойства и поведение искателя. В следующих разделах описываются шаги, необходимые для создания класса finder. В объяснении используется класс с именем GrantFinder as an example
. Код для класса находится в файле, GrantFinder.m
, который сопровождает этот скрипт. The GrantFinder
класс определяет поисковик, способный находить и форматировать гранты, присуждаемые Национальным гуманитарным фондом США (NEH).
Создайте файл определения класса скелета
Используйте РЕДАКТОРА MATLAB (не Live Editor), чтобы создать определение класса скелета для поиска, для примера
Задайте базовый класс Finder
Укажите API- mlreportgen.finder.Finder
отчета класс как базовый класс для вашего поисковика.
Этот базовый класс определяет свойства, общие для поисковиков, включая
Container
: свойство, используемое для ссылки на контейнер, который будет проверяться поисковиком. Для примера, GrantFinder
используйте это свойство для хранения ссылки на созданную базу данных предоставления.
Properties
: свойство, используемое клиентами поиска для задания значений свойств, которые объект должен удовлетворять поиску. Для примера это свойство позволяет клиенту GrantFinder задать свойства гранта, которые должны быть возвращены в результате поиска базы данных грантов NEH.
The mlreportgen.finder.Finder
класс задает другие свойства и методы, которые должно задать определение класса finder. Это гарантирует, что ваш поисковик работает с API Report.
Определите конструктор Finder
Задайте функцию, которая создает образец вашего искателя, например,
The GrantFinder
конструктор использует xmlread
MATLAB функция для чтения XML- файл с диска и преобразования его в документ Java DOM. Затем документ DOM передается в
mlreportgen.finder.Finder
конструктор, который устанавливает документ Java DOM как значение Container
искателя свойство. Хранение базы данных NEH в качестве документа Java DOM позволяет поисковику использовать стороннее программное обеспечение Java для поиска основы данных. Для получения дополнительной информации см. Xerces Java DOM API.
Конструктор также вызывает reset
функция, которая инициализирует переменные, используемые для поиска в базе данных предоставления. Класс GrantFinder задает эту функцию. Точно так же ваш класс должен задать функцию сброса. The reset
функция гарантирует, что клиент может использовать ваш поиск для проведения нескольких поисков своего контейнера. Для получения дополнительной информации см. раздел «Определение функции сброса».
Задайте find
Метод
Задайте метод для поиска в контейнере поиска объектов, которые соответствуют пользовательским ограничениям. Метод поиска должен вернуть массив объектов результата, которые содержат объекты, которые он находит. Объекты результата являются объектами базового типа mlreportgen.finder.Result
. Возврат результатов поиска как объектов результата позволяет пользователю поиска добавить результаты к главе отчета или отчета. Для получения дополнительной информации см. раздел «Определение результата поиска». Возврат результатов поиска в виде массива MATLAB позволяет вам использовать цикл for для обработки результатов поиска, например,
The GrantFinder
<reservedrangesplaceholder0>
метод иллюстрирует определение find
способ.
Этот метод поиска использует getNodeList
, служебную функцию поиска, которую GrantFinder
Класс задает (см. «Определение метода Утилиты поиска»), чтобы найти в базе данных грантов, которые соответствуют ограничениям по значениям свойств, заданным поисковиком Properties
свойство. The getNodeList
функция устанавливает внутреннее свойство с именем NodeList
к результату своего поиска. Результатом является Java DOM NodeList
объект (NodeList
), который содержит результаты поиска как список элементов Java DOM (Element
).
The find
затем метод преобразует этот список узлов в массив результирующих объектов типа GrantResult
. Он использует GrantResult
конструктор, чтобы создать объект результата предоставления из Java DOM Element
объект, который содержит данные предоставления.
Определите hasNext
и next
Методы
Ваше определение класса finder должно определять hasNext
и next
методы. По своему первому призыву, ваш hasNext
метод должен создать очередь результатов поиска и вернуть true, если очередь не пуста. При последующих вызовах hasNext
метод должен вернуться true
если очередь пуста, false
в противном случае. Ваши next
метод должен вернуть первый результат в очереди по первому вызову, следующий результат, по следующему вызову и так далее, пока очередь не будет пустой.
Эти методы предназначены для того, чтобы позволить клиенту вашего искателя использовать MATLAB while
цикл для поиска контейнера вашего поисковика, например,
The GrantFinder
класс иллюстрирует hasNext
способ.
Этот метод сначала проверяет, создал ли он очередь поиска, как указано IsIterating
поисковика свойство. Если очередь уже существует и не пуста, этот метод возвращается
true
. если очередь существует и пуста, этот метод возвращается false
. Если очередь еще не существует (т.е. это первый вызов метода), hasNext
метод создает очередь результатов следующим образом. Во-первых, он использует свои внутренние getNodeList
метод получения грантов, удовлетворяющих критериям поиска, заданным в Properties
поисковика свойство. The
getNodeList
метод устанавливает свойство внутреннего поиска с именем NodeCount
к количеству найденных результатов. Если NodeCount
больше нуля, hasNext
метод устанавливает внутреннее свойство с именем NextNodeIndex
по 1. Поисковик next
метод использует это свойство, чтобы сохранить состояние очереди поиска, то есть следующего элемента в очереди. Наконец, если очередь изначально не пуста, поисковик возвращается true
; в противном случае false
.
The GrantFinder
<reservedrangesplaceholder0>
метод действует с очередью, созданной hasNext
способ.
Задайте метод Утилита
Твоя искательница find
и hasNext
методы должны искать в контейнере поиска объекты, которые удовлетворяют ограничениям поиска. Следует рассмотреть возможность определения поисковой утилиты, которую могут использовать оба метода. Для примера, GrantFinder
hasNext
и next
оба метода делегируют поиск внутренней утилите с именем getNodeList
. The getNodeList
метод в свою очередь делегирует поиск в API поиска XML-документов с именем XPath
(см. Руководство).
Создайте InvalidPropertyNames
Свойство
Ваш поисковик должен задать свойство с именем InvalidPropertyNames
задает свойства объекта, которые нельзя использовать для ограничения поиска. The mlreportgen.finder.Finder
базовый класс использует это свойство, чтобы проверить, что заданные пользователем свойства поиска, заданные в Properties
искателя свойство допустимо. Если нет, базовый класс выдает ошибку. Другими словами, если клиент устанавливает
Properties
вашего поисковика свойство к недопустимым свойствам, базовый класс выдает ошибку. Таким образом, базовый поисковик Report API обрабатывает проверку валидности свойств для вашего поисковика.
Если ваш искатель может использовать любое свойство объекта поиска в качестве ограничения поиска, он должен задать InvalidPropertyNames
свойство пусто. Для примера, GrantFinder
может обрабатывать любое свойство предоставления. Поэтому это свойство остается пустым:
Задайте reset
Метод
Искатель должен иметь возможность поддерживать несколько поисков, чтобы избежать необходимости создавать поиск для каждого поиска. По этой причине класс base finder Report API заставляет ваш класс finder определять reset
метод, который сбрасывает переменные, используемые логикой поиска вашего поисковика, например,
Если подходящее определение не существует, необходимо создать класс для определения объектов результатов, возвращаемых поиском. В этом разделе показано, как задать объект результата поиска. В нем используется класс с именем GrantResult
в качестве примера. The GrantResult
класс определяет результаты, возвращенные GrantFinder
класс, используемый в качестве примера в разделе Define a Finder. The GrantResult.m
файл, который сопровождает этот скрипт, содержит код для GrantResult
класс. Определение результата поиска влечет за собой следующие задачи.
Задайте базовый класс результатов
Определите mlreportgen.finder.Result
как базовый класс для вашего класса результатов, например,
Определите Object
Свойство
Задайте свойство с именем Object
клиенты вашего объекта результата могут использовать для доступа к найденному объекту, который содержит ваш объект результата. Задайте protected
как SetAccess
значение Object
вашего поисковика свойство. Это гарантирует, что только ваш результат может задать найденный объект, который он содержит.
Ваш конструктор результатов должен задать найденный объект как значение его Object
свойство. Ваш конструктор результатов может использовать конструктор базового класса для выполнения этой задачи, например,
Показать свойства найденного объекта
Ваш результат Object
свойство позволяет клиенту получить доступ к найденному объекту и, следовательно, его свойствам. Однако для доступа к свойствам может потребоваться дополнительный код или специализированные знания. Можно хотеть показать некоторые или все свойства найденного объекта как свойства результирующего объекта. Для примера, GrantResult
класс предоставляет следующее подмножество свойств гранта.
Это спасает клиента объекта результата поиска гранта от необходимости извлечь эти свойства самостоятельно. Конструктор вашего результата должен извлечь значения свойств, которые будут открыты, и задать соответствующие свойства результата для извлеченных значений, например,
Обратите внимание, что GrantResult
объединяет некоторые свойства гранта в одно доступное свойство. Например, он раскрывает InstCity
гранта,
InstState
, InstPostalCode
, и InstCountry
свойства в одно свойство результата с именем Location
.
В этом примере конструктор использует внутренние методы, чтобы извлечь свойства гранта из объекта гранта, который является Java DOM Element
объект, для примера,
Задайте getReporter
Метод
Вы должны задать метод getReporter для вашего объекта результата, который возвращает объект reporter, который сообщает о найденном объекте, который содержит объект результата. Этот метод позволяет клиенту вашего искателя сообщать о результате операции поиска просто путем добавления результата к Report
, Section
, или Chapter
объект. Для примера,
Отчет или add
главы метод знает, что объект результата должен иметь
getReporter
метод, который возвращает репортер, форматирующий данные, содержащиеся в результате. Поэтому, если вы добавляете объект результата к отчету или главе, add
метод вызывает getReporter
результата метод для получения репортера результатов и добавления репортера результатов в отчет или репортер, в результате чего данные результатов будут форматированы и включены в отчет.
The GrantResult
определение класса задает getReporter
метод, который возвращает настроенную версию API Report mlreportgen.report.BaseTable
репортер. The BaseTable
reporter создает таблицу с пронумерованным заголовком. The GrantResult
класс настраивает BaseTable
reporter, чтобы сгенерировать таблицу свойств гранта, например,
Следующий код показывает, как GrantResult
класс настраивает BaseReporter
чтобы сгенерировать нумерованную таблицу свойств гранта:
Этот скрипт показывает, как использовать finder для генерации отчета. Этот скрипт использует пример GrantFinder, используемый в разделе Define a Finder, чтобы сгенерировать отчет PDF о грантах NEH учреждениям в отдельных состояниях с 2010 по 2012 год. Скрипт выполняет следующие задачи.
Импорт API генератора отчетов
Импортируйте классы, включенные в API отчета MATLAB Report Generator. Импорт классов позволяет скрипту использовать неквалифицированные (то есть сокращенные) имена для ссылки на классы.
import mlreportgen.report.* import mlreportgen.dom.*
Создание контейнера отчета
Создайте контейнер PDF для отчета, используя mlreportgen.report.Report
Report API класс. Обратите внимание, что поскольку скрипт импортирует Report API, он может ссылаться на класс по его неквалифицированному имени.
rpt = Report('grant', 'pdf');
Создайте страницу заголовка отчета
Добавьте страницу заголовка к отчету, используя TitlePage
Report API класс.
add(rpt, TitlePage( ... 'Title', 'NEH Grants', ... 'Subtitle', 'By State from 2010-2012', ... 'Image', 'neh_logo.jpg', ... 'Author', 'John Doe' ... ));
Создайте Таблицу содержимого отчета
Добавьте таблицы содержимого, используя TableOfContents
Report API класс.
add(rpt, TableOfContents);
Поиск данных отчета
Используйте массив структур, чтобы задать состояния, которые будут включены в этот отчет. Каждая структура содержит данные для определенного состояния:
Name
: имя состояния
PostalCode
почтовый (почтовый) код состояния
Grants
субсидии, предоставляемые учреждениям в состояние. Это поле первоначально пустое.
NGrants
Количество грантов, предоставленных учреждениям в этом состоянии (первоначально пустых)
states = struct( ... 'Name', {'California', 'Massachusetts', 'New York'}, ... 'PostalCode', {'CA', 'MA', 'NY'}, ... 'Grants', cell(1,3), ... 'NGrants', cell(1,3) ... );
Используйте средство поиска грантов, чтобы заполнить Grants
и NGrants
полей государственных структур. Создайте поиск гранта.
f = GrantFinder;
Цикл через массив состояний. Для каждого состояния используйте Properties
поисковика свойство для ограничения поиска грантов, присуждаемых состоянию. Используйте эти свойства гранта, чтобы ограничить поиск:
InstState
: Определяет почтовый код состояния, в которой находится учреждение, получившее грант.
YearAwarded
: Определяет год, в который была предоставлена субсидия.
Поисковик рассматривает значения свойств как регулярные выражения. Используйте этот факт, чтобы указать область значений значений, 2010-2012, как значение YearAwarded
свойство.
n = numel(states); for i = 1:n f.Properties = [ {'InstState', states(i).PostalCode}, ... {'YearAwarded', '201[0-2]'}]; states(i).Grants = find(f); states(i).NGrants = numel(states(i).Grants); end
Создайте главу Сводных данных грантов
Создайте сводные данные грантов в качестве первой главы отчета. Глава сводных данных грантов содержит заголовок и сводную таблицу грантов. В каждой строке таблицы перечислено общее количество грантов и общая сумма денег, предоставленных учреждениям в состояние за 2010-2012 годы. Состояния указаны в таблице в порядке убывания количества грантов. Каждое состояние имеет гиперссылку на главу, в которой подробно описываются предоставленные ему гранты.
Создайте контейнер сводной главы
Начните, создав контейнер главы..
ch = Chapter('Title', 'Grant Summary');
Создание содержимого сводной таблицы грантов
Начните с создания форматтера валюты Java. Используйте этот объект для форматирования суммы в долларах грантов, предоставляемых состоянию.
currencyFormatter = java.text.NumberFormat.getCurrencyInstance();
Создайте массив ячеек, содержащий содержимое заголовка таблицы.
header = {'State', 'Grants Awarded', 'Amount Awarded'};
Предварительно выделите массив ячеек, содержащий содержимое тела таблицы. Массив ячеек имеет Rx3 строки и столбцы, где R - количество состояний, а 3 - количество элементов сводки, сообщаемых для каждого состояния.
body = cell(numel(states), 3);
Отсортируйте массив состояний по количеству предоставленных им грантов, используя MATLAB sort
функция. The sort
функция возвращает ind
, массив индексов в массив состояний. Первый индекс ind
массив - индекс состояния с большинством грантов, вторым, со вторым самым большим количеством грантов, и т.д.
[~, ind] = sort([states.NGrants], 'descend');
Цикл через состояния по количеству грантов, заполняя сводную информацию для каждого состояния. Используйте переменную, rowIdx
, как индекс к строке массива ячеек, соответствующей текущему состоянию.
rowIdx = 0;
Следующая линия переставляет states
массив в порядке полученных грантов и создает for
цикл, который присваивает каждую структуру в отсортированной states
массив к переменной state
на каждой итерации цикла.
for state = states(ind)
Обновите индекс строки, чтобы указать на строку массива ячеек, соответствующую текущему состоянию.
rowIdx = rowIdx+1;
Скрипт вводит гиперссылку на главу сведений о гранте для состояния в качестве первой записи в таблице для состояния, например,
В следующей линии используется DOM InternalLink
конструктор для создания гиперссылки. The InternalLink
конструктор принимает два аргумента, целевой идентификатор ссылки и текст гиперссылки. Скрипт использует почтовый код текущего состояния в качестве идентификатора цели ссылки, а имя состояния в качестве текста ссылки. Позже, когда скрипт создает главу сведений о гранте, он вставляет цель ссылки в заголовок главы, идентификатор которой является почтовым кодом состояния. Это завершает создание гиперссылки.
body(rowIdx, 1) = {InternalLink(state.PostalCode, state.Name)};
Присвойте общее количество грантов для этого состояния второму элементу в строке массива ячеек.
body(rowIdx, 2) = {state.NGrants};
Вычислите общую сумму, присвоенную этому состоянию.
totalAwarded = 0; for grant = state.Grants totalAwarded = totalAwarded + str2double(grant.AwardAmount); end
Используйте форматтер валюты для форматирования общей суммы в виде долларовой суммы, например,
и присвойте форматированный результат третьему и последнему элементу массива ячеек для этого состояния.
body(rowIdx,3) = {char(currencyFormatter.format(totalAwarded))};
end
Чтобы создать сводную таблицу, передайте заголовок и массивы ячеек тела в конструктор mlreportgen.dom.FormalTable
объект.
table = FormalTable(header, body);
Формальная таблица является таблицей, которая имеет заголовок и тело. The FormalTable
конструктор принимает два аргумента: массив ячеек, задающий содержимое заголовка таблицы, и массив ячеек, задающий содержимое его тела. Конструктор преобразует содержимое массива ячеек в DOM TableRow
и TableEntry
объекты, которые определяют таблицу, сохраняя скрипт от необходимости создавать необходимые объекты таблицы самостоятельно.
Форматирование сводной таблицы грантов
На данной точке сводная таблица выглядит следующим образом:
Это не очень читаемо. Заголовок имеет тот же формат, что и тело, и столбцы не разнесены.
На следующих шагах скрипт настраивает форматирование текста заголовка так, чтобы выглядеть следующим образом:
Сначала скрипт задает ширину и выравнивание столбцов таблицы, используя DOM TableColSpecGroup
объект. A TableColSpecGroup
объект задает формат группы столбцов. Итоговая таблица имеет только одну группу столбцов, поэтому скрипт должен создать только одну TableColSpecGroup
объект.
grp = TableColSpecGroup;
The TableColSpecGroup
Объект позволяет скрипту задать стиль по умолчанию для столбцов таблицы. Скрипт задает 1.5in
ширина столбцов по умолчанию и центровое выравнивание как выравнивание столбцов по умолчанию.
grp.Style = {HAlign('center'), Width('1.5in')};
Скрипт использует TableColSpec
объект, чтобы переопределить выравнивание столбца по умолчанию для первого столбца.
specs(1) = TableColSpec;
specs(1).Style = {HAlign('left')};
grp.ColSpecs = specs;
table.ColSpecGroups = grp;
Примечание Скрипт мог использовать аж три TableColSpec
объекты, по одному для каждого столбца таблицы, для переопределения стилей столбцов группы. Первый TableColSpec
объект применяется к первому столбцу, второму столбцу и т.д. Скрипт должен назначить группе только один объект спецификации столбца, поскольку он переопределяет стиль по умолчанию только для первого столбца. Однако, если бы ему потребовалось изменить только третий столбец, ему пришлось бы назначить три объекта спецификаций столбцов, оставив Style
свойство первых двух объектов спецификаций столбцов пусто.
Стиль таблицы по умолчанию разделяет записи таблицы. Так что скрипт использует DOM InnerMargin
формат объекта, чтобы создать некоторое пространство над записями, чтобы отделить их от записей в строке над ними. Система координат InnerMargin
объект создает пространство (внутреннее поле) между объектом документа и объектом, который содержит его, например, между текстом в записи таблицы и границами записи таблицы. The InnerMargin
конструктор, опционально, принимает четыре аргумента, левые, правые, верхние, нижние внутренние поля объекта документа.
Скрипт использует этот конструктор, чтобы создать верхний внутренний формат поля из 3 точек. Затем этот формат присваивается стилю записей в разделе тела сводной таблицы.
table.Body.TableEntriesStyle = {InnerMargin('0pt', '0pt', '3pt', '0pt')};
Наконец, скрипт форматирует заголовок таблицы так, чтобы он состоял из жирного, белого текста на сером фоне:
table.Header.row(1).Style = {Bold, Color('white'), BackgroundColor('gray')};
Добавьте сводную главу к отчету
add(ch, table); add(rpt, ch);
Создание разделов подробных сведений о грантах
Цикл через структуры состояния.
for state = states
Для каждого состояния создайте главу, чтобы сохранить данные о гранте штата. Вставьте цель ссылки в заголовок главы, чтобы служить целью для гиперссылки в сводной таблице в первой главе.
ch = Chapter('Title', {LinkTarget(state.PostalCode), state.Name});
Цикл через результаты предоставления для состояния.
for grant = state.Grants
Для каждого результата предоставления добавьте результат в главу.
add(ch, grant);
Результат гранта имеет getReporter
метод, который возвращает репортер, который создает таблицу выбранных свойств предоставления. Глава add
метод предварительно сконфигурирован, чтобы получить репортер результата и добавить его в главу. Таким образом, добавление гранта к главе равносильно добавлению таблицы свойств результата к главе, например,
end add(rpt, ch); end
Закройте объект отчета
Закрытие объекта отчета генерирует выходной файл PDF (grant.pdf
), который задает объект отчета.
close(rpt);
Отображение отчета
rptview(rpt);
Источником базы данных, используемой в этом примере, является Национальный фонд гуманитарных наук (NEH). База данных содержит информацию о грантах NEH за 2010-2019 период. Она содержит около 6000 записей в формате XML. Он доступен в NEH Grant Data. Этот пример использует локальную копию XML- файла базы данных, NEH_Grants2010s.xml
.
База данных состоит из Grants
элемент, который содержит набор Grant
элементы, каждый из которых содержит набор элементов предоставленных данных. Ниже приведен экстракт из базы данных, иллюстрирующий ее структуру:
mlreportgen.finder.Finder
| mlreportgen.report.Chapter
| mlreportgen.report.Report
| rptview