日期: 2018 年 11 月 13 日

python读取excel内容再转变成html添加到outlook中

需求

读取excel里的表格里的内容,然后打开本机的outlook。把excel里的内容添加到正文里,注意。这里是要添加到正文!正文!正文!而不是添加到附件里

设计思路

1.excel处理

打开excel的方法有很多,但是在不知道excel里,行和列的大小的情况下,就能获得excel里的非空值行列的办法不多。我这边采用的是xlwings这个库,用的方法是range.current_region这个方法。这个方法会选择当前range下,有值的区域(非空区域)
通过配置options选项,可以指定excel获得的值的格式,int或者string,或者空值返回N/A

2.打开outlook

打开outlook在windows上只能用win32模块了,通过下面方法可以打开outlook并且创建一个空的email

olook = win32com.client.Dispatch("Outlook.Application")
mail = olook.CreateItem(0)

然后配置邮件的htmlbody和outlook邮件悬停(可以手动更改邮件内容,手动发送),可以用以下方法

mail.HTMLBody = body_html
mail.Display(True)

完整代码

下面是完整代码,读者修改一下excel的路径,就可以自己去试试啦

# -*- coding: UTF-8 -*-
import sys
reload(sys)
sys.setdefaultencoding('utf-8')
import win32com.client
import xlwings
def get_excel_date(filename):
    '''
    获得excel里的所有内容,返回list
    :param filename:  excel路径
    :return: list[list[]]
    '''
    app = xlwings.App(visible=False, add_book=True)
    app.display_alerts = False
    app.screen_updating = False
    wb = app.books.open(filename)
    sht = wb.sheets[0]
    rng = sht.range('A1')
    # 把excel里的数据读取成 年-月-日 时:分:秒的格式
    my_date_handler = lambda year, month, day, hour, minute, second, **kwargs: "%04i-%02i-%02i %02i:%02i:%02i" % (
    year, month, day, hour, minute, second)
    # 取出所有内容,这里用ig这个变量,是为了庆祝I.G获得LOL S8赛季总冠军
    ig = rng.current_region.options(index=False, numbers=int, empty='N/A', dates=my_date_handler)
    result = ig.value
    wb.close()
    app.quit()
    return result
if __name__ == '__main__':
    olook = win32com.client.Dispatch("Outlook.Application")
    mail = olook.CreateItem(0)
    mail.Recipients.Add("357244849@qq.com")
    mail.Subject = "test report"
    body_html = ""
    body_html = body_html + '<body>Hi all:<br/>以下是XXXXX项目今天的测试情况:<br/><br/>明天的测试计划:<br/><br/>目前的bug:'
    body_html = body_html + '<table width="1" border="1" cellspacing="1" cellpadding="1" height="100">'
    # 这里用rng 是因为这一次rng止步8强!
    rng_list = get_excel_date("C:\lzw_programming\resource\reports\CurrentVersionAllDefectTable.xlsx")
    # 表头
    for tr_list in rng_list[:1]:
        body_html = body_html + "<tr>"
        for td_list in tr_list:
            # 这里也是奇葩需求,因为要求表头不能换行,所以用了nowrap
            body_html = body_html + '<th bgcolor="#C3C3C3" nowrap="nowrap">' + td_list + '</th>'
        body_html = body_html + "</tr>"
    # 表内容
    for tr_list in rng_list[1:]:
        body_html = body_html + "<tr>"
        for td_list in tr_list:
            body_html = body_html + "<td>" + td_list + "</td>"
        body_html = body_html + "</tr>"
    body_html = body_html + '</table>'
    body_html = body_html + "</body>"
    mail.HTMLBody = body_html
    mail.Display(True)

解决pyinstaller不兼容python-docx的方法

需求

python-docx是一个python的读写word的库,可以用来读写word文档,向word文档里插入表格。例如如下的操作docx的代码:

from docx import Document
document = Document()
document.add_heading('Document Title', 0)
p = document.add_paragraph('A plain paragraph having some ')
p.add_run('bold').bold = True
p.add_run(' and some ')
p.add_run('italic.').italic = True
document.add_heading('Heading, level 1', level=1)
document.add_paragraph('Intense quote', style='Intense Quote')
document.add_paragraph(
    'first item in unordered list', style='List Bullet'
)
document.add_paragraph(
    'first item in ordered list', style='List Number'
)
records = (
    (3, '101', 'Spam'),
    (7, '422', 'Eggs'),
    (4, '631', 'Spam, spam, eggs, and spam')
)
table = document.add_table(rows=1, cols=3,style='Light Grid Accent 1')
hdr_cells = table.rows[0].cells
hdr_cells[0].text = 'Qty'
hdr_cells[1].text = 'Id'
hdr_cells[2].text = 'Desc'
for qty, id, desc in records:
    row_cells = table.add_row().cells
    row_cells[0].text = str(qty)
    row_cells[1].text = id
    row_cells[2].text = desc
document.add_page_break()
document.save('demo.docx')

 
pyinstaller是python打包成exe的工具。
当我们要把编写好的使用了python-docx的程序打包时,问题来了。
首先,命令行打包

pyinstaller -D word_generate.py

这个没问题,word_generate.py是我的主程序文件。这里打包也不报错。但是下一步,运行的时候,duang~报错了,报错如下:

C:lzw_programmingjira_testdistword_generate>word_generate.exe
Traceback (most recent call last):
  File "word_generate.py", line 4, in <module>
  File "site-packagesdocxapi.py", line 25, in Document
  File "site-packagesdocxopcpackage.py", line 116, in open
  File "site-packagesdocxopcpkgreader.py", line 32, in from_file
  File "site-packagesdocxopcphys_pkg.py", line 31, in __new__
docx.opc.exceptions.PackageNotFoundError: Package not found at 'C:LZW_PR~1JIRA_T~1distWORD_G~1docxtemplatesdefault.docx'
[4232] Failed to execute script word_generate

解决方法

在翻了很多地方之后,终于找到了解决方法。很简单。增加一个hook-docx.py文件在PyInstallerhooks目录下就可以了。下面是文件内容以及路径

#-----------------------------------------------------------------------------
# Copyright (c) 2018-2018, PyInstaller Development Team.
#
# Distributed under the terms of the GNU General Public License with exception
# for distributing bootloader.
#
# The full license is in the file COPYING.txt, distributed with this software.
#-----------------------------------------------------------------------------
from PyInstaller.utils.hooks import collect_data_files
datas = collect_data_files("docx")

路径:


苏ICP备18047533号-1