
Today, I needed to save some of my Gmail emails to Google Drive as PDF files. I looked around for a bit. I tried CloudHQ, but I didn’t want to pay. Next, I looked into exporting my Google Data into an MBOX type format. This seemed reasonable at first, but then I had to find a tool to import MBOX into. I chose Thunderbird, but then Thunderbird wanted me to pay. Next, I tried a couple of other Chrome Extensions. Neither of these worked well.
Finally, I determined to get the emails to be outputted in the format that I wanted without paying, it was probably best to write a Google App Script.
What’s a Google App Script?
Well, according to Google, “Apps Script is a scripting platform developed by Google for light-weight application development in the G Suite platform.” You can learn more here. If you have a Gmail account, it looks like you should be able to use it.
I started by assigning all of the emails in Gmail that I wanted to export a Label. For the purpose of this tutorial, I created the label “Export”
After I created the label “Export”, I next associated the label with the emails that I wanted to save as PDF.

After selecting the emails that I wanted to export. I logged into the Google App Scripts by typing this url, http://script.google.com/. Once in Google App Scripts, I created a new project entitled Save Gmail to Google Drive. I had to give Google App Scripts access to both my Gmail and Google Drive.

I double-clicked on the project and entered the following javascript code.
function saveGmailToGoogleDriveAsPDF() {
var gmailLabels = "Export ";
var driveFolder = "My Gmail";
//Search Gmail for our Export Label
//GMail will return the threads of the email conversations. This is different than the raw emails. This is all of the emails within a thread.
var threads = GmailApp.search("label:" + gmailLabels, 0, 3);
if (threads.length > 0) {
/*GetFolders returns a FolderIterator. See if we have any folders. If not, then create one.
var folders = DriveApp.getFoldersByName(driveFolder);
var folder;
if ( folders.hasNext() ) {
folder = folders.next();
}
else
folder = DriveApp.createFolder(driveFolder);
/*Iterate through the threads of emails*/
for (var t=0; t<threads.length; t++) {
var msgs = threads[t].getMessages();
var html = "";
var attachments = [];
//Get the Subject of the first email in the thread. We'll use the Subject in the name of the email
var subject = threads[t].getFirstMessageSubject();
/* We're going to stick all of the messages in this thread into one pdf */
for (var m=0; m<msgs.length; m++) {
//designate what the first date is in the thread, we'll use this in the name as well
var firstDate;
var msg = msgs[m];
var date;
if ( m == 0 )
{
firstDate = msg.getDate();
date = firstDate;
}
else
date = msg.getDate()
//Build the HTML, you may wany to introduce some hrs. The wordpress pre tag was behaving oddly with html tags.
html += "From: " + msg.getFrom() + "";
html += "To: " + msg.getTo() + "";
html += "Date: " + date + "";
html += "Subject: " + msg.getSubject() + "";
html += msg.getBody().replace(/<img[^>]*>/g,"");
//Snag the attachments so we can save them for later
var atts = msg.getAttachments();
for (var a=0; a<atts.length; a++) {
attachments.push(atts[a]);
}
}
/* Iterate through the attachment files and create links in the pdf's footer */
if (attachments.length > 0) {
var footer = "Attachments:";
for (var z=0; z<attachments.length; z++) {
var attachment = attachments[z]
var filename = attachment.getName();
//You may want to treat different ContentType's differently...
var contentType = attachment.getContentType();
var iter = folder.getFilesByName( filename );
var file;
if ( iter.hasNext() )
file = iter.next()
else
file = folder.createFile(attachment);
footer += "" + file.getName() + "";
}
html += footer";
}
//Format the name to differentiate between Emails and attachments. Otherwise, everything starts to look the same.
//Write the formatted firstDate into the name
var filename = "Email: " + getFormattedDate( firstDate ) +": "+ subject;
var tempFile = DriveApp.createFile(filename+".html", html, "text/html");
/* Convert the Email Thread into a PDF File */
folder.createFile(tempFile.getAs("application/pdf")).setName(filename + ".pdf");
/*Get rid of the tmp file*/
tempFile.setTrashed(true);
}
}
}
Now to format the date use the following bit of code
function getFormattedDate( date )
{
var month = date.getMonth() + 1;
var day = date.getDate();
var hour = date.getHours();
var min = date.getMinutes();
var sec = date.getSeconds();
month = (month < 10 ? "0" : "") + month;
day = (day < 10 ? "0" : "") + day;
hour = (hour < 10 ? "0" : "") + hour;
min = (min < 10 ? "0" : "") + min;
sec = (sec < 10 ? "0" : "") + sec;
var str = date.getFullYear() + "-" + month + "-" + day + "_" + hour + ":" + min + " ";
/*alert(str);*/
return str;
}
Next, run the code in Google App Scripts by hitting the play button.

Execute Google App Script Project to save Gmails to Google Drive as PDF
Navigate to your Google Drive My Gmail Folder. Voila! You’ll see your pdfs. This code will also handle attachments, which include calendar event types. Ping me if you have any issues, and I can share the script with you.

Export Emails to Google Drive as PDF


Hi,
I find the features interesting and want it to be tailored to suit my requirements.
Would be indeed grateful if you can help.
Thanks
Sure, what exactly are your needs?
Hello, thank you so much for sharing this code.
I had to adjust 2 lines:
*/ was missing in line 8: /*GetFolders returns a FolderIterator. See if we have any folders. If not, then create one.
removed ” in line 56 : html += footer”;
But…the code worked ! Really nice.
I do have a question.
The body of 1 of the mails I tested contained an image.
After running the code I noticed that the image did not show in the PDF but was exported as a separate file
with name “image.png” (which was apparently the real image name)
As I have a lot of mails with images in the body it will be hard for me to determine which image goes with what mail.
Can you help me figure out a way to save the image with the same name as the PDF
and perhaps add a number (as 1 email might have multiple images in the body)
or will this be impossible?
I hope you can help me with this.
Thanks once again, the code really helped me.
Regards,
Caramel
Travor, Can you contact me? Im trying your script (copied above) but it seems a bit broken. I would love your help to get it working.
Travor—you rock! This is going to make tax season so much easier.
For people who found this page trying to figure out how to PDF their e-mails:
– I also had to use Caramel’s mods, they are pretty simple and obvious when you start to look at the code.
– The code as written only saves the first 3 e-mails it finds. This is simple to change by calling line 6 as GmailApp.search(“search criteria”) instead of GmailApp.search(“search criteria”,0,3)
– Instead of creating a label, you can change line 6 to use any search criteria that shows up in gmail’s search line. For example, my search criteria are:
threads = GmailApp.search(“in:taxes after:2021/1/1 before:2022/1/1”);
Can I get the code? Exactly what I need!
Would like the code!