<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          Python自動(dòng)化辦公-玩轉(zhuǎn)報(bào)表

          共 10473字,需瀏覽 21分鐘

           ·

          2021-08-16 10:27

          你很可能也看到過(guò)公眾號(hào)文章下方的廣告,是關(guān)于 Python 自動(dòng)化生成報(bào)表的,我自己就經(jīng)常看到,說(shuō)的是一個(gè)人因?yàn)閳?bào)表做不出來(lái),愁眉苦臉,做不出來(lái)就要被辭職了,這時(shí)一個(gè)高手拿過(guò)電腦,一頓操作猛如虎,一份精美的報(bào)表很快就生成了,被幫助的人寫(xiě)滿(mǎn)一臉的崇拜...

          其實(shí)不用崇拜,很簡(jiǎn)單,今天,我來(lái)告訴你方法。

          這里說(shuō)做報(bào)表,不用 excel,不用專(zhuān)業(yè)的報(bào)表平臺(tái),就是純 html 生成一些漂亮的可視化報(bào)表,甚至可以交互,這樣的報(bào)表你可以發(fā) html 郵件給老板,老板不需要下載,不需要登陸專(zhuān)業(yè)的報(bào)表平臺(tái),打開(kāi)郵件就可以直接看到,還可以點(diǎn)擊來(lái)交互,非常方便,如果你這樣做,那離升職加薪不會(huì)太遠(yuǎn)??。

          廢話(huà)不多說(shuō),現(xiàn)在就告訴你方法。咱們以目標(biāo)為導(dǎo)向,技術(shù)不技術(shù)的不重要,實(shí)現(xiàn)了就好。

          1、選擇一個(gè)報(bào)表模版

          首先你要生成什么樣的報(bào)表,這里有個(gè)網(wǎng)站可以供你選擇,就是大名鼎鼎的 ECharts 庫(kù),https://echarts.apache.org/zh/index.html

          點(diǎn)擊所有示例,可以看到很多樣例圖片:

          選擇一個(gè)你想用的,比如,我們選擇「柱狀圖」->「基礎(chǔ)柱狀圖」

          點(diǎn)擊「下載示例」,就可以下載一個(gè) html 文件,用瀏覽器打開(kāi)就是這個(gè)柱狀圖。

          現(xiàn)在用個(gè)編輯器打開(kāi)這個(gè) html 文件,修改其中的數(shù)據(jù),我們就可以生成一個(gè)屬于自己的報(bào)表

          然后保存,這樣一個(gè)報(bào)表就生成了,如果簡(jiǎn)陋一點(diǎn)的話(huà),你直接把這個(gè) html 作為郵件的附件發(fā)給老板,老板雙擊這個(gè) html 文件就可以在瀏覽器上看到,不過(guò)這并不是完美的,萬(wàn)一老板的電腦沒(méi)有瀏覽器呢。

          完美的解決方案是將這些報(bào)表顯示在郵件的正文。

          2、用 Python 發(fā)送 html 郵件

          這個(gè) 前文最簡(jiǎn)單的方式發(fā)送郵件 小節(jié) "發(fā)送多彩的 html 郵件" 有有具體的方法和代碼,這里就不重復(fù)說(shuō)了。

          3、使用 Jinja2 來(lái)渲染 html

          第 1 步中的替換是手工操作的,假如數(shù)據(jù)量比較大,或者要批量生成報(bào)表,可能就沒(méi)那么方便,這不,我們有萬(wàn)能的 Python 嘛。

          如果用過(guò) Django,你就知道 Jinja2 的模版大法,簡(jiǎn)單來(lái)講,Jinja2 將一個(gè)文件中的標(biāo)識(shí)替換成你需要的內(nèi)容。這里我們用的正是這一點(diǎn)。

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

          option = {
              xAxis: {
                  type'category',
                  data: ['張三''李四''王五''趙六']
              },
              yAxis: {
                  type'value'
              },
              series: [{
                  data: [12020015080],
                  type'bar'
              }]
          };

          我們希望替換其中兩處的 data,就可以先這樣寫(xiě)


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

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

          from templater import DefaultTemplater

          if __name__ == "__main__":

              templater = DefaultTemplater("bar-simple.html""bar-simple-templeted.html")
              data1 = ['張三1''李四2''王五3''趙六4']
              data2 = [312032003150980]
              tags = {
                  "data1": data1,
                  "data2": data2,
              }
              templater.render(tags)

          打開(kāi) bar-simple-templeted.html 發(fā)現(xiàn)已經(jīng)被替換掉了,在批量制作報(bào)表時(shí),是不是很方便?

          這里用到了 DefaultTemplater,其實(shí)現(xiàn)代碼如下 (templater.py):

          # 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)

          比如說(shuō)一些更酷炫的:

          其 html 代碼如下(與 echarts 上下載的略有調(diào)整):

          <!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 = [
                 [12345],
                 [84323],
                 [596103],
                 [97476],
                 [54329]
          ]

          option = {
              xAxis: {
                  max'dataMax',
              },
              yAxis: {
                  type'category',
                  data: ['A''B''C''D''E'],
                  inversetrue,
                  animationDuration300,
                  animationDurationUpdate300,
                  max4 // only the largest 3 bars will be displayed
              },
              series: [{
                  realtimeSorttrue,
                  name'X',
                  type'bar',
                  data: data_list[0],
                  label: {
                      showtrue,
                      position'right',
                      valueAnimationtrue
                  }
              }],
              legend: {
                  showtrue
              },
              animationDuration0,
              animationDurationUpdate3000,
              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 的分類(lèi)就可以實(shí)現(xiàn)自己想要的動(dòng)態(tài)報(bào)表。

          最好懂一點(diǎn) javascript 的語(yǔ)法,這樣可以改一改數(shù)據(jù)的結(jié)構(gòu),更方便的生成自己想要的報(bào)表。

          最后的話(huà)

          要生成報(bào)表,其實(shí)并不需要太精通技術(shù),從網(wǎng)上下載個(gè)模版,自己改下數(shù)據(jù)和分類(lèi),就可以制作一個(gè) html 報(bào)表,然后將 html 作為郵件正文發(fā)送出去,也可以轉(zhuǎn)成圖片、pdf 發(fā)送,具體場(chǎng)景就看自己需求了。如果要批量制作很多同類(lèi)報(bào)表,可以借助 Jinja2 的模版大法,批量替換報(bào)表中的數(shù)據(jù),更高效的完成。

          如果你也在學(xué)習(xí) Python,不妨關(guān)注一下我,每天學(xué)習(xí)一個(gè) Python 技巧。

          推薦閱讀:

          Python自動(dòng)化辦公-玩轉(zhuǎn)圖表

          有問(wèn)題?留言討論


          瀏覽 54
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  好吊爽一区二区三区免费 | 久久久久无码国产精品一区 | 性欧美大战久久久久久久免费观看 | 日韩爽歪歪 | 看90后操逼 |