write contents of CSV to body of email

18607
18
12-16-2016 08:04 AM
jaykapalczynski
Frequent Contributor

I am trying to write the contents of a csv to the body of an email and of course having issues.

I can list out the contents as such.  But looking for a formatted HTML version that I can place in the body of an email...I have been through a dozen of forums and cant seem to find a simple solution and one that works..

        csv.register_dialect(
            'mydialect',
            delimiter = ',',
            quotechar = '"',
            doublequote = True,
            skipinitialspace = True,
            lineterminator = '\r\n',
            quoting = csv.QUOTE_MINIMAL)
        
        print("\n Now the output from a dictionary created from the csv file")
        with open('z_outFileRegion1.csv', 'rb') as mycsvfile:
            dictofdata = csv.DictReader(mycsvfile, dialect='mydialect')
            for row in dictofdata:
                print(row['region']+"\t "+row['county']+"\t "+row['ramp'])‍‍‍‍‍‍‍‍‍‍‍‍‍‍

I tried this one but cant get it to work

python - Send the contents of a CSV as a table in an email? - Stack Overflow 

Python send email from a csv list - Stack Overflow 

Anyone have any easy solution to grab the CSV, format with HTML and attach it to the body of the email?

Below I am attaching the csv to the email but want to display the records in the email itself.

    filename = "z_outFileRegion1.csv"
    f = file(filename)

    #===BUILD EMAIL========================================
    def msgEmail():
        msg = MIMEMultipart()

        #body = "This is the message"
        #content = MIMEText(body, 'plain')
        #msg.attach(content)
        
        attachment = MIMEText(f.read())
        attachment.add_header('Content-Disposition', 'attachment', filename=filename)           
        msg.attach(attachment)

        msg['Subject'] = "Region Report " + CurrentDate

        server = smtplib.SMTP('smtp1.fff',25)
        server.set_debuglevel(1)
        server.ehlo()
        server.sendmail(FROMADDR, TOADDRS, msg.as_string())
        server.quit()
   
    #===PROCESS EMAIL======================================
    getMsgP = msgEmail()
    print getMsgP‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍
0 Kudos
18 Replies
jaykapalczynski
Frequent Contributor

Im also trying this approach...

BUT NO MATTER what I do to try and format the column widths and table widths nothing changes...

thoughts?

        ##First, create the texts of the columns:
        cols = ["<td style='width:100px'>{0}</td>".format( "<td style='width:100px'></td>".join(t)) for t in your_list]
        ##then use it to join the rows (tr)
        rows = "<tr style='width:100px'>{0}</tr>".format( "<tr style='width:100px'>\n</tr><br><br><br>".join(cols))
        ##finaly, inject it into the html...
        html1 = """<HTML> <body>
            <h1>Attendance list</h1>
                <table style="width:100%">  
                   {0}
                </table>
            </body>  
            </HTML>""".format(rows)

        part4 = MIMEText(html1, 'html')
        msg.attach(part4)
0 Kudos
jaykapalczynski
Frequent Contributor

ok my last post seems to stem from too many fields....I narrows down to 10 adn I was able to add Style to my table being built.

Were my results from your code what you were expecting?

THANKS for all your help....much appreciated.

0 Kudos
JamesCrandall
MVP Frequent Contributor

My mistake, yes I was testing with "mylist" not "mylist2".  The result I get when print hmtl:

       <html>
          <head></head>
          <body>
            <p><br>
                Python Script Errors & Logging Reports<br> <br> <br>
                | Log Items | <br>
                <a href=>[1, 'blah', 'blah2', 'blah3', 'blah4', 'blah5']</a>
                <a href=>[2, 'blah33', 'blah44', 'blah55', 'blah66', 'blah77']</a>
                <a href=>[3, 'blah111', 'blah222', 'blah333', 'blah444', 'blah555']</a><br> <br>
            </p>
          </body>
        </html>
0 Kudos
jaykapalczynski
Frequent Contributor

Is there a way to add the headers in there?

0 Kudos
JamesCrandall
MVP Frequent Contributor

Is there a way to add the headers in there?

The headers as in the first row of your csv file?  Just make sure your list is correctly populated from the csv.

mylist = [[0, "Header1", "Header2", "Header3", "Header4", "Header5"],[1, "blah", "blah2", "blah3", "blah4", "blah5"], [2, "blah33", "blah44", "blah55", "blah66", "blah77"], [3, "blah111", "blah222", "blah333", "blah444", "blah555"]]

Or do you mean attach the csv file to the message? 

0 Kudos
jaykapalczynski
Frequent Contributor

OK...I was able to get this working....

But my question is how can I get a bit more effective with the html formatting...Maybe a vertical table?  Any ideas on how to modify this to be a vertical table?

Im not sure how to target the specific fields to put in the html formatting.  Thoughts?

DESIRED_COLUMNS = ('county','ramp','date','trailblazers','regulations','safteygsign','rutfree','potholes','grass','trash','portapotties','lighting',
           'courtesypier','boatslide','fishingpier','debris','potholesramp','bulkhead','shoreline','contractor','comments','CreationDate','Creator','EditDate','Editor')

f2 = open("z_outFileRegion3.csv")
reader = csv.reader(f2)

headers2 = [1,2,3,4,8,12,16,20,24,28,32,36,41,45,49,53,57,61,65,69,74,75,76,77,78]
results2 = []
for row in reader:
    if not headers2:
        headers2 = []
        for i, col in enumerate(row):
            if col in DESIRED_COLUMNS:
                # Store the index of the cols of interest
                headers2.append(i)
    else:
        results2.append(tuple([row for i in headers2]))

#...SNIP
        cols1 = ["<td>{0}</td>".format( "<td><td/>".join(t)) for t in results2]
        rows1 = "<tr>{0}</tr>".format( "<tr><tr/><br>".join(cols1))
        html1 = """<HTML>
            <body>
            <h4>Attendance list</h4>
                <table>  
                   {0}
                </table>
            </body>  
            </HTML>""".format(rows1)

        part4 = MIMEText(html1, 'html')
        msg.attach(part4)
#...SNIP
0 Kudos
jaykapalczynski
Frequent Contributor

Geeze thanks Blake...you are so kind.  I simple suggestion steering me towards printing in python would have been nice.  

Is there anyone out there, someone that choose not to insult people, that have any idea of how to do this.  I dont care if its HTML just thought that  might be an easier option formatting wise.

0 Kudos
RonnieRichards
Occasional Contributor III

It takes a some time to work with but I would recommend trying the jinja2 library or alternative templating library. It has many options for looping over python objects. We have standardized our formatted email's using html and attachments. It works very well, it is much easier to copy and reuse existing templates than to understand inline print statements. 

0 Kudos
BlakeTerhune
MVP Regular Contributor

Haha, sorry! I was making a joke about the repeated occurrences of "Human feces all over sign" in your posts. My apologies for any insult taken. My suggestions are honest though, I really think you should try adding some HTML formatting to style the email.