视觉画布设计
canvas-design
基于设计原则创作静态视觉作品,用于海报与品牌图形。
, no `%,`, no `%d`). For currency/units, wrap `Number` in `Paragraph` and prepend/append `Text` |\n| Customizing only \"default\"/\"even\" page headers | Customize ALL page types: \"first\", \"default\", \"even\" — but differentiate content (see below) |\n| 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 |\n| Opening DOCX with `winopen`/`open`/`start` | Use `rptview(rpt)` or `docview(file,\"updatefields\")` — triggers field update |\n| Using `ColSpec`/`ColSpecGroup` for widths | Use `TableColSpecGroup` + `TableColSpec` with `Width` in `Style` |\n| Setting widths without `ResizeToFitContents(false)` | Add `ResizeToFitContents(false)` to table `Style`; set absolute `ft.Width` (not `\"100%\"`) |\n| `TemplateParagraphStyle.Formats = {Bold(true)}` | Use array: `Formats = [Bold(true),FontSize(\"12pt\")]` |\n| `Template(path,\"pdf\")` to edit existing template | 2-arg creates blank. Use 3-arg: `Template(out,\"pdf\",src)` |\n| Same path for source and output in Template constructor | OPC cannot read/write simultaneously. Use different paths, then `movefile` |\n| Setting `PDFPageLayout.PageSize.Orientation` without `rotate()` | Call `rotate(pl)` — swaps Width/Height AND sets Orientation |\n| Using `DOCXPageLayout` without explicit Height and Width | DOCX does not auto-swap — set both explicitly |\n| Page numbers resetting after `PDFPageLayout` | Set `pl.FirstPageNumber = ''` (empty string) to continue numbering |\n| Wrapping reporter in Paragraph to center it | Customize the reporter's template style via Template API |\n| Using `RawText(html)` for HTML in PDF | Use `HTMLFile(path)` or `HTML(string)` — works for any format |\n| Using `Group` in a `Table` cell array | Use nested cell arrays: `Table({{img,caption},desc})` |\n| Passing MATLAB `table()` to `BaseTable` | Pass `FormalTable(headers,body)` — avoids `MATLABTable` wrapper |\n| `e.Style = {BackgroundColor(\"yellow\")}` (overwrites existing styles) | Append: `e.Style = [e.Style, {BackgroundColor(\"yellow\")}]` — preserves inherited styles |\n| Force-fitting fields into `TitlePage.Subtitle` | Create a custom title page reporter via `customizeReporter` |\n| Writing custom reporter class from scratch | Use `customizeReporter` to scaffold — creates required binary templates |\n| Writing classdef before running `customizeReporter` | Scaffolding overwrites classdef files. Scaffold first, then edit |\n| Unqualified `TitlePage.getClassFolder()` in package | Use fully-qualified: `mypkg.TitlePage.getClassFolder()` |\n| `getStyle(ss,name,type)` for PDF/HTML | Type arg returns `[]`. Use `getStyle(ss,name)` without type |\n| `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 |\n| Using `TemplateCharacterStyle` | Does not exist. Use `TemplateTextStyle` for character/inline styles in PDF/HTML |\n| 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 |\n| `find_system` + `DiagramFinder` for discovery | Use `SystemDiagramFinder` with filter properties |\n| `Diagram(result.Path)` on `ChartDiagramFinder` results | Use `getReporter(result)` — chart paths are invalid for `Diagram` constructor |\n| `find()` + for loop on finders | Always use iterator: `while finder.hasNext()` / `result = finder.next()` |\n| `BlockFinder` with `SearchDepth=inf` expecting referenced models | `BlockFinder` does NOT traverse Model References. Use `SystemDiagramFinder` (IncludeReferencedModels=true) + per-system `BlockFinder` (SearchDepth=1) |\n| `ExecutionOrder` on virtual subsystem | Check `get_param(obj,'IsSubsystemVirtual')` first |\n| `ExecutionOrder`/`SystemIO` on Simulink Functions | Guard with `slreportgen.utils.isSimulinkFunction(result.Object)` |\n\n## Conventions\n\n- **Always `close(rpt)`** after appending all content — generates the output file\n- **Always `rptview` or `docview`** to open DOCX — never `winopen` or `open`\n- **Use `figure(\"Visible\",\"off\")`** for plots destined for reports\n- **Use `exportgraphics`** (not `print`) when saving figures to files\n- **One Chapter = one numbering scope** — figures/tables numbered Chapter-Sequence (e.g., \"Figure 2-1\")\n- **`BaseTable` wraps `FormalTable`** — pass `FormalTable(headers,body)`, not a MATLAB `table()`\n- **Cell-level styling:** Use `entry(t,row,col)` after construction, not during\n- **Template styles use `[]` arrays**; inline `.Style` properties use `{}`\n- **Reporters in `@ClassName` directories** — each needs its own `resources/templates/`\n- **Scaffold ALL reporters before editing ANY** — `customizeReporter` creates binary templates + overwrites classdef\n- **Fix unqualified class names** after scaffolding — use package-qualified names\n- **Customize all output formats** — PDF/Word/HTML templates are independent\n- **Simulink:** Always `slreportgen.report.Report`; always `Diagram.Snapshot.ScaleToFit = true`\n- **Simulink finders:** Use `.Object` handle (not path string) for `get_param`; use `result.Name` for titles\n- **JSON is single source of truth** for multi-reporter packages — never hardcode style values\n\n## Viewing and Processing Reports\n\n```matlab\nrptview(rpt); % Open in system viewer (updates DOCX fields)\nrptview(\"MyReport.docx\",\"pdf\"); % Convert DOCX to PDF via Word\ndocview(\"Report.docx\",\"updatefields\",\"closedoc\",\"closeapp\"); % Update without display\n```\n\n**Verification:** Running without error does NOT confirm correctness. After `close(rpt)`:\n- Check `isfile(rpt.OutputPath)` and `dir(rpt.OutputPath).bytes > 1000`\n- For PDF: call `open(rpt)`, then set `rpt.Document.RetainFO = true` before appending content, search `*_FO/*.fo` files\n- For DOCX: unzip and search `word/document.xml`\n- Assert expected titles, headings, captions appear in output\n\nSee [references/report-api-patterns.md](references/report-api-patterns.md) for full verification patterns.\n\n## Required Toolbox\n\nMATLAB Report Generator (verify with `mcp__matlab__detect_matlab_toolboxes`). Simulink Report Generator additionally required for Simulink model reports.\n\n----\n\nCopyright 2026 The MathWorks, Inc.\n\n----\n","licenseDocuments":[]}}
matlab-generate-report【文档与办公】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, buil…
独立 GitHub 快照 · 自动分类 · 以原作者文档为准
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.
import 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);
load_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 titlesrptview(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.