Custom Export Formats
The export system is intentionally extensible. FdcExportFormat is a const value object rather than an enum, so applications and add-on packages can define new formats without modifying the Community package.
1. Define the format
const markdownTable = FdcExportFormat(
'markdownTable',
label: 'Markdown',
fileExtension: 'md',
mimeType: 'text/markdown',
);
Choose a stable id. Equality is based on format identity metadata rather than the optional icon.
2. Implement a writer
class MarkdownTableWriter implements FdcExportWriter {
const MarkdownTableWriter();
@override
FdcExportPayload write(FdcExportWriterContext context) {
final buffer = StringBuffer();
if (context.options.includeHeaders) {
buffer.writeln(
'| ${context.columns.map(context.headerFor).join(' | ')} |',
);
buffer.writeln(
'| ${context.columns.map((_) => '---').join(' | ')} |',
);
}
for (final row in context.rows) {
final values = context.columns.map(
(column) => context.displayTextFor(row, column),
);
buffer.writeln('| ${values.join(' | ')} |');
}
return FdcTextExportPayload(buffer.toString());
}
}
The exporter has already resolved row scope and column order before write is called. Writers should focus on serialization.
FdcExportWriterContext provides helpers for common format models:
valueFor(row, column)for source values,displayTextFor(row, column)for presentation text,keyFor(column)for object-oriented output keys,elementNameFor(column)for XML-style names,headerFor(column)for tabular headers.
3. Register the writer
FdcExportRegistry.register(
markdownTable,
const MarkdownTableWriter(),
);
Now direct export can resolve the writer automatically:
final result = await FdcExporter.exportDataSet(
orders,
format: markdownTable,
);
Registered formats are also discovered by the grid export button's effective format list.
Passing a writer directly
Registration is optional when a one-off export already has the writer instance:
final result = await FdcExporter.exportDataSet(
orders,
format: markdownTable,
writer: const MarkdownTableWriter(),
);
Use the registry for application-wide or package-level format integrations. Pass a writer directly for localized or dynamically configured export flows.
Writer-specific options
Define a strongly typed options object by extending FdcExportWriterOptions:
final class MarkdownExportOptions extends FdcExportWriterOptions {
const MarkdownExportOptions({this.alignNumbers = true});
final bool alignNumbers;
}
Pass it through the exporter:
await FdcExporter.exportDataSet(
orders,
format: markdownTable,
writerOptions: const MarkdownExportOptions(),
);
The writer reads and validates context.writerOptions.
Cross-format settings belong in FdcExportOptions; writer-specific settings belong in an FdcExportWriterOptions subtype.
Text and binary payloads
Return text:
return FdcTextExportPayload(content);
Return binary bytes:
return FdcBinaryExportPayload(bytes);
Consumers can always read FdcExportResult.bytes, regardless of payload type.
Custom visual styles
Presentation-oriented formats can define a style type extending FdcExportFormatStyle and place defaults in FdcExportStyle.formats:
FdcExportStyle(
formats: {
markdownTable: markdownStyle,
},
)
The writer can resolve the style with:
final style = context.exportStyle.styleFor<MyExportStyle>(
context.format,
);
This is the same extension model used by application/subtree export defaults.