Build Eye-Catching HTML Table Emails with Power Automate
Learn how to automatically create a styled HTML table from SharePoint data and embed it in an email, using basic Power Automate actions and a pinch of CSS.
Sending an automated email with a table of data is a common request, but a plain HTML table can look dull. Fortunately, Power Automate makes it straightforward to combine the Create HTML Table action with a small block of CSS to produce an attractive, formatted table that your recipients will actually enjoy reading. In this guide we'll walk through a real-world example using SharePoint as the data source, and you'll see how to style, format, and email the table in just a few actions.
Scenario: Weekly Project Status Summary
Imagine you manage a portfolio of projects and need to send a weekly status report to stakeholders. You maintain a SharePoint list called Project Tracker with these columns:
- ProjectName (single line of text)
- Status (choice – On Track / At Risk / Delayed)
- Progress (number - percentage)
- Deadline (date only)
- Owner (person or group)
At the end of each week you want an email that shows a clean, colour‑coded table of every project, with proper formatting for the progress and deadline columns.
Step 1: Prepare the SharePoint List
Create the list and populate it with sample data. For example:
| ProjectName | Status | Progress | Deadline | Owner |
|---|---|---|---|---|
| Cloud Migration | On Track | 65 | 2026-07-15 | Alice |
| Mobile App Revamp | At Risk | 30 | 2026-06-30 | Bob |
| Compliance Update | Delayed | 20 | 2026-05-01 | Carol |
| Data Warehouse | On Track | 80 | 2026-08-01 | Dave |
The list can hold many more items; we'll only select the columns we need later.
Step 2: Build the Flow
Open the Power Automate designer and create a Scheduled cloud flow that runs weekly. Add these actions:
2.1 Get Items from the SharePoint list
Use the SharePoint – Get items action and point it to your Project Tracker list. If your list may grow large, consider setting a pagination limit (e.g., 1000 items) and later handle pagination with a Apply to each – but for simplicity we'll assume the list stays small.
2.2 Select the columns you want to display
The Get items action returns all columns, most of which you don't want in the email. Insert a Data Operations – Select action and map only the four columns you need. In the From field use the output of Get items. In the Map section define:
- Title (or use your own key) –
item()?['ProjectName'] - Status –
item()?['Status'] - Progress –
item()?['Progress'] - Deadline –
item()?['Deadline']
Leave the Owner column out for now to keep the table uncluttered.
2.3 Create the HTML Table
Add a Data Operations – Create HTML table action. Point its From field to the output of the Select action. This action will produce a raw HTML table element.
2.4 Apply Custom CSS with a Compose Action
Create a Data Operations – Compose action and paste the following CSS inside it. (You can generate similar CSS with the DivTable table styler tool or write your own.)
<style>
table {
border-collapse: collapse;
width: 100%;
font-family: 'Segoe UI', Arial, sans-serif;
font-size: 14px;
}
th, td {
border: 1px solid #cccccc;
padding: 8px 12px;
text-align: left;
}
th {
background-color: #2c3e50;
color: #ffffff;
font-weight: 600;
}
tr:nth-child(even) {
background-color: #f4f6f8;
}
</style>Note: The <style> tags are essential – the email body must contain them for the styling to be applied. You can adjust the colours, font, or spacing as needed.
2.5 Combine the Table and CSS in the Email Body
Add an Office 365 Outlook – Send an email (V2) action. Choose the desired recipient(s) and set a subject like "Weekly Project Status Update".
Switch the email body to Code View (click the </> icon) and insert the following:
@{outputs('Compose')}
@{outputs('Create_HTML_table')}The Compose output holds your CSS (including the <style> block), and the Create HTML table output is the actual table markup. When rendered together, the email will show a styled table.
Your flow should now look like this:
Get Items → Select → Create HTML Table → Compose (CSS) → Send Email
Step 3: Format Data for Better Readability
The Select action is the perfect place to transform raw values.
Format a Date Column
Assuming Deadline returns a date string like 2026-07-15, use the formatDateTime expression to display it in a friendlier format:
formatDateTime(item()?['Deadline'], 'MMM dd, yyyy')
This will turn 2026-07-15 into Jul 15, 2026.
Format a Number Column
For Progress (which is a number), use formatNumber to add a percentage sign:
formatNumber(item()?['Progress'], '#0"%"')
Alternatively, if you want a decimal or currency style, you can adapt the pattern (e.g., "$#,##0.00" for currency). The key is to keep the format string consistent with your locale.
After these changes, run your flow and check the email. The dates and percentages should appear exactly as specified.
Tips & Considerations
- Pagination: If your SharePoint list contains more than 1000 items, implement pagination with a Do until loop and an Append to array variable to collect all items before passing them to the Select action. The Create HTML table action can handle up to about 500 rows reliably without hitting size limits.
- Column names are case‑sensitive: In the
item()?['ColumnName']expressions, the column internal name (usually same as display name but without spaces) must be typed exactly. Use the dynamic content picker to avoid typos. - Email client compatibility: Most email clients (Outlook, Gmail, Outlook on the web) respect embedded
<style>blocks. However, some clients (e.g., Gmail app on iOS) may strip the<style>tag. For maximum compatibility, consider inlining the CSS properties on each<td>and<th>element using an inline‑styling tool. The approach described works for the majority of business users in Outlook. - Performance: Each Select and Create HTML table action adds a few seconds to the flow. For extremely large tables (1000+ rows), consider breaking the report into multiple emails or using a data summary.
Common Pitfalls
- Table appears unstyled – You likely forgot to include the Compose output in the email body, or the
<style>tags are missing from the CSS block. - Expression errors – If you see
item()?['Deadline']not resolving, double‑check the column internal name (use Get items sample output to verify). - Email body is truncated – The Create HTML table may generate a very long string. Although the action can handle large tables, the email action has limits (~2 MB). Keep the table reasonable and consider sending an attachment instead for extremely long data sets.
- The table does not show up at all – Ensure you are in Code View when pasting the dynamic expressions. Plain text mode may not interpret them.
Final Recommendation
Combining the Select, Create HTML table, and a Compose action containing CSS is a clean, foolproof way to produce professional-looking HTML tables in Power Automate emails. By customising the CSS and formatting the data in the Select step, you retain full control over the appearance without relying on third‑party connectors or premium actions. Start with the example above, then tweak the colours, fonts, and formatting to match your brand guidelines.
References
- Original article: Matthew Devaney, Foolproof Power Automate HTML Table Styling – https://www.matthewdevaney.com/foolproof-power-automate-html-table-styling/
- Microsoft Learn: Create HTML table action – [official docs placeholder, see Power Automate documentation]
- Microsoft Learn: Select action – [official docs placeholder]
- DivTable Table Styler – https://divtable.com/table-styler/
Core principles for resilient, maintainable, and efficient cloud flows, distilled from real-world implementations.
Build flows that gracefully handle failures and automatically notify you with run details.
Discover the trade-offs between Content-ID, Base64, and the Microsoft Graph API for embedding images in Power Automate emails. This guide covers which method works best for Outlook, Gmail, and more.