skills/flexcel-vcl/SKILL.md
Use when writing Delphi / FreePascal / C++Builder code that reads, writes, manipulates, or exports Excel (.xlsx / .xls) files, generates PDF or HTML from Excel, or produces data-driven reports with FlexCel Studio for VCL and FireMonkey (TMS FlexCel). Triggers include Excel/xlsx from Delphi, TXlsFile, TFlexCelReport, TFlexCelPdfExport, TFlexCelHtmlExport, FireMonkey Excel export, Lazarus Excel, and Excel reporting from Pascal.
npx skillsauth add tmssoftware/skills flexcel-vclInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
This skill helps write Delphi (VCL, FMX, Lazarus/LCL, Linux/SKIA) and C++Builder code that uses FlexCel — the TMS Software library for working with Excel .xlsx / .xls files, exporting to PDF/HTML/images, and generating data-driven reports from templates.
Activate whenever the user wants to, from Pascal/Delphi/C++Builder code:
.xlsx or .xls) — cell values, formulas, formatting.FlexCel does not require Excel or any Office installation on the target machine. It has no OLE/COM dependency.
Before writing code, decide which API fits the task:
| If the user wants to… | Use | Why |
|-----------------------|-----|-----|
| Read existing files, or build files cell-by-cell in code | TXlsFile API (FlexCel.XlsAdapter) | Full programmatic control; no designer required. |
| Produce the same report repeatedly from changing data, with a styled layout | TFlexCelReport + Excel template (FlexCel.Report) | Non-programmers can edit the template in Excel; code just provides data. |
When the user says "generate a report with company logo / nice formatting / many rows from a database", prefer Reports. When they say "read this file and extract values" or "create an Excel file with these calculations", prefer the API.
You can combine both: run a report to produce an in-memory TXlsFile, then manipulate it with the API, then export to PDF.
All examples assume VCL. For FireMonkey replace FlexCel.VCLSupport with FlexCel.FMXSupport; for Lazarus use FlexCel.LCLSupport; for Delphi Linux use FlexCel.SKIASupport. The platform support unit goes in the main program (.dpr) uses clause only, not every unit.
uses
System.IOUtils,
FlexCel.Core, FlexCel.XlsAdapter;
procedure CreateExcelFile;
var
xls: TXlsFile;
begin
// Start an empty workbook with 1 sheet and Excel-2019 default formatting.
xls := TXlsFile.Create(1, TExcelFileFormat.v2019, true);
try
xls.SetCellValue(1, 1, 'Hello from FlexCel!'); // A1 text
xls.SetCellValue(2, 1, 7); // A2 number
xls.SetCellValue(3, 1, 11.3); // A3 number
xls.SetCellValue(4, 1, TFormula.Create('=Sum(A2:A3)')); // A4 formula
xls.Save(TPath.Combine(TPath.GetDocumentsPath, 'test.xlsx'));
finally
xls.Free;
end;
end;
Key points:
(1, 1) is cell A1. (XF format indices are the single exception — they're 0-based.).xlsx → OOXML, .xls → BIFF8).TXlsFile is a plain class, not a component — you create it in code and must Free it.uses
System.IOUtils,
FlexCel.Core, FlexCel.XlsAdapter;
procedure ReadExcelFile(const aMemo: TMemo);
var
xls: TXlsFile;
row, colIndex, XF: integer;
cell: TCellValue;
addr: TCellAddress;
s: string;
begin
xls := TXlsFile.Create(TPath.Combine(TPath.GetDocumentsPath, 'test.xlsx'));
try
xls.ActiveSheetByName := 'Sheet1'; // or loop xls.ActiveSheet from 1 to xls.SheetCount
for row := 1 to xls.RowCount do
begin
// Use ColCountInRow, NOT ColCount — much faster. See performance guide.
for colIndex := 1 to xls.ColCountInRow(row) do
begin
XF := -1;
cell := xls.GetCellValueIndexed(row, colIndex, XF);
addr := TCellAddress.Create(row, xls.ColFromIndex(row, colIndex));
s := 'Cell ' + addr.CellRef + ' ';
if cell.IsEmpty then s := s + 'is empty.'
else if cell.IsString then s := s + 'string: ' + cell.ToString
else if cell.IsNumber then s := s + 'number: ' + FloatToStr(cell.AsNumber)
else if cell.IsBoolean then s := s + 'bool: ' + BoolToStr(cell.AsBoolean)
else if cell.IsError then s := s + 'error: ' + cell.ToString
else if cell.IsFormula then s := s + 'formula: ' + cell.AsFormula.Text;
aMemo.Lines.Add(s);
end;
end;
finally
xls.Free;
end;
end;
Key points:
ColCountInRow(row) combined with GetCellValueIndexed + ColFromIndex — this skips empty cells and is dramatically faster than a dense 1..ColCount loop.TCellValue is a discriminated-union record. Test with IsEmpty / IsString / IsNumber / IsBoolean / IsError / IsFormula, then extract with ToString / AsNumber / AsBoolean / AsFormula.uses
FlexCel.Core, FlexCel.XlsAdapter, FlexCel.Render;
procedure XlsxToPdf(const Source, Dest: string);
var
xls: TXlsFile;
pdf: TFlexCelPdfExport;
begin
xls := TXlsFile.Create(Source);
try
pdf := TFlexCelPdfExport.Create(xls);
try
pdf.Export(Dest); // one PDF covering all visible sheets
finally
pdf.Free;
end;
finally
xls.Free;
end;
end;
PDF export needs FlexCel.Render plus the platform-support unit in the main .dpr (the renderer uses the graphics engine for font measurement). For PDF/A, digital signatures, font embedding tuning, or multi-sheet bookmarks see references/pdf-html-export.md.
Assume an Excel template invoice-template.xlsx already exists, with tags like <#Customers.Name> inside a named range __Customers__ spanning the repeating row(s).
uses
FlexCel.Core, FlexCel.XlsAdapter, FlexCel.Report;
procedure RunReport(Customers: TDataSet);
var
report: TFlexCelReport;
begin
report := TFlexCelReport.Create(true); // true = case-insensitive tags
try
report.AddTable('Customers', Customers, TDisposeMode.DoNotDispose);
report.SetValue('ReportDate', Now);
report.SetValue('CompanyName', 'Acme Corp');
report.Run('invoice-template.xlsx', 'invoice-output.xlsx');
finally
report.Free;
end;
end;
To write the output straight to PDF, run the report into a TXlsFile and pipe it through TFlexCelPdfExport:
out := TXlsFile.Create;
try
report.Run('template.xlsx', out);
pdf := TFlexCelPdfExport.Create(out);
try pdf.Export('report.pdf'); finally pdf.Free end;
finally
out.Free;
end;
For the full tag language and template-design conventions see references/reports-cheatsheet.md.
uses)Always include FlexCel.Core in every unit that touches FlexCel types. Then add, per task:
| Task | Additional units |
|------|------------------|
| Platform graphics (main .dpr only) | FlexCel.VCLSupport / FlexCel.FMXSupport / FlexCel.LCLSupport / FlexCel.SKIASupport |
| Read / write xls/xlsx | FlexCel.XlsAdapter |
| PDF / HTML / image export, autofitting | FlexCel.Render |
| Low-level PDF access (sign, PDF/A options, standalone PDF) | FlexCel.Pdf |
| Template-based reports | FlexCel.Report |
SetCellValue(1, 1, ...) writes to A1. (XF format indices are 0-based.)Free TXlsFile, TFlexCelReport, TFlexCelPdfExport, etc. They're plain classes, not components. Use try..finally.ColCount — it scans the whole sheet. Use ColCountInRow(row) + GetCellValueIndexed + ColFromIndex..dpr only, not in every unit — it has no published types.GetCellValue returns the serial date; check the cell's number format to know it's a date.Load a reference file only when the task actually needs it — keeps your context lean.
references/api-cheatsheet.md — deeper TXlsFile usage: formatting, fonts, colors, merging, row/column sizing, comments, images, charts, data validation, protection, sheet management, streams.references/reports-cheatsheet.md — full tag reference, named-range conventions for bands, master-detail, config sheets, user functions, events.references/pdf-html-export.md — TFlexCelPdfExport and TFlexCelHtmlExport options: PDF/A, font embedding, digital signing, HTML5, image embedding.references/pitfalls.md — longer list of gotchas drawn from the official Tips section: locale, fonts on Docker/Linux, barcodes, tokens in formulas, strict xlsx, conditional formats, etc.The cheatsheets cover the common path. For anything deeper, fetch from the public documentation source:
https://raw.githubusercontent.com/tmssoftware/TMS-FlexCel.VCL-doc-src/main/<path>.md
guides/api-developer-guide.md, guides/reports-developer-guide.md, guides/reports-tag-reference.md, guides/pdf-exporting-guide.md, guides/html-exporting-guide.md, guides/performance-guide.mdtips/<topic>.md (one file per tip)api/FlexCel.XlsAdapter/TXlsFile/<MemberName>.md and similarhttps://doc.tmssoftware.com/flexcel/vcl/index.htmlhttps://github.com/tmssoftware/TMS-FlexCel.VCL-demosUse WebFetch on the raw markdown URL when you need to confirm a signature or pull an official example. Prefer the raw markdown over the rendered HTML.
try..finally..Free around every FlexCel object. Don't rely on interface reference counting — these are not interfaces.SetCellValue(1, 1, ...)) — do not pretend indices are 0-based.TFormula.Create('=...'), TCellValue) over implicit conversions when the intent is ambiguous..dpr block or mention it in a comment — otherwise rendering will fail at runtime with a missing-graphics-engine error.api/<unit>/<class>/<member>.md in the doc source, or tell the user to verify with APIMate.development
Use when writing C# / VB.NET / F# code that reads, writes, manipulates, or exports Excel (.xlsx / .xls) files, generates PDF or HTML from Excel, or produces data-driven reports with FlexCel Studio for .NET (TMS Software). Triggers include Excel/xlsx from C#, XlsFile, FlexCelReport, FlexCelPdfExport, FlexCelHtmlExport, FlexCelImgExport, ExcelFile, PdfWriter, .NET Excel export, ASP.NET Excel generation, .NET MAUI Excel, Native AOT + Excel, and Excel reporting from .NET.
testing
Save, load, update, delete, merge, and navigate entity objects using TMS Aurelius ORM (TObjectManager). Use when the user asks how to persist or retrieve data with Aurelius, manage object lifetime, work with associations or collections at runtime, handle transactions, use cached updates, or control concurrency. Does NOT cover query DSL or criteria/projections (those are in a separate skill). Triggers on requests like "save an entity with Aurelius", "load a customer from the database", "add items to a collection", "how do I update an object", "flush changes", "delete a record with Aurelius", "merge a transient object", "how do transactions work in Aurelius", "batch updates Aurelius".
testing
Map Delphi classes to a relational database using TMS Aurelius ORM attributes. Use when the user asks to create entity classes, add Aurelius mapping to existing classes, fix or review mapping attributes, explain how a class is mapped, or work with associations, inheritance, automapping, nullable fields, blobs, or composite identifiers. Triggers on requests like "create Aurelius entities for...", "map this class to Aurelius", "add ORM mapping", "fix the mapping on this class", "how do I map a one-to-many in Aurelius".
development
Maintainer-only workflow for handling GitHub Secret Scanning alerts on OpenClaw. Use when Codex needs to triage, redact, clean up, and resolve secret leakage found in issue comments, issue bodies, PR comments, or other GitHub content.