- Home
- Guides
- Power Automate
- How to mail merge with individual attachments using Power Automate and Excel
How to mail merge with individual attachments using Power Automate and Excel
Build an instant Power Automate flow that reads contacts from an Excel table, finds each person's own file in a OneDrive folder, and sends a personalized email with that file attached and an optional CC.
Jump to a step (14)
Sending a different invoice or document to each client usually means writing every email by hand and attaching the right file each time. Outlook's built-in mail merge cannot attach a separate file per recipient, so it is slow and easy to send the wrong file.
The contacts live in an Excel table with a column that holds each person's file name. The files themselves sit in a OneDrive folder. The flow loops through the contacts, searches the folder for the matching file, gets its content and sends one email per contact with merge fields for name, due date and amount.
It only uses Excel Online (Business), OneDrive for Business and Office 365 Outlook, which are all standard connectors. No SharePoint and no premium licence are needed. The flow sends an email only when it finds a file for that row.
What you need
- Microsoft 365 Business Basic or Standard with Outlook and Power Automate
- A OneDrive for Business folder with one file per recipient
- An Excel table in OneDrive with columns such as
Email,First Name,Due Date,Amount,AttachmentandCC
Step by step
0 of 14 done-
01
Prepare the files and the contact list
Put each recipient's file in one OneDrive folder. The video uses demo invoice PDFs, but any file type works. In an Excel Online workbook, list the contacts with an
Attachmentcolumn holding each person's file name.File names can be written with or without the extension. If two people have files with the same name but different extensions, include the extension so the search finds the right one.
-
02
Format the data as a table
Select all the data, choose Format as Table, make sure My table has headers is ticked and click OK. On the Table Design tab, rename the table (the video uses
ContactsData). The flow reads the data through this table. -
03
Fix date and currency columns
Power Automate ignores Excel's display format. A date column formatted as a date comes through as a serial number, and a currency column loses its symbol.
Format those columns as Text instead. For the currency column, copy the values into Notepad, set the column to Text, and paste the values back. The cells now hold text like
$250.00that the flow sends exactly as shown. -
04
Create an instant cloud flow
Open Power Automate at make.powerautomate.com. Go to Create, select Instant cloud flow, name it
Mail merge with separate attachments, choose Manually trigger a flow and click Create. An instant flow runs only when you press Run, which is what you want for a mail merge. -
05
Read the Excel table
Add
List rows present in a tablefrom Excel Online (Business). SetLocationtoOneDrive for Business,Document LibrarytoOneDrive, browse to the contacts workbook and select the table. -
06
Loop through the contacts
Add
Apply to eachfrom Control. For the input, pickbody/valuefromList rows present in a table. Rename this loopContacts. The name matters because the expressions later refer to it. -
07
Find each contact's file
Inside the loop, add
Find files in folderfrom OneDrive for Business.Search Query: theAttachmentcolumn (click See more if it is not listed)Folder: the folder with the attachmentsFile Search Mode:OneDrive Search
-
08
Add a second loop for the found file
Inside the first loop, add another
Apply to eachand set its input to the output ofFind files in folder. The search returns a list, so this loop handles the file it found. If no file is found, this loop does nothing and no email is sent for that contact. -
09
Get the file content
Inside the second loop, add
Get file contentfrom OneDrive for Business and setFiletoIdfromFind files in folder. This gives the flow the actual file to attach. -
10
Add the email action and template
Still inside the second loop, add
Send an email (V2)from Office 365 Outlook. Paste your email template into the body. The video uses a short invoice reminder with placeholders for first name, due date and amount. -
11
Fill the recipient and merge fields with expressions
Inside the nested loop, the dynamic content does not list the contact columns properly, and the Excel dynamic fields will not follow the
Contactsloop. Use expressions that point at the loop instead.In
To, switch to advanced mode and insert:items('Contacts')?['Email']Use the same pattern for the other fields:
- Subject:
items('Contacts')?['Due Date'] - Body:
items('Contacts')?['First Name'],items('Contacts')?['Due Date']anditems('Contacts')?['Amount']
The name inside the brackets must match your Excel header, including spaces. Capital letters do not matter.
- Subject:
-
12
Attach the file
Under Advanced parameters, add
Attachmentsand click Add new item.Attachments Name:NamefromFind files in folderAttachments Content:File contentfromGet file content
-
13
Add a CC from the table
In Advanced parameters, add
CC. Switch to advanced mode and insertitems('Contacts')?['CC']. Do the same withBCCif you have a BCC column. -
14
Save and run the flow
Save the flow, click Run, confirm the connections to OneDrive and Outlook, then click Continue and Run flow. Check your Sent Items. Each contact gets one email with their own attachment and their own name, due date and amount.
Tips and common problems
- Keep the contacts workbook in a different folder from the attachment files. If they share a folder, the file search can return the wrong file.
- Format date and currency columns as Text in Excel. Otherwise dates arrive as serial numbers and amounts lose their currency symbol.
- Rename the first loop to
Contactsbefore writing expressions, becauseitems('Contacts')must match the loop name. - No file found means no email. The flow only sends when
Find files in folderreturns a match for that row. - For a large list, you can add a
Delayaction afterSend an email (V2)to space out the emails.
Expressions used in this flow
| Field | Expression |
|---|---|
| To | items('Contacts')?['Email'] |
| Subject and body due date | items('Contacts')?['Due Date'] |
| First name | items('Contacts')?['First Name'] |
| Amount | items('Contacts')?['Amount'] |
| CC | items('Contacts')?['CC'] |
Quick version
The short version of this build covers the same idea in under a minute: copy the attachment files into a OneDrive folder, create an Excel Online file with the contacts and a file name column, read it in a new flow, loop through the rows, search for each file name in the folder, and when a file is found, get its content and send the email with the merge fields and the attachment. Watch the short.
There is also a newer, improved tutorial that covers more scenarios: watch it here.
Questions
Can Outlook mail merge send a different attachment to each person?
Not on its own. Power Automate can: read the contacts from Excel, find each person's file in OneDrive with Find files in folder, and attach it in Send an email (V2).
Why do I need expressions instead of the Excel dynamic content?
The email is inside a second loop, so the Excel columns do not follow the outer contacts loop. items('Contacts')?['Email'] reads the column from the current contact row.
Does this need SharePoint or a premium licence?
No. It uses Excel Online (Business), OneDrive for Business and Office 365 Outlook, which are all standard connectors available with Microsoft 365 business plans.
Can I add CC and BCC to a Power Automate mail merge?
Yes. Add columns for them in the Excel table, then set CC or BCC in Send an email (V2) to an expression such as items('Contacts')?['CC'].
