前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Python自动化办公-玩转报表

Python自动化办公-玩转报表

作者头像
somenzz
发布2021-08-19 16:26:47
5840
发布2021-08-19 16:26:47
举报
文章被收录于专栏:Python七号

你很可能也看到过公众号文章下方的广告,是关于 Python 自动化生成报表的,我自己就经常看到,说的是一个人因为报表做不出来,愁眉苦脸,做不出来就要被辞职了,这时一个高手拿过电脑,一顿操作猛如虎,一份精美的报表很快就生成了,被帮助的人写满一脸的崇拜...

其实不用崇拜,很简单,今天,我来告诉你方法。

这里说做报表,不用 excel,不用专业的报表平台,就是纯 html 生成一些漂亮的可视化报表,甚至可以交互,这样的报表你可以发 html 邮件给老板,老板不需要下载,不需要登陆专业的报表平台,打开邮件就可以直接看到,还可以点击来交互,非常方便,如果你这样做,那离升职加薪不会太远?。

废话不多说,现在就告诉你方法。咱们以目标为导向,技术不技术的不重要,实现了就好。

1、选择一个报表模版

首先你要生成什么样的报表,这里有个网站可以供你选择,就是大名鼎鼎的 ECharts 库,https://echarts.apache.org/zh/index.html

点击所有示例,可以看到很多样例图片:

选择一个你想用的,比如,我们选择「柱状图」->「基础柱状图」

点击「下载示例」,就可以下载一个 html 文件,用浏览器打开就是这个柱状图。

现在用个编辑器打开这个 html 文件,修改其中的数据,我们就可以生成一个属于自己的报表

然后保存,这样一个报表就生成了,如果简陋一点的话,你直接把这个 html 作为邮件的附件发给老板,老板双击这个 html 文件就可以在浏览器上看到,不过这并不是完美的,万一老板的电脑没有浏览器呢。

完美的解决方案是将这些报表显示在邮件的正文。

2、用 Python 发送 html 邮件

这个 前文最简单的方式发送邮件 小节 "发送多彩的 html 邮件" 有有具体的方法和代码,这里就不重复说了。

3、使用 Jinja2 来渲染 html

第 1 步中的替换是手工操作的,假如数据量比较大,或者要批量生成报表,可能就没那么方便,这不,我们有万能的 Python 嘛。

如果用过 Django,你就知道 Jinja2 的模版大法,简单来讲,Jinja2 将一个文件中的标识替换成你需要的内容。这里我们用的正是这一点。

比如 html 文件中的有这么一段:

代码语言:javascript
复制
option = {
    xAxis: {
        type: 'category',
        data: ['张三', '李四', '王五', '赵六']
    },
    yAxis: {
        type: 'value'
    },
    series: [{
        data: [120, 200, 150, 80],
        type: 'bar'
    }]
};

我们希望替换其中两处的 data,就可以先这样写

代码语言:javascript
复制

option = {
    xAxis: {
        type: 'category',
        data: {{ data1 }}
    },
    yAxis: {
        type: 'value'
    },
    series: [{
        data: {{ data2 }},
        type: 'bar'
    }]
};

然后借助 Jinja2 可以很方便的替换:

代码语言:javascript
复制
from templater import DefaultTemplater

if __name__ == "__main__":

    templater = DefaultTemplater("bar-simple.html", "bar-simple-templeted.html")
    data1 = ['张三1', '李四2', '王五3', '赵六4']
    data2 = [3120, 3200, 3150, 980]
    tags = {
        "data1": data1,
        "data2": data2,
    }
    templater.render(tags)

打开 bar-simple-templeted.html 发现已经被替换掉了,在批量制作报表时,是不是很方便?

这里用到了 DefaultTemplater,其实现代码如下 (templater.py):

代码语言:javascript
复制
# templater.py
from dataclasses import dataclass
from typing import Dict
from jinja2 import Template


@dataclass
class DefaultTemplater(object):
    """ Allow to inject data in a jinja2 templated file and write the result to specified destination """

    source: str
    destination: str

    def render(self, data: Dict) -> None:
        """ Write template from source filled with data to destination
        Args:
        data: the data to inject in the template
        """
        self.load_template()
        filled_template = self.replace(data)
        self.write_filled_template(filled_template)

    def load_template(self) -> None:
        """ Load template from source
        """
        with open(self.source, "r") as f:
            self.template = f.read()

    def replace(self, values: Dict) -> str:
        """ Replace tag in template with values
        Args:
        values: dict with key: tag to search in template, value: value to replace the tag
        """
        template = Template(self.template)
        templated = template.render(**values)
        return templated

    def write_filled_template(self, content: str):
        """Write the result of the template and injected value to destination
        Args:
        content: what to write
        """
        with open(self.destination, "w") as f:
            f.write(content)

比如说一些更酷炫的:

其 html 代码如下(与 echarts 上下载的略有调整):

代码语言:javascript
复制
<!DOCTYPE html>
<html style="height: 100%">
    <head>
        <meta charset="utf-8">
    </head>
    <body style="height: 100%; margin: 0">
        <div id="container" style="height: 100%"></div>

        <script type="text/javascript" src="https://cdn.jsdelivr.net/npm/echarts@5/dist/echarts.min.js"></script>     

        <script type="text/javascript">
var dom = document.getElementById("container");
var myChart = echarts.init(dom);
var app = {};

var option;



var data_list = [
       [1, 2, 3, 4, 5],
       [8, 4, 3, 2, 3],
       [5, 9, 6, 10, 3],
       [9, 7, 4, 7, 6],
       [5, 4, 3, 2, 9]
]

option = {
    xAxis: {
        max: 'dataMax',
    },
    yAxis: {
        type: 'category',
        data: ['A', 'B', 'C', 'D', 'E'],
        inverse: true,
        animationDuration: 300,
        animationDurationUpdate: 300,
        max: 4 // only the largest 3 bars will be displayed
    },
    series: [{
        realtimeSort: true,
        name: 'X',
        type: 'bar',
        data: data_list[0],
        label: {
            show: true,
            position: 'right',
            valueAnimation: true
        }
    }],
    legend: {
        show: true
    },
    animationDuration: 0,
    animationDurationUpdate: 3000,
    animationEasing: 'linear',
    animationEasingUpdate: 'linear'
};

var index = 1;

function run () {
    var data = option.series[0].data;
    if(index >= data_list.length){
        return;
    }
    for (var i = 0; i < data.length; ++i) {
        data[i] = data_list[index][i];
    }
    index++;
    myChart.setOption(option);
}


setInterval(function () {
    run();
}, 3000);

if (option && typeof option === 'object') {
    myChart.setOption(option);
}

        </script>
    </body>
</html>

你只需要修改 data_list 和 yAxis 的分类就可以实现自己想要的动态报表。

最好懂一点 javascript 的语法,这样可以改一改数据的结构,更方便的生成自己想要的报表。

最后的话

要生成报表,其实并不需要太精通技术,从网上下载个模版,自己改下数据和分类,就可以制作一个 html 报表,然后将 html 作为邮件正文发送出去,也可以转成图片、pdf 发送,具体场景就看自己需求了。如果要批量制作很多同类报表,可以借助 Jinja2 的模版大法,批量替换报表中的数据,更高效的完成。

如果你也在学习 Python,不妨关注一下我,每天学习一个 Python 技巧。

推荐阅读:

Python自动化办公-玩转图表

有问题?留言讨论

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-08-13,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Python七号 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1、选择一个报表模版
  • 2、用 Python 发送 html 邮件
  • 3、使用 Jinja2 来渲染 html
  • 最后的话
相关产品与服务
腾讯云 BI
腾讯云 BI(Business Intelligence,BI)提供从数据源接入、数据建模到数据可视化分析全流程的BI能力,帮助经营者快速获取决策数据依据。系统采用敏捷自助式设计,使用者仅需通过简单拖拽即可完成原本复杂的报表开发过程,并支持报表的分享、推送等企业协作场景。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档