đź’ˇ Full working example available on GitHub: convert-email-and-attachments-to-pdf-dotnet
Email-to-PDF conversion is a GroupDocs.Conversion workflow for .NET that turns an Outlook message and its attachments into one or more PDF files without one attachment overwriting another or one unsupported file breaking the whole run. It replaces a manual export-and-rename routine with a few lines of code that know, for every item, where it came from and whether it converted at all.
The Old Way Was Painful
Imagine a support inbox where every case e-mail carries two or three
attachments - a report here, a screenshot there, sometimes a file format
nobody on the team recognizes. Nothing about that is unusual. Filing that
case means opening the message,
saving each attachment by hand, renaming the ones that collide because two
systems both exported a file called report.csv, and hoping nothing in the
set is a format your PDF viewer cannot open either. Do that fifty times a
week and the “quick export” becomes the slowest part of the job, and the
part most likely to be rushed, which is exactly when mistakes happen.
Doing this by hand does not just cost time - it is also where files quietly
go missing. Save two attachments both named report.csv into the same
folder without renaming them first, and the second save overwrites the
first; nobody notices until the September numbers are nowhere to be found.
A message with even one attachment in a format nobody has a converter for
can stall the whole export until someone decides what to do with it.
The real cost of doing it manually: a renamed-and-overwritten attachment does not throw an error - it just silently disappears, and the case file looks complete until someone needs the data that was in it.
There’s a Better Way
GroupDocs.Conversion for .NET turns this into a few lines of code. No
manual renaming is needed. Its
EmailLoadOptions class controls whether the message, the attachments, or
both get converted, and a SaveContext callback describes every output item
well enough that two attachments named report.csv never collide and an
attachment with no route to PDF never stops the rest of the run. Every call
to that callback reports ItemIndex (a running count starting at 1),
HierarchyLevel (0 for the message, 1 for an attachment) and
SourceFileName (the original file name), which is enough context to build
a collision-free output name without writing any extra bookkeeping.
Before we start, you’ll need:
- .NET SDK 8.0 or later
- GroupDocs.Conversion for .NET 26.10.0 (get a temporary license to remove evaluation limits)
- An Outlook
.msgor.emlmessage to convert
Install with one command:
dotnet add package GroupDocs.Conversion --version 26.10.0
The New Way: Converting a Message and Its Attachments
Here’s what the same task looks like with GroupDocs.Conversion. The following example converts an Outlook message and every one of its attachments into its own PDF, with file names that never collide.
Step 1 - Decide What to Convert
EmailLoadOptions.ConvertOwner and ConvertOwned independently switch the
message and its attachments on or off; Depth (default 2) limits how far
nested attachments are followed.
// Convert the message itself and every attachment it carries
var loadOptions = new EmailLoadOptions
{
ConvertOwner = true,
ConvertOwned = true,
Depth = 2
};
Step 2 - Name Every Output From SaveContext
Pass a SaveContext callback to Converter.Convert instead of a fixed
output path. The callback fires once per item, with ItemIndex unique per
item even when two attachments share a file name.
using (var converter = new Converter(messagePath, (LoadContext _) => loadOptions))
{
converter.Convert((SaveContext item) =>
{
// ItemIndex is 1 for the message, then counts up per attachment
string name = $"{item.ItemIndex:D2}-{item.SourceFileName}.pdf";
return File.Create(Path.Combine(outputFolder, name));
}, new PdfConvertOptions());
}
Step 3 - Handle Attachments With No PDF Route
Not every attachment can become a PDF. Check SaveContext.TargetFormat
against FileType.Unknown and save that one item under its own name instead
of converting it.
converter.Convert((SaveContext item) =>
{
bool passedThrough = item.TargetFormat == FileType.Unknown;
string baseName = $"{item.ItemIndex:D2}-{item.SourceFileName}";
string name = passedThrough
? baseName
: $"{baseName}.{item.TargetFormat.Extension}";
return File.Create(Path.Combine(outputFolder, name));
}, new PdfConvertOptions());
Point this code at a sample support e-mail with two attachments both named
report.csv and one attachment in an unsupported format. Three PDFs come
out: the message and both CSV reports. The unsupported file comes out too,
untouched - open it next to the original and every one of its 32 bytes
lines up.
How do I avoid overwriting attachments that share a file name?
A file name on its own cannot serve as a safe key for the output, because
two attachments can carry the exact same one. Fold SaveContext.ItemIndex
into the name together with SaveContext.SourceFileName, and two
attachments named report.csv stop competing for the same slot on disk;
each gets its own zero-padded prefix (02- and 03- in the sample, after
the message’s 01-) and its own file, whatever name the source used.
Side-by-Side: Before vs. After
| Before (Manual) | After (GroupDocs.Conversion) | |
|---|---|---|
| Time | Minutes per message, by hand | A few lines of code, any number of messages |
| Duplicate names | Silently overwritten | Kept separate via ItemIndex |
| Unsupported attachment | Breaks the whole conversion (pre-26.10) | Saved under its own name, run continues |
| Output | Whatever your PDF viewer could save | Structured PDFs you can file or index |
The sample’s support e-mail is built from exactly that mix: two monthly CSV exports with the same name, and one capture file no converter recognizes.
Real-World Example: Support Case Archiving
A support team logs every customer case as an e-mail with one or more
spreadsheet attachments, and the case-tracking system needs each attachment
filed as its own searchable PDF, separate from the message. Running the
message through KeepAttachmentsWithoutPdfRoute once per incoming case
turns the message and its attachments into a numbered set of files, with
no attachment ever overwriting another even when two reports share a
name. A case e-mail with two monthly report.csv exports and one capture
file in a format nobody converts comes out as four files: the message,
both CSV reports as PDFs, and the capture file saved under its own name -
nothing dropped, nothing merged, nothing silently overwritten.
// One call per case e-mail - no manual export, no renamed duplicates
int kept = KeepAttachmentsWithoutPdfRoute(caseMessagePath, caseOutputFolder);
What Else Can You Do with GroupDocs.Conversion for .NET?
Beyond splitting a message from its attachments, EmailLoadOptions covers
more of the message itself:
- Field visibility: show or hide the header and its
From,To,CcandBcclines withDisplayHeaderand the relatedDisplay*options (CcandBccare hidden by default). - Localized headers: map each
EmailFieldto a different caption withFieldTextMap, for example translatingSubjectandAttachmentsinto another language. - Date formatting: the
Sentline follows the culture of the machine that runs the conversion, andTimeZoneOffsetsets the UTC offset used for the message dates. - Message-only output: set
ConvertOwnedtofalsewhen the PDF only needs to stand in for the message, with attachment names still listed in the header for reference.
See the full EmailLoadOptions reference for every option.
Conclusion
What used to mean opening a message, saving attachments by hand, and
re-checking for overwritten duplicates now takes a SaveContext callback
and a few lines of code. GroupDocs.Conversion for .NET gives every output
item - the message and each attachment - a name that never collides, and
keeps an attachment with no PDF route instead of failing the run. The same
three building blocks - ConvertOwner, ConvertOwned and the
SaveContext callback - scale from a single summary PDF up to a full,
collision-safe breakdown of a message and every attachment it carries, so
you can start small and grow into the full workflow as your inbox demands it.
Ready to automate your e-mail-to-PDF workflow?
- Try a free temporary license
- Explore converting each email attachment to a different output format
- Read the full EmailLoadOptions reference
- Check out the sample project on GitHub