Создайте и используйте пользовательский поиск

Отчет 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). База данных содержит информацию о грантах NEH за 2010-2019 период. Она содержит около 6000 записей в формате XML. Он доступен в NEH Grant Data. Этот пример использует локальную копию XML- файла базы данных, NEH_Grants2010s.xml.

База данных состоит из Grants элемент, который содержит набор Grant элементы, каждый из которых содержит набор элементов предоставленных данных. Ниже приведен экстракт из базы данных, иллюстрирующий ее структуру:

См. также

| | |

Похожие темы