Main Content

Create Simulink Report Generator Reports

The Simulink® Report Generator™ Report API comprises a set of objects designed to find and format model and simulation data. You can use these objects with MATLAB® Report API and DOM API objects to create MATLAB programs that generate reports on Simulink models and simulations. The following example illustrates using the Simulink Report API and the MATLAB Report API to create a MATLAB program. This program generates a report on the contents of a Simulink model. The report contains these sections:

  • Title Page

  • Table of Contents

  • Root System Chapter — Contains the root block diagram and properties of each block in the root diagram

  • Subsystems Chapter -- Contains the diagram and block properties of each subsystem of the model

  • Stateflow® Charts Chapter -- Contains charts and chart object properties of each chart in the model

Run the following command to access the supporting files used in this example.

openExample('rptgenext/SimulinkReportGeneratorFilesExample');
  1. Import the API functions.

    To eliminate the need to use fully qualified names of Report, Finder, and DOM API functions, use these statements. For example, instead of using slreportgen.finder.BlockFinder, you can use BlockFinder.

    import slreportgen.report.*
    import slreportgen.finder.*
    import mlreportgen.report.*
  2. Load the sf_car model.

    model = load_system('sf_car');
    
  3. Create a report object.

    Use a Simulink report constructor (slreportgen.report.Report) to create a report object to hold the contents of the report. You must fully qualify the name of the constructor to distinguish it from the MATLAB report constructor (mlreportgen.report.Report). Set the name of the report to sdd_ followed by the value of the Name property of the model.

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

    To customize properties that apply to the whole report, see slreportgen.report.Report.

  4. Add a title page.

    Use a title page reporter constructor (mlreportgen.report.TitlePage) to create a title page reporter. This reporter generates a title page based on its properties. Set the Title, Subtitle, and Author properties to character arrays that specify the report title, subtitle, and author, respectively.

    Use a diagram reporter constructor (slreportgen.report.Diagram) to create a diagram reporter for this model. This reporter generates an image of the block diagram of the model. To include this image on the report title page, assign the diagram reporter to the Image property of the title page reporter. Then, add the title page to the report.

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

    Report title page with title, subtitle, author, and model diagram

    To customize additional title page properties, see mlreportgen.report.TitlePage.

  5. Add a table of contents.

    Use a table of contents (TOC) reporter constructor to create a TOC reporter. This reporter generates a TOC for the report. Add the TOC reporter to the report.

    toc = TableOfContents;
    append(rpt,toc);

    Table of contents showing chapters and subsections

    To customize the table of contents, see mlreportgen.report.TableOfContents.

  6. Add a chapter for the root system.

    Use a chapter constructor (mlreportgen.report.Chapter) to create a chapter reporter. This reporter generates a chapter based on its Title and Content properties. The reporter automatically numbers the chapter title. The chapter reporter also generates the chapter page headers and footers and its page numbers.

    Add a model diagram reporter to the chapter. This reporter returns an image of the block diagram of the model that you add to the chapter.

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

    Block diagram image displaying below chapter name RootSystem

    For information on customizing chapters, see mlreportgen.report.Chapter.

  7. Add chapter sections for each root system block.

    Use the block finder constructor (slreportgen.report.BlockFinder) to create a block finder for the root diagram. Then, use the find function of the block finder. The find function returns an array of block result objects (slreportgen.report.BlockResult), each of which contains a block.

    Loop through the block result objects. For each result, construct a section reporter (mlreportgen.report.Section). This reporter generates a numbered report section based on its Title and Content properties. Set the section Title property to the name of the block on which it reports.

    Add the current block result to the section reporter. Adding the result sets the section reporter Content property to a simulink.report.SimulinkObjectProperties reporter. This SimulinkObjectProperties reporter generates a table of the properties of the current block, which is then added to the section. Add each subsection to the parent chapter. Then add the chapter to the report.

    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);

    Subsections of the report with tables of properties inserted in each subsection

    For information finding blocks and how to customize sections, see slreportgen.finder.BlockFinder and mlreportgen.report.Section, respectively.

  8. Add a chapter for subsystems.

    Create a chapter for the subsystems of the model and the blocks in each subsystem.

    ch = Chapter("Title","Subsystems");
  9. Find subsystem diagrams in the model.

    Find all subsystem diagrams in the model. The finder returns an array of DiagramResult objects, each of which contains a Diagram reporter that creates a snapshot of the subsystem diagram.

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

    Chapter titled Subsystems, followed by subsection titled Engine, which contains a snapshot of subsystem diagram, and another subsection titled Ti which contains a table of properties

    For more information, see slreportgen.finder.SystemDiagramFinder and slreportgen.finder.DiagramResult

  10. Add results to chapter sections.

    Using loops, create a chapter section for each subsystem. Find the blocks and block elements in each subsystem. Add a table of block elements to each chapter section and add each section to the chapter. Then, add the chapter to the report.

    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);
     

    Subsection titled Vehicle, which contains a block diagram, and another subsection titled brake torque which contains a table of properties

    Note

    Simulink finders can operate in either array or iterator mode. In array mode, use the finder find function to return the search results as an array of results. In iterator mode, use the finder hasNext and next functions to return the search results one-by-one. Use iterator mode when searching for diagrams in models that have many model references. Iterator mode closes a model after compiling and searching it, whereas find mode keeps all the models that it searches open. Having many open models can potentially consume all system memory and slow report generation. Although the model used in this example does not contain model references, the example uses iterator mode to illustrate its syntax.

  11. Add a chapter for Stateflow charts and objects.

    Find all Stateflow charts in the model. Create a chapter. Using loops, add subsections for each chart. Find all the elements in each chart and add them to the subsections. Then, add the section to the chapter and the chapter to the report.

    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);

    For information on chart and diagram element finders, see slreportgen.finder.ChartDiagramFinder and slreportgen.finder.StateflowDiagramElementFinder.

    Chapter title Stateflow Charts with subsections for each Stateflow chart, followed by tables of properties

  12. Close the report, run the report, and close the model.

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

The complete code is:

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);

See Also