Apple’s Worldwide Developers Conference to kick off June 10 at 10 a.m. PDT with Keynote address

The Keynote will be available to stream on apple.com, the Apple Developer app, the Apple TV app, and the Apple YouTube channel. On-demand playback will be available after the conclusion of the stream.

Looks like no one’s replied in a while. To start the conversation again, simply ask a new question.

How to export emails into a .CSV file

I was looking for a solution similar to that in the discussions at Exporting Email to Numbers - Apple Community and convert mbox to csv - Apple Community, but I wanted to save the mailbox folder name and the email recipients, which the script in those discussions will not do


I revised the script from those discussions to do what I needed. I have decided to post my new script here for the benefit of others plodding along in my footsteps.



Mac mini 2018 or later

Posted on Jul 6, 2022 4:19 PM

Reply
Question marked as Best reply

Posted on Jul 23, 2022 2:36 PM

Here are detailed instructions on how to use this latest version to export emails into a .CSV or .TSV file:


Open a Script Editor app window (Click on an empty area of the Mac desktop so that no app window is currently active, then on the taskbar at the top of the Mac desktop select Go > Utilities > Script Editor). When a new empty Script Editor window opens, copy&paste the script into the window.


Open a Mail app window (Click on an empty area of the Mac desktop so that no app window is currently active, then on the taskbar at the top of the Mac desktop, select Go > Applications > Mail. If you have difficulty getting the Mail app window to open or if desired emails are not showing up in the Mail app, on the taskbar at the top of the Mac desktop, use Mail > Accounts... and select the desired account on the right or press the + sign at the bottom of the Internet Accounts window.


Once the desired emails are showing in the Mail app window, select the emails to be exported. Best to first select only a few emails and confirm that the script works properly before running it on a large number of emails.


You can use search to find selected emails based upon keywords, but best not to search in "All Mailboxes". Instead, best to select a folder (eg, Inbox) and search within that folder. If "All Mailboxes" is searched, the 'Mailbox folder' column in all rows of the exported .CSV or .TSV file are going to contain "Import", no matter what folder the selected emails are actually in and even if the selected emails are all in a single folder.


In the Script Editor app window, click the run button and watch the Running... indicator. If there are more than a hundred emails, the script can take many minutes to finish. If the script fails with a "Numbers got an error: Invalid row count.", then the script is not seeing any emails selected in the Mail app.


When the script runs successfully, it opens a new Numbers app window and writes the results into that window. When the script finishes, look for the new Numbers app window or open the Numbers app from the app bar that pops up from the bottom of the Mac desktop when the cursor is moved there. With Numbers app window active on the Mac desktop, use File > Export To > CSV... to save the result in .CSV format in the directory and file of your choice. (There is also an option to save the file in TSV (Tab-Separated Value) format, which is often a better option than CSV format.) Then, close the Numbers app window and click Delete if you don't want to save the result in spreadsheet format.


The Accounts... window in the Mail app suggests that it can be used to access emails on many different email servers (iCloud, Microsoft Exchange, Google Gmail, Yahoo Mail, AOL, and perhaps others). If that is true, then the attached Apple script can be used to extract emails from all those different servers. That is, of course, a big if. As we all know, despite Apple's mantra, Apple software often doesn't just work! 😣

Similar questions

13 replies
Question marked as Best reply

Jul 23, 2022 2:36 PM in response to OneSkyWalker

Here are detailed instructions on how to use this latest version to export emails into a .CSV or .TSV file:


Open a Script Editor app window (Click on an empty area of the Mac desktop so that no app window is currently active, then on the taskbar at the top of the Mac desktop select Go > Utilities > Script Editor). When a new empty Script Editor window opens, copy&paste the script into the window.


Open a Mail app window (Click on an empty area of the Mac desktop so that no app window is currently active, then on the taskbar at the top of the Mac desktop, select Go > Applications > Mail. If you have difficulty getting the Mail app window to open or if desired emails are not showing up in the Mail app, on the taskbar at the top of the Mac desktop, use Mail > Accounts... and select the desired account on the right or press the + sign at the bottom of the Internet Accounts window.


Once the desired emails are showing in the Mail app window, select the emails to be exported. Best to first select only a few emails and confirm that the script works properly before running it on a large number of emails.


You can use search to find selected emails based upon keywords, but best not to search in "All Mailboxes". Instead, best to select a folder (eg, Inbox) and search within that folder. If "All Mailboxes" is searched, the 'Mailbox folder' column in all rows of the exported .CSV or .TSV file are going to contain "Import", no matter what folder the selected emails are actually in and even if the selected emails are all in a single folder.


In the Script Editor app window, click the run button and watch the Running... indicator. If there are more than a hundred emails, the script can take many minutes to finish. If the script fails with a "Numbers got an error: Invalid row count.", then the script is not seeing any emails selected in the Mail app.


When the script runs successfully, it opens a new Numbers app window and writes the results into that window. When the script finishes, look for the new Numbers app window or open the Numbers app from the app bar that pops up from the bottom of the Mac desktop when the cursor is moved there. With Numbers app window active on the Mac desktop, use File > Export To > CSV... to save the result in .CSV format in the directory and file of your choice. (There is also an option to save the file in TSV (Tab-Separated Value) format, which is often a better option than CSV format.) Then, close the Numbers app window and click Delete if you don't want to save the result in spreadsheet format.


The Accounts... window in the Mail app suggests that it can be used to access emails on many different email servers (iCloud, Microsoft Exchange, Google Gmail, Yahoo Mail, AOL, and perhaps others). If that is true, then the attached Apple script can be used to extract emails from all those different servers. That is, of course, a big if. As we all know, despite Apple's mantra, Apple software often doesn't just work! 😣

Jul 23, 2022 2:40 PM in response to OneSkyWalker

By the way, the Apple support item at Save emails as files or PDFs in Mail on Mac - Apple Support explains how to save multiple selected emails into a single Rich Text Format file which will preserve an image of each email as displayed in the Mail app. When saving in .RTF format, leaving 'Include Attachments' selected may cause problems when later attempting to access the .RTF file on Microsoft Windows. The Microsoft Windows Wordpad app does not display page breaks, so it appears that all emails are on a single giant page, but the Microsoft Word app will display the emails with a page break between each email.


And please note that the Apple support item at Save emails as files or PDFs in Mail on Mac - Apple Support is quite misleading! 😣 The first option is "Save messages as files:". That option actually saves all selected emails into a single file. And there is no indication that there are potential issues when saving in .RTF format with 'Include Attachments' selected. The second option is "Save messages as PDFs:". That option saves each selected email into a separate .PDF file. The subject of the email is used as the name of the .PDF file. There is nothing in the Apple support item which explains what is going to happen if two emails have the same subject or what is going to happen if an email has no subject. The answers to those questions are almost certain to disappoint some users! 😣


When you are finished exporting all desired emails, if you no longer want the Mail app to access your email server, on the taskbar at the top of the Mac desktop, use Mail > Accounts... and in the Internet Accounts window, select the account which was added above and press the - sign at the bottom of the window.


And, oops, Microsoft Excel typically won't be able to properly import .CSV or .TSV files created by this script because the Excel legacy import wizard does not properly handle carriage return characters within text delimiters ("). 😣 I have written a 1000-line Perl script to parse a .TSV file produced using the attached Apple script and to build a sparse .TSV file suitable for import into Microsoft Excel and other spreadsheet programs. I can make that Perl script available if others need it. Just post a reply here.


My thanks again to SGIII for posting the original version of this Apple script.

Jul 7, 2022 9:17 AM in response to OneSkyWalker

Nice enhancement to the script!


# Why the heck must 'of aMsg' be added to the end of this line?!??


The short answer is that the script won't work if you don't do that!😀


AppleScript seems to be full of little things like that are a bit mysterious to people (like me) without a formal coding background.


The longer answer would be to have a look at the AppleScript Dictionary for the Mail app. (In Script Editor File > Open Dictionary).




There's a lot going on there with 'mailbox'. Here we want to retrieve the property of a message, as opposed to trying to do something like having the script set up a new mailbox (I think of that as an element contained by the application). So in this case AppleScript requires more specificity before it can tell Mail what you mean.


Instead of:


set nameMailbox to name of mailbox of aMsg


You can instead use:


set nameMailbox to name of its mailbox


That feels less redundant.


You can add the its to other statements referring to aMsg as well, if you like.



SG





Jul 23, 2022 2:35 PM in response to OneSkyWalker

Here is my latest version of the script which I enhanced to export the email subject:

# Edited from https://discussions.apple.com/thread/253056753
set dataLst to {{"SenderAddress", "SenderName", "Mailbox folder", "RecipientAddresses", "Date", "Time", "Subject", "Content"}}

tell application "Mail"
	repeat with aMsg in items of (get selection)
		tell aMsg
			set senderNameAddr to my splitEmail(sender)
			set senderAddr to item 2 of senderNameAddr
			set senderName to item 1 of senderNameAddr
			# Why the heck must 'of aMsg' be added to the end of this line?!??
			set nameMailbox to name of mailbox of aMsg
			set toRecipients to to recipients
			set theRecipientAddrs to address of item 1 of toRecipients
			repeat with i from 2 to (count of toRecipients)
				set theRecipientAddrs to theRecipientAddrs & " " & address of (get to recipient i) as rich text
			end repeat
			set ccRecipients to cc recipients
			repeat with i from 1 to (count of ccRecipients)
				set theRecipientAddrs to theRecipientAddrs & " " & address of (get cc recipient i) as rich text
			end repeat
			set bccRecipients to bcc recipients
			repeat with i from 1 to (count of bccRecipients)
				set theRecipientAddrs to theRecipientAddrs & " " & address of (get bcc recipient i) as rich text
			end repeat
			set msgSubj to subject
			set msgDate to date received
			set msgTime to time string of msgDate
			set msgDate to my dateFormat(date string of msgDate)
			set msgContent to content
			set msgLst to {senderAddr, senderName, nameMailbox, theRecipientAddrs, msgDate, msgTime, msgSubj, msgContent}
			copy msgLst to dataLst's end
		end tell
	end repeat
end tell

tell application "Numbers"
	set newDoc to make new document
	tell table 1 of active sheet of newDoc
		delete column "A" -- remove default Header Column
		set column count to length of item 1 of dataLst
		set row count to (length of dataLst)
		repeat with i from 1 to length of dataLst
			repeat with j from 1 to length of item 1 of dataLst
				set value of cell j of row i to item j of item i of dataLst
			end repeat
		end repeat
	end tell
end tell

to dateFormat(aDateString) --> yyyy-mm-dd
	set {year:y, month:m, day:d} to date aDateString
	tell (y * 10000 + m * 100 + d) as string to text 1 thru 4 & "-" & text 5 thru 6 & "-" & text 7 thru 8
end dateFormat

to splitEmail(nameAddress)
	set text item delimiters to "<"
	tell nameAddress
		set theName to text item 1
		set theAddress to text 1 thru -2 of text item 2
	end tell
	return {theName, theAddress}
end splitEmail


Jul 6, 2022 4:27 PM in response to OneSkyWalker

Here is my new version of the script:

# Edited from https://discussions.apple.com/thread/253056753
set dataLst to {{"SenderAddress", "SenderName", "Mailbox folder", "RecipientAddresses", "Date", "Time", "Content"}}

tell application "Mail"
	repeat with aMsg in items of (get selection)
		tell aMsg
			set senderNameAddr to my splitEmail(sender)
			set senderAddr to item 2 of senderNameAddr
			set senderName to item 1 of senderNameAddr
			# Why the heck must 'of aMsg' be added to the end of this line?!??
			set nameMailbox to name of mailbox of aMsg
			set toRecipients to to recipients
			set theRecipientAddrs to address of item 1 of toRecipients
			repeat with i from 2 to (count of toRecipients)
				set theRecipientAddrs to theRecipientAddrs & " " & address of (get to recipient i) as rich text
			end repeat
			set ccRecipients to cc recipients
			repeat with i from 1 to (count of ccRecipients)
				set theRecipientAddrs to theRecipientAddrs & " " & address of (get cc recipient i) as rich text
			end repeat
			set bccRecipients to bcc recipients
			repeat with i from 1 to (count of bccRecipients)
				set theRecipientAddrs to theRecipientAddrs & " " & address of (get bcc recipient i) as rich text
			end repeat
			set msgSubj to subject
			set msgDate to date received
			set msgTime to time string of msgDate
			set msgDate to my dateFormat(date string of msgDate)
			set msgContent to content
			set msgLst to {senderAddr, senderName, nameMailbox, theRecipientAddrs, msgDate, msgTime, msgContent}
			copy msgLst to dataLst's end
		end tell
	end repeat
end tell

tell application "Numbers"
	set newDoc to make new document
	tell table 1 of active sheet of newDoc
		delete column "A" -- remove default Header Column
		set column count to length of item 1 of dataLst
		set row count to (length of dataLst)
		repeat with i from 1 to length of dataLst
			repeat with j from 1 to length of item 1 of dataLst
				set value of cell j of row i to item j of item i of dataLst
			end repeat
		end repeat
	end tell
end tell

to dateFormat(aDateString) --> yyyy-mm-dd
	set {year:y, month:m, day:d} to date aDateString
	tell (y * 10000 + m * 100 + d) as string to text 1 thru 4 & "-" & text 5 thru 6 & "-" & text 7 thru 8
end dateFormat

to splitEmail(nameAddress)
	set text item delimiters to "<"
	tell nameAddress
		set theName to text item 1
		set theAddress to text 1 thru -2 of text item 2
	end tell
	return {theName, theAddress}
end splitEmail


By the way, can anyone tell me why the heck the line 'set nameMailbox to name of mailbox of aMsg
' must have 'of aMsg' at the end? Doesn't 'tell aMsg' imply 'of aMsg' for each line?


Jul 7, 2022 6:54 PM in response to Peggy

Peggy wrote:

I'd like to try this script but it is failing to compile at "tell table 1 of active sheet of newDoc."


Maybe a forum thing. Here's another copy-paste:


# https://discussions.apple.com/thread/254023594
# Edited from https://discussions.apple.com/thread/253056753

set dataLst to {{"SenderAddress", "SenderName", "Mailbox folder", "RecipientAddresses", "Date", "Time", "Content"}}

tell application "Mail"
	repeat with aMsg in items of (get selection)
		tell aMsg
			set senderNameAddr to my splitEmail(sender)
			set senderAddr to item 2 of senderNameAddr
			set senderName to item 1 of senderNameAddr
			# Why the heck must 'of aMsg' be added to the end of this line?!??
			set nameMailbox to name of its mailbox
			set toRecipients to to recipients
			set theRecipientAddrs to address of item 1 of toRecipients
			repeat with i from 2 to (count of toRecipients)
				set theRecipientAddrs to theRecipientAddrs & " " & address of (get to recipient i) as rich text
			end repeat
			set ccRecipients to cc recipients
			repeat with i from 1 to (count of ccRecipients)
				set theRecipientAddrs to theRecipientAddrs & " " & address of (get cc recipient i) as rich text
			end repeat
			set bccRecipients to bcc recipients
			repeat with i from 1 to (count of bccRecipients)
				set theRecipientAddrs to theRecipientAddrs & " " & address of (get bcc recipient i) as rich text
			end repeat
			set msgSubj to subject
			set msgDate to date received
			set msgTime to time string of msgDate
			set msgDate to my dateFormat(date string of msgDate)
			set msgContent to content
			set msgLst to {senderAddr, senderName, nameMailbox, theRecipientAddrs, msgDate, msgTime, msgContent}
			copy msgLst to dataLst's end
		end tell
	end repeat
end tell

tell application "Numbers"
	set newDoc to make new document
	tell table 1 of active sheet of newDoc
		delete column "A" -- remove default Header Column
		set column count to length of item 1 of dataLst
		set row count to (length of dataLst)
		repeat with i from 1 to length of dataLst
			repeat with j from 1 to length of item 1 of dataLst
				set value of cell j of row i to item j of item i of dataLst
			end repeat
		end repeat
	end tell
end tell

to dateFormat(aDateString) --> yyyy-mm-dd
	set {year:y, month:m, day:d} to date aDateString
	tell (y * 10000 + m * 100 + d) as string to text 1 thru 4 & "-" & text 5 thru 6 & "-" & text 7 thru 8
end dateFormat

to splitEmail(nameAddress)
	set text item delimiters to "<"
	tell nameAddress
		set theName to text item 1
		set theAddress to text 1 thru -2 of text item 2
	end tell
	return {theName, theAddress}
end splitEmail


SG

Jul 8, 2022 7:59 AM in response to SGIII

This continued to fail to compile when using my Mac mini running Mojave. I was finally able to get this to compile by using ScriptEditor on my Mac mini running Monterey. I wouldn't think that would be a problem but it obviously is. I will try later to see if the script will run on Mojave.

Jul 8, 2022 9:06 AM in response to Peggy

Could it be a difference in versions of Numbers?


Or a difference between the System Preferences settings on the two Macs?


Might check in particular Security & Privacy > Privacy > Accessibility and (if Mojave had that) Security & Privacy > Privacy > Automation.


It's vanilla AppleScript so in theory it should run fine on old OS. And I don't think AppleScript support for Numbers has changed that much.


Anyway, good to hear it's running fine under Monterey.


SG

Jul 8, 2022 9:32 AM in response to SGIII

My problem was getting it to compile so that I could save it as an AppleScript. Now that I've saved it as an AppleScript, it's still having errors when trying to run the script.


In both Monterey & Mojave with a blank Numbers document open using Numbers 12.1 & Numbers 6.1 respectively, I get "Numbers got an error: Invalid row count." Do I need to create a blank document with 1000 rows first?


In Mojave, with Numbers 2.3, the error is "Numbers got an error: Can't make application "Numbers" into type reference."

How to export emails into a .CSV file

Welcome to Apple Support Community
A forum where Apple customers help each other with their products. Get started with your Apple ID.