Main Content

本页采用了机器翻译。点击此处可查看英文原文。

创建 Simulink Report Generator 报告

Simulink® Report Generator™ 报告 API 包含一组用于查找和格式化模型和仿真数据的对象。您可以将这些对象与 MATLAB® 报告 API 和 DOM API 对象一起使用来创建 MATLAB 程序,以生成有关 Simulink 模型和仿真的报告。下面的示例说明如何使用报告 API 和报告 API 创建 MATLAB 程序。该程序生成有关 Simulink 模型内容的报告。报告包含以下节:

  • 标题页面

  • 目录

  • 根系统章节--包含根模块图以及根模块图中每个模块的属性

  • 子系统章节--包含模型每个子系统的图和模块属性

  • Stateflow® 图章节--包含模型中每个图的图和图对象属性

运行以下命令访问本示例中使用的支持文件。

openExample('rptgenext/SimulinkReportGeneratorFilesExample');
  1. 导入 API 函数。

    为了消除使用报告、查找器和 DOM API 函数的完全限定名称的需要,请使用这些语句。例如,您可以使用 BlockFinder,而不是使用 slreportgen.finder.BlockFinder

    import slreportgen.report.*
    import slreportgen.finder.*
    import mlreportgen.report.*
  2. 加载 sf_car 模型。

    model = load_system('sf_car');
    
  3. 创建报告对象。

    使用 Simulink 报告构造函数(slreportgen.report.Report)创建报告对象来保存报告的内容。您必须完全限定构造函数的名称,以将其与 MATLAB 报告构造函数 (mlreportgen.report.Report) 区分开来。将报告的名称设置为 sdd_,后跟模型的 Name 属性的值。

    rpt = slreportgen.report.Report(['sdd_'...
        get_param('sf_car','Name')],'pdf');
    

    要自定义适用于整个报告的属性,请参阅 slreportgen.report.Report

  4. 添加标题页。

    使用标题页报告器构造函数(mlreportgen.report.TitlePage)来创建标题页报告器。该报告器根据其属性生成了标题页。将 TitleSubtitleAuthor 属性设置为分别指定报告标题、副标题和作者的字符数组。

    使用图报告器构造函数(slreportgen.report.Diagram)为该模型创建图报告器。该报告器生成了该模型模块的图像。要将此图像包含在报告标题页中,请将图报告器分配给标题页报告器的 Image 属性。然后,将标题页添加到报告。

    tp = TitlePage;
    tp.Title = upper(get_param(model,'Name'));
    tp.Subtitle = 'System Design Description';
    tp.Author = 'MathWorks';
    tp.Image = Diagram(model);
    append(rpt,tp);
    

    要自定义其他标题页属性,请参阅 mlreportgen.report.TitlePage

  5. 添加目录。

    使用目录 (TOC) 报告器构造函数创建 TOC 报告器。该报告器为该报告生成了目录。将 TOC 报告器添加到报告中添加。

    toc = TableOfContents;
    append(rpt,toc);

    要自定义目录,请参阅 mlreportgen.report.TableOfContents

  6. 为根系统添加一章。

    使用章节构造函数(mlreportgen.report.Chapter)创建章节报告器。该报告器根据其 TitleContent 属性生成章节。报告器自动对章节标题进行编号。章节报告器还会生成章节页眉和页脚及其页码。

    在章节中添加模型图报告器。该报告器返回您添加到章节的模型的模块图像。

    ch = Chapter("Title","RootSystem");
    append(ch,Diagram(model));

    有关自定义章节的信息,请参阅 mlreportgen.report.Chapter

  7. 为每个根系统模块添加章节部分。

    使用模块查找器构造函数(slreportgen.report.BlockFinder)为根图创建一个模块查找器。然后,使用模块查找器的 find 函数。find 函数返回一个模块结果对象数组(slreportgen.report.BlockResult),每个对象包含一个模块。

    循环遍历模块结果对象。对于每个结果,构建一个节报告器(mlreportgen.report.Section)。该报告器根据其 TitleContent 属性生成编号的报告节。将节 Title 属性设置为其报告的模块的名称。

    将当前模块结果添加到节报告器中。添加结果将节报告器 Content 属性设置为 simulink.report.SimulinkObjectProperties 报告器。这个 SimulinkObjectProperties 报告器会生成当前模块的属性表,然后将其添加到该节。将每个小节添加到父章节。然后将章节添加到报告中。

    blkFinder = BlockFinder(model);
    blocks = find(blkFinder);
    for block = blocks
        section = Section("Title", ...
           strrep(block.Name, newline,' '));
        append(section,block);
        append(ch,section);
    end
    append(rpt,ch);

    有关查找模块和如何自定义节的信息,请分别参阅 slreportgen.finder.BlockFindermlreportgen.report.Section

  8. 添加子系统章节。

    为模型的子系统以及每个子系统中的模块创建一个章节。

    ch = Chapter("Title","Subsystems");
  9. 在模型中查找子系统图。

    查找模型中的所有子系统图。查找器返回一个 DiagramResult 对象数组,每个对象都包含一个创建子系统图快照的 Diagram 报告器。

    sysdiagFinder = SystemDiagramFinder(model);
    sysdiagFinder.IncludeRoot = false;

    有关详细信息,请参阅 slreportgen.finder.SystemDiagramFinderslreportgen.finder.DiagramResult

  10. 将结果添加到章节部分。

    使用循环为每个子系统创建一个章节部分。查找每个子系统中的块和模块元素。为每个章节部分添加一个模块元素表,并将每个部分添加到章节中。然后,将该章节添加到报告中。

    while hasNext(sysdiagFinder)
        system = next(sysdiagFinder);
        section1 = Section("Title",system.Name);
        append(section1,system);
        
        blkFinder1 = BlockFinder(system);
        elems = find(blkFinder1);
        for elem = elems
           section2 = Section("Title",...
               strrep(elem.Name,newline,' '));
           append(section2,elem);
           append(section1,section2);
        end
        append(ch,section1);
    end
    append(rpt,ch);
     

    注意

    Simulink 查找器可以在数组或迭代器模式下运行。在数组模式下,使用查找器 find 函数将搜索结果以结果数组的形式返回。在迭代器模式下,使用查找器 hasNextnext 函数逐一返回搜索结果。在具有许多模型引用的模型中搜索图时使用迭代器模式。迭代器模式在编译和搜索模型后会关闭该模型,而查找模式则会保持其搜索的所有模型处于打开状态。打开许多模型可能会消耗所有系统内存并减慢报告生成速度。虽然本例中使用的模型不包含模型引用,但示例使用迭代器模式来说明其语法。

  11. 为 Stateflow 图和对象添加一章。

    查找模型中的所有 Stateflow 图。创建一个章节。使用循环为每个图添加子节。找到每个图中的所有元素并将其添加到子节。然后,将节添加到章中,将章添加到报告中。

    ch = Chapter("Title", "Stateflow Charts");
    
    chdiagFinder = ChartDiagramFinder(model);
    while hasNext(chdiagFinder) 
       chart = next(chdiagFinder); 
       section = Section("Title",chart.Name);
       append(section,chart);
    
       objFinder = StateflowDiagramElementFinder(chart);
       sfObjects = find(objFinder);
       for sfObj = sfObjects
           title = sfObj.Name;
           if isempty(title)
              title = sfObj.Type;
           end
           objSection = Section("Title",title);
           append(objSection,sfObj);
           append(section,objSection);
       end
       append(ch,section);
    end
    append(rpt,ch);

    有关图和图元素查找器的信息,请参阅 slreportgen.finder.ChartDiagramFinderslreportgen.finder.StateflowDiagramElementFinder

  12. 关闭报告,运行报告,然后关闭模型。

    close(rpt);
    rptview(rpt);
    close_system(model);

完整代码如下:

import slreportgen.report.*
import slreportgen.finder.*
import mlreportgen.report.*
model = load_system('sf_car');
rpt = slreportgen.report.Report(['sdd_'...
    get_param('sf_car','Name')],'pdf');

tp = TitlePage;
tp.Title = upper(get_param(model,'Name'));
tp.Subtitle = 'System Design Description';
tp.Author = 'MathWorks';
tp.Image = Diagram(model);
append(rpt,tp);
toc = TableOfContents;
append(rpt,toc);

ch = Chapter("Title","RootSystem");
append(ch,Diagram(model));
blkFinder = BlockFinder(model);
blocks = find(blkFinder);
for block = blocks
    section = Section("Title", ...
       strrep(block.Name, newline, ' '));
    append(section,block);
    append(ch,section);
end
append(rpt,ch);

ch = Chapter("Title","Subsystems");
sysdiagFinder = SystemDiagramFinder(model);
sysdiagFinder.IncludeRoot = false;

while hasNext(sysdiagFinder)
    system = next(sysdiagFinder);
    section1 = Section("Title",system.Name);
    append(section1,system);
    
    blkFinder1 = BlockFinder(system);
    elems = find(blkFinder1);
    for elem = elems
       section2 = Section("Title",...
           strrep(elem.Name, newline, ' '));
       append(section2,elem);
       append(section1,section2);
    end
    append(ch,section1);
end
append(rpt,ch);

ch = Chapter("Title", "Stateflow Charts");
chdiagFinder = ChartDiagramFinder(model);
while hasNext(chdiagFinder) 
   chart = next(chdiagFinder); 
   section = Section("Title",chart.Name);
   append(section,chart);

   objFinder = StateflowDiagramElementFinder(chart);
   sfObjects = find(objFinder);
   for sfObj = sfObjects
       title = sfObj.Name;
       if isempty(title)
          title = sfObj.Type;
       end
       objSection = Section("Title",title);
       append(objSection,sfObj);
       append(section,objSection);
   end
   append(ch,section);
end
append(rpt,ch);

close(rpt);
rptview(rpt);
close_system(model);

另请参阅