Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Unified skill for all MATLAB and Simulink report generation tasks. Covers report generation, PDF report, document generation, mlreportgen, Report Generator, template, TitlePage, Chapter, multipage HTML, HTMLPage, html-multipage, custom reporter, customizeReporter, template hole, page header, page border, company style package, branded reporters, buildTemplates, Simulink report, model documentation, slreportgen, block diagram report, model report, subsystem documentation, SystemDiagramFinder, Sys
.claude/skills/matlab-matlab-generate-report/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-03 | ✗→✓ | ▲ Improved | 58% | 0% |
| case-01 | ✗→✓ | ▲ Improved | 73% | 0% |
| case-02 | ✗→✓ | ▲ Improved | 83% | 0% |
| case-08 | ✗→✓ | ▲ Improved | 189% | 0% |
| case-09 | ✗→✓ | ▲ Improved | 115% | 0% |
Generate structured, professional reports (PDF, Word, HTML) from MATLAB data and Simulink models.
writetable, writematrixslreportgen.webview.* directlyAlways use the Report API (mlreportgen.report.*) as the foundation. It provides the Report container and reporters (Figure, BaseTable, FormalImage, Chapter, TitlePage, etc.) that handle auto-numbering, captions, and document structure.
Use both APIs together. Use the Report API to create the report and add content for which reporters exist. Use the DOM API (mlreportgen.dom.*) for styled paragraphs, custom tables, inline formatting, HTML inclusion, and images without captions. DOM objects append directly to Report, Chapter, or Section alongside reporters.
Critical rule: Report API reporters (Figure, BaseTable, FormalImage) can ONLY be appended to Report, Chapter, or Section objects — never to DOM objects like TableEntry. Use DOM objects inside TableEntry.
Simulink reports: Use slreportgen.report.Report (not mlreportgen.report.Report) — it extends the base with model compilation support required by SystemIO, ExecutionOrder, and other Simulink reporters.
Multipage HTML: Use mlreportgen.dom.Document with "html-multipage" type + HTMLPage objects. This is the only case where you use the DOM Document instead of the Report API Report.
TitlePage, TableOfContents, ListOfFigures, and ListOfTables are optional — include only when the task requires them. The minimal report is just Report + content + close.
matlabimport mlreportgen.report.* import mlreportgen.dom.* rpt = Report("MyReport","pdf"); append(rpt,TitlePage(Title="Report Title",Author="Team")); % optional append(rpt,TableOfContents()); % optional append(rpt,ListOfFigures()); % optional append(rpt,ListOfTables()); % optional ch = Chapter("Results"); append(ch,Paragraph("Analysis complete.")); % Auto-numbered table data = FormalTable(["ID","Value"],[1 10; 2 20]); bt = BaseTable(data); bt.Title = "Measured values"; append(ch,bt); % Auto-numbered figure fig = figure("Visible","off"); plot([1 2],[10 20]); rptFig = Figure(fig); rptFig.Snapshot.Caption = "Value trend"; append(ch,rptFig); close(fig); append(rpt,ch); close(rpt); rptview(rpt);
matlabload_system(modelName); % MUST use slreportgen.report.Report for Simulink content rpt = slreportgen.report.Report(outputPath,"pdf"); append(rpt,mlreportgen.report.TitlePage("Title","Model Report")); append(rpt,mlreportgen.report.TableOfContents()); ch = mlreportgen.report.Chapter("Diagrams"); % Root diagram — direct reporter rootDiag = slreportgen.report.Diagram(modelName); rootDiag.Snapshot.ScaleToFit = true; append(ch,rootDiag); % Subsystems — finder pattern (iterator for memory efficiency) finder = slreportgen.finder.SystemDiagramFinder(modelName); finder.IncludeRoot = false; finder.SortType = "alphabetical"; while finder.hasNext() result = finder.next(); sec = mlreportgen.report.Section("Title",result.Name); append(sec,result); append(ch,sec); end append(rpt,ch); close(rpt); rptview(rpt);
Before writing code, analyze requirements against built-in reporter capabilities:
TitlePage has: Title, Subtitle, Author, Publisher, PubDate, Image. Built-in Chapter/Section provide headings, auto-numbering, and a Content hole.Common triggers for custom reporters:
Do NOT force-fit requirements into built-in properties (e.g., concatenating fields into Subtitle). Create a custom reporter instead.
Do NOT build custom title pages with raw DOM elements (Paragraphs, Images appended to a Chapter). Always use customizeReporter for template-based layout and format portability.
| I need to... | Reference | |--------------|-----------| | Build a standard report with chapters, figures, tables, verification | references/report-api-patterns.md | | Work with DOM tables, HTML inclusion, multipage HTML, Number/NumberFormat | references/dom-api-patterns.md | | Understand template file types, locate/inspect templates | references/template-system.md | | Look up built-in template holes, styles, page layout (pre-computed) | references/template-reference.md | | Create a custom reporter class (customizeReporter, holes, headers) | references/custom-reporters.md | | Build a multi-reporter package with shared styles and buildTemplates | references/report-package.md | | Generate Simulink model reports (finders, orientation, centering) | references/simulink-report.md | | Look up all Simulink finders and reporters | references/finders-and-reporters.md | | Iterate struct arrays into chapters with custom reporters | references/data-driven-report-pattern.md | | Edit template styles (colors, fonts, headers, footers, TOC) | references/template-system.md |
| Class | Purpose | Package | |-------|---------|---------| | Report | Top-level report container | mlreportgen.report | | TitlePage | Title page with title, subtitle, author | mlreportgen.report | | TableOfContents | Auto-generated TOC | mlreportgen.report | | Chapter / Section | Document structure | mlreportgen.report | | Figure | Auto-numbered figure from MATLAB figure | mlreportgen.report | | FormalImage | Auto-numbered image from file with caption | mlreportgen.report | | BaseTable | Auto-numbered table wrapper (pass FormalTable) | mlreportgen.report | | FormalTable | Table with header/body/footer from cell arrays | mlreportgen.dom | | Template (3-arg) | Edit templates: Template(out,fmt,src) | mlreportgen.dom | | HTMLFile / HTML | Include HTML content in any output format | mlreportgen.dom | | HTMLPage | Page in multipage HTML document (R2024a+) | mlreportgen.dom | | Number | Numeric DOM object (use with NumberFormat) | mlreportgen.dom | | TemplateHole | Placeholder filled at report time | mlreportgen.dom | | Page / NumPages | Page number / total pages | mlreportgen.dom | | *.customizeReporter | Scaffold custom reporter + templates | mlreportgen.report | | getStyle / replaceStyle | Modify template styles | mlreportgen.dom | | slreportgen.report.Report | Report container for Simulink content | slreportgen.report | | slreportgen.report.Diagram | Diagram snapshot of a system | slreportgen.report | | slreportgen.finder.SystemDiagramFinder | Find system/subsystem diagrams | slreportgen.finder | | slreportgen.report.SystemIO | Report inputs/outputs (requires compilation) | slreportgen.report | | slreportgen.report.ExecutionOrder | Report block execution order | slreportgen.report | | slreportgen.report.LookupTable | Report lookup table data + plot | slreportgen.report | | rptview | Display report (updates DOCX fields) | function | | docview | Process Word documents (update fields, convert) | function |
| Mistake | Correct Approach | |---------|-----------------| | Using mlreportgen.dom.Document as report container | Use mlreportgen.report.Report. Exception: multipage HTML requires Document with "html-multipage" | | Using mlreportgen.report.Report for Simulink content | Use slreportgen.report.Report — needed for model compilation | | Using Report with "html" for multipage output | Use mlreportgen.dom.Document with "html-multipage" + HTMLPage objects | | Appending reporters to DOM objects (Paragraph, TableEntry) | Reporters can ONLY go in Report, Chapter, or Section. Use DOM objects inside TableEntry | | Putting raw doubles in FormalTable cells | Use Number with NumberFormat in Style: n = Number(42); n.Style = {NumberFormat("%.0f")}. Put n directly in cell arrays. See references/dom-api-patterns.md § Number and NumberFormat | | NumberFormat("$%.0f") or NumberFormat("%,.0f") | Only standard sprintf specifiers work (no $, no %,, no %d). For currency/units, wrap Number in Paragraph and prepend/append Text | | Customizing only "default"/"even" page headers | Customize ALL page types: "first", "default", "even" — but differentiate content (see below) | | Putting StyleRef (chapter title) in the first-page header | First page already displays the chapter heading — omit StyleRef from "first" header. Use it only in "default"/"even" for wayfinding | | Opening DOCX with winopen/open/start | Use rptview(rpt) or docview(file,"updatefields") — triggers field update | | Using ColSpec/ColSpecGroup for widths | Use TableColSpecGroup + TableColSpec with Width in Style | | Setting widths without ResizeToFitContents(false) | Add ResizeToFitContents(false) to table Style; set absolute ft.Width (not "100%") | | TemplateParagraphStyle.Formats = {Bold(true)} | Use array: Formats = [Bold(true),FontSize("12pt")] | | Template(path,"pdf") to edit existing template | 2-arg creates blank. Use 3-arg: Template(out,"pdf",src) | | Same path for source and output in Template constructor | OPC cannot read/write simultaneously. Use different paths, then movefile | | Setting PDFPageLayout.PageSize.Orientation without rotate() | Call rotate(pl) — swaps Width/Height AND sets Orientation | | Using DOCXPageLayout without explicit Height and Width | DOCX does not auto-swap — set both explicitly | | Page numbers resetting after PDFPageLayout | Set pl.FirstPageNumber = '' (empty string) to continue numbering | | Wrapping reporter in Paragraph to center it | Customize the reporter's template style via Template API | | Using RawText(html) for HTML in PDF | Use HTMLFile(path) or HTML(string) — works for any format | | Using Group in a Table cell array | Use nested cell arrays: Table({{img,caption},desc}) | | Passing MATLAB table() to BaseTable | Pass FormalTable(headers,body) — avoids MATLABTable wrapper | | e.Style = {BackgroundColor("yellow")} (overwrites existing styles) | Append: e.Style = [e.Style, {BackgroundColor("yellow")}] — preserves inherited styles | | Force-fitting fields into TitlePage.Subtitle | Create a custom title page reporter via customizeReporter | | Writing custom reporter class from scratch | Use customizeReporter to scaffold — creates required binary templates | | Writing classdef before running customizeReporter | Scaffolding overwrites classdef files. Scaffold first, then edit | | Unqualified TitlePage.getClassFolder() in package | Use fully-qualified: mypkg.TitlePage.getClassFolder() | | getStyle(ss,name,type) for PDF/HTML | Type arg returns []. Use getStyle(ss,name) without type | | OuterMargin("12pt","6pt","0","0") for vertical spacing | Args are (left,right,top,bottom) — NOT CSS order. Use OuterMargin("0","0","12pt","6pt") for top/bottom spacing | | Using TemplateCharacterStyle | Does not exist. Use TemplateTextStyle for character/inline styles in PDF/HTML | | Unzipping .pdftx/.htmtx/.dotx to edit with fileread/regexprep | ALWAYS use DOM Template API — Template(out,fmt,src) + open + modify objects + close. Raw edits bypass framework validation | | find_system + DiagramFinder for discovery | Use SystemDiagramFinder with filter properties | | Diagram(result.Path) on ChartDiagramFinder results | Use getReporter(result) — chart paths are invalid for Diagram constructor | | find() + for loop on finders | Always use iterator: while finder.hasNext() / result = finder.next() | | BlockFinder with SearchDepth=inf expecting referenced models | BlockFinder does NOT traverse Model References. Use SystemDiagramFinder (IncludeReferencedModels=true) + per-system BlockFinder (SearchDepth=1) | | ExecutionOrder on virtual subsystem | Check get_param(obj,'IsSubsystemVirtual') first | | ExecutionOrder/SystemIO on Simulink Functions | Guard with slreportgen.utils.isSimulinkFunction(result.Object) |
close(rpt) after appending all content — generates the output filerptview or docview to open DOCX — never winopen or openfigure("Visible","off") for plots destined for reportsexportgraphics (not print) when saving figures to filesBaseTable wraps FormalTable — pass FormalTable(headers,body), not a MATLAB table()entry(t,row,col) after construction, not during[] arrays; inline .Style properties use {}@ClassName directories — each needs its own resources/templates/customizeReporter creates binary templates + overwrites classdefslreportgen.report.Report; always Diagram.Snapshot.ScaleToFit = true.Object handle (not path string) for get_param; use result.Name for titlesmatlabrptview(rpt); % Open in system viewer (updates DOCX fields) rptview("MyReport.docx","pdf"); % Convert DOCX to PDF via Word docview("Report.docx","updatefields","closedoc","closeapp"); % Update without display
Verification: Running without error does NOT confirm correctness. After close(rpt):
isfile(rpt.OutputPath) and dir(rpt.OutputPath).bytes > 1000open(rpt), then set rpt.Document.RetainFO = true before appending content, search *_FO/*.fo filesword/document.xmlSee references/report-api-patterns.md for full verification patterns.
MATLAB Report Generator (verify with mcp__matlab__detect_matlab_toolboxes). Simulink Report Generator additionally required for Simulink model reports.
Copyright 2026 The MathWorks, Inc.
Other measured skills in the registry, with their headline benchmark lift.