Interface IDocxMailMerge
- Namespace
- DocToolkit.Extensions.DependencyInjection
- Assembly
- DocToolkit.Extensions.DependencyInjection.dll
Fills a Word mail-merge template — a document carrying MERGEFIELD instructions — from a set
of named values. Registered by AddDocToolkit(IServiceCollection, Action<DocToolkitOptions>?).
public interface IDocxMailMerge
Remarks
Not IDocxEditor's placeholders and not IDocxForm's content
controls. The difference is who authored the template: {{placeholder}} is a convention
this library invented, a MERGEFIELD is what Word writes from Insert → Merge Field,
and a content control is a named region Word protects. A caller has whichever one their document
was built with.
Methods
InspectTemplate(byte[])
Reads what docx asks for, without merging anything.
DocxMailMergeTemplate InspectTemplate(byte[] docx)
Parameters
docxbyte[]The template to read.
Returns
Exceptions
- ArgumentNullException
docxis null.- ArgumentException
docxis empty.- DocumentConversionException
It could not be opened or read.
InspectTemplateAsync(Stream, CancellationToken)
Reads what docx asks for, without merging anything.
Task<DocxMailMergeTemplate> InspectTemplateAsync(Stream source, CancellationToken ct = default)
Parameters
sourceStreamThe template to read. Read to its end; never disposed or sought.
ctCancellationTokenCancels before the document is read.
Returns
Merge(byte[], IReadOnlyDictionary<string, string>)
A copy of docx with every merge field filled.
byte[] Merge(byte[] docx, IReadOnlyDictionary<string, string> values)
Parameters
docxbyte[]The template to fill.
valuesIReadOnlyDictionary<string, string>The value for each field, matched case-insensitively.
Returns
- byte[]
Remarks
Refuses to produce a document with an unfilled field, naming every one. Measured: an
unfilled field survives as a live field and the document reads «Balance» — valid,
opening cleanly, and looking finished. Use
MergeWithReport(byte[], IReadOnlyDictionary<string, string>) when you want it
anyway.
Exceptions
- ArgumentNullException
An argument is null.
- ArgumentException
docxis empty, or a value is null.- DocumentConversionException
A field received no value, or the document could not be read or written.
MergeAsync(Stream, Stream, IReadOnlyDictionary<string, string>, CancellationToken)
A copy of docx with every merge field filled.
Task MergeAsync(Stream source, Stream destination, IReadOnlyDictionary<string, string> values, CancellationToken ct = default)
Parameters
sourceStreamThe template to fill. Read to its end; never disposed or sought.
destinationStreamReceives the filled document. Written; never disposed or sought.
valuesIReadOnlyDictionary<string, string>The value for each field, matched case-insensitively.
ctCancellationTokenCancels before the document is read, and while it is written.
Returns
MergeBatch(byte[], IEnumerable<IReadOnlyDictionary<string, string>>)
Fills docx once per entry in records, yielding each
filled document in order. Strict — refuses the moment a record is incomplete, mid-sequence;
everything already yielded before that point is unaffected.
IEnumerable<byte[]> MergeBatch(byte[] docx, IEnumerable<IReadOnlyDictionary<string, string>> records)
Parameters
docxbyte[]The template to fill, once per record.
recordsIEnumerable<IReadOnlyDictionary<string, string>>One dictionary of values per output document, matched case-insensitively. An empty sequence yields no documents.
Returns
- IEnumerable<byte[]>
Exceptions
- ArgumentNullException
docxorrecordsis null, or an individual record inrecordsis null.- ArgumentException
docxis empty, or a record's value is null.- DocumentConversionException
The package could not be read or written, or a record is missing a value for a field the template requires — the message names the record's position (0-based) and the missing field(s).
MergeBatchAsync(byte[], IEnumerable<IReadOnlyDictionary<string, string>>, CancellationToken)
Fills docx once per entry in records, yielding each
filled document in order. Strict — refuses the moment a record is incomplete, mid-sequence;
everything already yielded before that point is unaffected.
IAsyncEnumerable<byte[]> MergeBatchAsync(byte[] docx, IEnumerable<IReadOnlyDictionary<string, string>> records, CancellationToken ct = default)
Parameters
docxbyte[]The template to fill, once per record.
recordsIEnumerable<IReadOnlyDictionary<string, string>>One dictionary of values per output document, matched case-insensitively. An empty sequence yields no documents.
ctCancellationTokenCancels before the next record's merge runs.
Returns
Remarks
Argument validation is not thrown until the caller starts enumerating the result — inherent to how an IAsyncEnumerable<T> iterator method defers its whole body.
MergeBatchWithReport(byte[], IEnumerable<IReadOnlyDictionary<string, string>>)
Fills docx once per entry in records, yielding each
record's document together with what happened to every field in it. The lenient
half of the pair — always produces a document for every record, complete or not, and never
throws for an incomplete one.
IEnumerable<DocxMailMergeBatchItem> MergeBatchWithReport(byte[] docx, IEnumerable<IReadOnlyDictionary<string, string>> records)
Parameters
docxbyte[]The template to fill, once per record.
recordsIEnumerable<IReadOnlyDictionary<string, string>>One dictionary of values per output document, matched case-insensitively. An empty sequence yields no items.
Returns
Exceptions
- ArgumentNullException
docxorrecordsis null, or an individual record inrecordsis null.- ArgumentException
docxis empty, or a record's value is null.- DocumentConversionException
The package could not be read or written.
MergeBatchWithReportAsync(byte[], IEnumerable<IReadOnlyDictionary<string, string>>, CancellationToken)
Fills docx once per entry in records, yielding each
record's document together with what happened to every field in it. The lenient
half of the pair — always produces a document for every record, complete or not, and never
throws for an incomplete one.
IAsyncEnumerable<DocxMailMergeBatchItem> MergeBatchWithReportAsync(byte[] docx, IEnumerable<IReadOnlyDictionary<string, string>> records, CancellationToken ct = default)
Parameters
docxbyte[]The template to fill, once per record.
recordsIEnumerable<IReadOnlyDictionary<string, string>>One dictionary of values per output document, matched case-insensitively. An empty sequence yields no items.
ctCancellationTokenCancels before the next record's merge runs.
Returns
Remarks
Argument validation is not thrown until the caller starts enumerating the result — the same IAsyncEnumerable<T> deferral MergeBatchAsync(byte[], IEnumerable<IReadOnlyDictionary<string, string>>, CancellationToken) has.
MergeConditional(byte[], IReadOnlyDictionary<string, bool>)
A copy of docx with every conditional block resolved, refusing if the
template asks for a condition conditions did not supply.
byte[] MergeConditional(byte[] docx, IReadOnlyDictionary<string, bool> conditions)
Parameters
docxbyte[]The template to resolve.
conditionsIReadOnlyDictionary<string, bool>Whether to include each named block.
Returns
- byte[]
Exceptions
- ArgumentNullException
An argument is null.
- ArgumentException
docxis empty.- DocumentConversionException
A condition the template asks for was not supplied, the marker structure is unbalanced, or the document could not be read or written.
MergeConditionalAsync(Stream, Stream, IReadOnlyDictionary<string, bool>, CancellationToken)
A copy of docx with every conditional block resolved, refusing if the
template asks for a condition conditions did not supply.
Task MergeConditionalAsync(Stream source, Stream destination, IReadOnlyDictionary<string, bool> conditions, CancellationToken ct = default)
Parameters
sourceStreamThe template to resolve. Read to its end; never disposed or sought.
destinationStreamReceives the resolved document. Written; never disposed or sought.
conditionsIReadOnlyDictionary<string, bool>Whether to include each named block.
ctCancellationTokenCancels before the document is read, and while it is written.
Returns
MergeConditionalWithReport(byte[], IReadOnlyDictionary<string, bool>)
A copy of docx with every conditional block resolved, together with
which condition names the template asked for that conditions did not
supply. Never refuses for a missing name — an unsupplied condition defaults to
false.
DocxMailMergeBlockResult MergeConditionalWithReport(byte[] docx, IReadOnlyDictionary<string, bool> conditions)
Parameters
docxbyte[]The template to resolve.
conditionsIReadOnlyDictionary<string, bool>Whether to include each named block.
Returns
Exceptions
- ArgumentNullException
An argument is null.
- ArgumentException
docxis empty.- DocumentConversionException
The marker structure is unbalanced, or the document could not be read or written.
MergeConditionalWithReportAsync(Stream, Stream, IReadOnlyDictionary<string, bool>, CancellationToken)
A copy of docx with every conditional block resolved, together with
which condition names the template asked for that conditions did not
supply. Never refuses for a missing name — an unsupplied condition defaults to
false.
Task<DocxMailMergeBlockReport> MergeConditionalWithReportAsync(Stream source, Stream destination, IReadOnlyDictionary<string, bool> conditions, CancellationToken ct = default)
Parameters
sourceStreamThe template to resolve. Read to its end; never disposed or sought.
destinationStreamReceives the resolved document. Written; never disposed or sought.
conditionsIReadOnlyDictionary<string, bool>Whether to include each named block.
ctCancellationTokenCancels before the document is read, and while it is written.
Returns
Remarks
Returns the report alone, because the document went to destination.
MergeRepeating(byte[], IReadOnlyDictionary<string, IEnumerable<IReadOnlyDictionary<string, string>>>)
A copy of docx with every repeating block ({{#each Name}} …
{{/each Name}}) expanded once per entry in its region, refusing if the template asks
for a region regions did not supply.
byte[] MergeRepeating(byte[] docx, IReadOnlyDictionary<string, IEnumerable<IReadOnlyDictionary<string, string>>> regions)
Parameters
docxbyte[]The template to expand.
regionsIReadOnlyDictionary<string, IEnumerable<IReadOnlyDictionary<string, string>>>One sequence of value sets per named repeating region.
Returns
- byte[]
Exceptions
- ArgumentNullException
An argument is null, or an individual record in it is null.
- ArgumentException
docxis empty, or a record's value is null.- DocumentConversionException
A region the template asks for was not supplied, the marker structure is unbalanced, or the document could not be read or written.
MergeRepeatingAsync(Stream, Stream, IReadOnlyDictionary<string, IEnumerable<IReadOnlyDictionary<string, string>>>, CancellationToken)
A copy of docx with every repeating block ({{#each Name}} …
{{/each Name}}) expanded once per entry in its region, refusing if the template asks
for a region regions did not supply.
Task MergeRepeatingAsync(Stream source, Stream destination, IReadOnlyDictionary<string, IEnumerable<IReadOnlyDictionary<string, string>>> regions, CancellationToken ct = default)
Parameters
sourceStreamThe template to expand. Read to its end; never disposed or sought.
destinationStreamReceives the expanded document. Written; never disposed or sought.
regionsIReadOnlyDictionary<string, IEnumerable<IReadOnlyDictionary<string, string>>>One sequence of value sets per named repeating region.
ctCancellationTokenCancels before the document is read, and while it is written.
Returns
MergeRepeatingRegions(byte[], IReadOnlyDictionary<string, IEnumerable<DocxMailMergeBlockData>>)
The nested-region twin of MergeRepeating(byte[], IReadOnlyDictionary<string, IEnumerable<IReadOnlyDictionary<string, string>>>) — each entry may itself carry further nested regions, for a template whose repeating blocks are nested inside one another.
byte[] MergeRepeatingRegions(byte[] docx, IReadOnlyDictionary<string, IEnumerable<DocxMailMergeBlockData>> regions)
Parameters
docxbyte[]The template to expand.
regionsIReadOnlyDictionary<string, IEnumerable<DocxMailMergeBlockData>>One sequence of block rows per named top-level repeating region.
Returns
- byte[]
Exceptions
- ArgumentNullException
An argument is null, or an individual block row in it is null.
- ArgumentException
docxis empty, or a block row's value is null.- DocumentConversionException
A region the template asks for was not supplied at any nesting level, the marker structure is unbalanced, or the document could not be read or written.
MergeRepeatingRegionsAsync(Stream, Stream, IReadOnlyDictionary<string, IEnumerable<DocxMailMergeBlockData>>, CancellationToken)
The nested-region twin of MergeRepeating(byte[], IReadOnlyDictionary<string, IEnumerable<IReadOnlyDictionary<string, string>>>) — each entry may itself carry further nested regions, for a template whose repeating blocks are nested inside one another.
Task MergeRepeatingRegionsAsync(Stream source, Stream destination, IReadOnlyDictionary<string, IEnumerable<DocxMailMergeBlockData>> regions, CancellationToken ct = default)
Parameters
sourceStreamThe template to expand. Read to its end; never disposed or sought.
destinationStreamReceives the expanded document. Written; never disposed or sought.
regionsIReadOnlyDictionary<string, IEnumerable<DocxMailMergeBlockData>>One sequence of block rows per named top-level repeating region.
ctCancellationTokenCancels before the document is read, and while it is written.
Returns
MergeRepeatingRegionsWithReport(byte[], IReadOnlyDictionary<string, IEnumerable<DocxMailMergeBlockData>>)
A copy of docx with every nested repeating region expanded, together
with which region names the template asked for — at any nesting level — that
regions did not supply. An unsupplied region, at any level, defaults
to zero rows rather than refusing.
DocxMailMergeBlockResult MergeRepeatingRegionsWithReport(byte[] docx, IReadOnlyDictionary<string, IEnumerable<DocxMailMergeBlockData>> regions)
Parameters
docxbyte[]The template to expand.
regionsIReadOnlyDictionary<string, IEnumerable<DocxMailMergeBlockData>>One sequence of block rows per named top-level repeating region.
Returns
Exceptions
- ArgumentNullException
An argument is null, or an individual block row in it is null.
- ArgumentException
docxis empty, or a block row's value is null.- DocumentConversionException
The marker structure is unbalanced, or the document could not be read or written.
MergeRepeatingRegionsWithReportAsync(Stream, Stream, IReadOnlyDictionary<string, IEnumerable<DocxMailMergeBlockData>>, CancellationToken)
A copy of docx with every nested repeating region expanded, together
with which region names the template asked for — at any nesting level — that
regions did not supply. An unsupplied region, at any level, defaults
to zero rows rather than refusing.
Task<DocxMailMergeBlockReport> MergeRepeatingRegionsWithReportAsync(Stream source, Stream destination, IReadOnlyDictionary<string, IEnumerable<DocxMailMergeBlockData>> regions, CancellationToken ct = default)
Parameters
sourceStreamThe template to expand. Read to its end; never disposed or sought.
destinationStreamReceives the expanded document. Written; never disposed or sought.
regionsIReadOnlyDictionary<string, IEnumerable<DocxMailMergeBlockData>>One sequence of block rows per named top-level repeating region.
ctCancellationTokenCancels before the document is read, and while it is written.
Returns
Remarks
Returns the report alone, because the document went to destination.
MergeRepeatingWithReport(byte[], IReadOnlyDictionary<string, IEnumerable<IReadOnlyDictionary<string, string>>>)
A copy of docx with every repeating block expanded, together with
which region names the template asked for that regions did not supply.
An unsupplied region defaults to zero rows rather than refusing.
DocxMailMergeBlockResult MergeRepeatingWithReport(byte[] docx, IReadOnlyDictionary<string, IEnumerable<IReadOnlyDictionary<string, string>>> regions)
Parameters
docxbyte[]The template to expand.
regionsIReadOnlyDictionary<string, IEnumerable<IReadOnlyDictionary<string, string>>>One sequence of value sets per named repeating region.
Returns
Exceptions
- ArgumentNullException
An argument is null, or an individual record in it is null.
- ArgumentException
docxis empty, or a record's value is null.- DocumentConversionException
The marker structure is unbalanced, or the document could not be read or written.
MergeRepeatingWithReportAsync(Stream, Stream, IReadOnlyDictionary<string, IEnumerable<IReadOnlyDictionary<string, string>>>, CancellationToken)
A copy of docx with every repeating block expanded, together with
which region names the template asked for that regions did not supply.
An unsupplied region defaults to zero rows rather than refusing.
Task<DocxMailMergeBlockReport> MergeRepeatingWithReportAsync(Stream source, Stream destination, IReadOnlyDictionary<string, IEnumerable<IReadOnlyDictionary<string, string>>> regions, CancellationToken ct = default)
Parameters
sourceStreamThe template to expand. Read to its end; never disposed or sought.
destinationStreamReceives the expanded document. Written; never disposed or sought.
regionsIReadOnlyDictionary<string, IEnumerable<IReadOnlyDictionary<string, string>>>One sequence of value sets per named repeating region.
ctCancellationTokenCancels before the document is read, and while it is written.
Returns
Remarks
Returns the report alone, because the document went to destination.
MergeTableRowGroups(byte[], int, int, int, IEnumerable<DocxMailMergeTableRowGroup>)
A copy of docx with a group/header row and its detail row template, both
in the table at tableIndex, repeated once per group in
groups. Index-based, like MergeTableRows(byte[], int, int, IEnumerable<IReadOnlyDictionary<string, string>>); no strict/lenient
split.
byte[] MergeTableRowGroups(byte[] docx, int tableIndex, int groupTemplateRowIndex, int detailTemplateRowIndex, IEnumerable<DocxMailMergeTableRowGroup> groups)
Parameters
docxbyte[]The template to expand.
tableIndexintZero-based index of the table, in document order.
groupTemplateRowIndexintZero-based row index of the group/header row template.
detailTemplateRowIndexintZero-based row index of the detail row template.
groupsIEnumerable<DocxMailMergeTableRowGroup>One group/header value set, with its detail rows, per generated group.
Returns
- byte[]
Exceptions
- ArgumentNullException
An argument is null, or an individual group or detail row in it is null.
- ArgumentException
docxis empty, or a group or detail row's value is null.- DocumentConversionException
tableIndex,groupTemplateRowIndexordetailTemplateRowIndexis out of range, or the document could not be read or written.
MergeTableRowGroupsAsync(Stream, Stream, int, int, int, IEnumerable<DocxMailMergeTableRowGroup>, CancellationToken)
A copy of docx with a group/header row and its detail row template, both
in the table at tableIndex, repeated once per group in
groups. Index-based, like MergeTableRows(byte[], int, int, IEnumerable<IReadOnlyDictionary<string, string>>); no strict/lenient
split.
Task MergeTableRowGroupsAsync(Stream source, Stream destination, int tableIndex, int groupTemplateRowIndex, int detailTemplateRowIndex, IEnumerable<DocxMailMergeTableRowGroup> groups, CancellationToken ct = default)
Parameters
sourceStreamThe template to expand. Read to its end; never disposed or sought.
destinationStreamReceives the expanded document. Written; never disposed or sought.
tableIndexintZero-based index of the table, in document order.
groupTemplateRowIndexintZero-based row index of the group/header row template.
detailTemplateRowIndexintZero-based row index of the detail row template.
groupsIEnumerable<DocxMailMergeTableRowGroup>One group/header value set, with its detail rows, per generated group.
ctCancellationTokenCancels before the document is read, and while it is written.
Returns
MergeTableRows(byte[], int, int, IEnumerable<IReadOnlyDictionary<string, string>>)
A copy of docx with the row at templateRowIndex in the
table at tableIndex repeated once per entry in rows.
Index-based rather than marker-based — no strict/lenient split, since there is no name that
could go unsupplied.
byte[] MergeTableRows(byte[] docx, int tableIndex, int templateRowIndex, IEnumerable<IReadOnlyDictionary<string, string>> rows)
Parameters
docxbyte[]The template to expand.
tableIndexintZero-based index of the table, in document order.
templateRowIndexintZero-based row index within that table to clone and bind.
rowsIEnumerable<IReadOnlyDictionary<string, string>>One value set per generated row.
Returns
- byte[]
Exceptions
- ArgumentNullException
An argument is null, or an individual row in it is null.
- ArgumentException
docxis empty, or a row's value is null.- DocumentConversionException
tableIndexortemplateRowIndexis out of range, or the document could not be read or written.
MergeTableRowsAsync(Stream, Stream, int, int, IEnumerable<IReadOnlyDictionary<string, string>>, CancellationToken)
A copy of docx with the row at templateRowIndex in the
table at tableIndex repeated once per entry in rows.
Index-based rather than marker-based — no strict/lenient split, since there is no name that
could go unsupplied.
Task MergeTableRowsAsync(Stream source, Stream destination, int tableIndex, int templateRowIndex, IEnumerable<IReadOnlyDictionary<string, string>> rows, CancellationToken ct = default)
Parameters
sourceStreamThe template to expand. Read to its end; never disposed or sought.
destinationStreamReceives the expanded document. Written; never disposed or sought.
tableIndexintZero-based index of the table, in document order.
templateRowIndexintZero-based row index within that table to clone and bind.
rowsIEnumerable<IReadOnlyDictionary<string, string>>One value set per generated row.
ctCancellationTokenCancels before the document is read, and while it is written.
Returns
MergeWithReport(byte[], IReadOnlyDictionary<string, string>)
A copy of docx with every merge field filled, together with what
happened to each one. Always produces a document, complete or not.
DocxMailMergeResult MergeWithReport(byte[] docx, IReadOnlyDictionary<string, string> values)
Parameters
docxbyte[]The template to fill.
valuesIReadOnlyDictionary<string, string>The value for each field, matched case-insensitively.
Returns
Exceptions
- ArgumentNullException
An argument is null.
- ArgumentException
docxis empty, or a value is null.- DocumentConversionException
It could not be read or written.
MergeWithReportAsync(Stream, Stream, IReadOnlyDictionary<string, string>, CancellationToken)
A copy of docx with every merge field filled, together with what
happened to each one. Always produces a document, complete or not.
Task<DocxMailMergeReport> MergeWithReportAsync(Stream source, Stream destination, IReadOnlyDictionary<string, string> values, CancellationToken ct = default)
Parameters
sourceStreamThe template to fill. Read to its end; never disposed or sought.
destinationStreamReceives the filled document. Written; never disposed or sought.
valuesIReadOnlyDictionary<string, string>The value for each field, matched case-insensitively.
ctCancellationTokenCancels before the document is read, and while it is written.
Returns
Remarks
Returns the report alone, because the document went to destination.