目录

  • 一、Jinja2
    • 1.1 概述
    • 1.2 语法
      • 1.2.1 变量
      • 1.2.2 控制循环结构
      • 1.2.3 宏
    • 1.3 空行
      • 1.3.1 分析
      • 1.3.2 解决方案
    • 1.4 渲染
    • 1.4.1 渲染函数
    • 1.4.2 继承和super函数
  • 二、word模板
    • 2.1 渲染函数
    • 2.2 表格
      • 2.2.1 动态水平合并
      • 2.2.2 动态垂直合并
    • 2.3 插入图片
  • 三、Excel操作
    • 3.1 概述
    • 3.2 工作簿对象Wrokbook
    • 3.3 表单对象Worksheet
      • 3.3.1 表单对象属性
      • 3.3.2 遍历表格
    • 3.4 单元格对象Cell

一、Jinja2

1.1 概述

  • 模板系统:模板文件中放置特定的占位符、占位语句,python程序文件用变量值来替换模板文件中的占位符
  • Jinja2:由flask作者开发的一款模板语言,原始目的为了web网页开发
  • 安装:pip3 install Jinja2

1.2 语法

  • 语法种类:注释:{# #},变量取值:{{ }},控制结构:{% %}
  • 在Jinja2渲染:传送门,以下语句可在其测试
  • 一个不错的Jinja2博客:传送门

1.2.1 变量

  • 代码示例

    {# 这里是注释的写法,文件名index.html #}
    <p> 来自字典的值:{{ mydict['one'] }}</p>
    <p> 来自列表的值:{{ mylist[0] }}</p>
    <p> 来自对象方法的值:{{ myobj.meth() }}</p>
    

    注意:大括号内两侧的空格是必须的

  • 过滤器表
    过滤器名 说明
    safe 渲染时不转意
    upper、lower、capital 把值全转大写、小写、首字母大写
    title 每个单词首字母大写
    trim 去首位空格
    join 拼接多个值为字符串
    replace 替换字符串值
    round、int 对数字四舍五入、值转成整型
  • 用法
    {{ 11.1 | round | int }}
    >>> 11
    {{ "hello world" | replace("hello", "goodbye") | upper }}
    >>> GOODBYE WORLD
    # names为列表:拼接字符为-
    {{ names | join("-") }}
    # 选列表第一个元素去除两侧空
    {{ ['  a  b'] | first | trim }}
    >>> a  b
    # 在给定宽度内将字符串行居中对齐
    {{ '居中标题' | center }}
    # hosts为列表,添加换行符
    {{ hosts | join('\n') }}
    # 添加默认值
    {{ name | default('duke') }}
    # 默认按键对字典排序:按值排序写法dictsort(by='value')
    {% for key, value in dic | dictsort %}
    # 先管道转换,再比较
    {% if str_value | float >= 4.22 %}
    

    注:过滤器通过管道符与变量连接

1.2.2 控制循环结构

  • if语句

    {% if duke.sick %}duke is sick
    {% elif duke.dead %}duke is dead
    {% else %}duke is ok
    {% endif %}
    

    比较运算符:==, !=, >, >=, <, <=
    逻辑运算符:and, or, not

  • for语句
    {# 遍历列表:语句排版,按没语句块考虑效果 #}
    <ul>
    {% for user in users %}<li>{{ user }}</li>
    {% endfor %}
    </ul>{# 遍历字典 #}
    <ul>
    {% for key, value in users.items() %}{% if loop.first %}<li>这是首轮循环</li>         {% endif %}    <li>当前键为:{{ key }}</li> <li>当前值为:{{ value }}</li>
    {% endfor %}
    </ul>
    

    loop.index:从1开始记录循环次数,loop.index()为从0开始
    loop.first:若为第一次迭代则为True,配合if使用,loop.last
    loop.length:循环次数

  • for + if语句:{% for num in nums if num>10 %}

1.2.3 宏

  • 定义位置:建议集中写在模板的尾部
  • 宏定义
    {% macro input(name, age=18) -%}
    <h1>{{ name }}:{{ age }}</h1>
    {%- endmacro -%}
    
  • 宏使用
    <h1>{{input('duke', 12)}}</h1>
    

1.3 空行

1.3.1 分析

  • 示例
  • 显示:右侧渲染结果有多处空行
  • 原因分析:渲染模板时,所有语言块都将被删除,但所有空都保留在原处。也就是说,如果在块之前或之后有空格、制表符或换行符,都保留

1.3.2 解决方案

  • 方法一:

    • -语句:{%- 语句 %},去除语言块之前的空,{% 语句 -%},去除之后的空(含换行符)
    • 渲染if语句:删除{% if true %}语句块,末尾换行符保留;删除{% if false %}语句块,末尾换行符也删除;删除{% endif %}语句块,不管真假,都保留前后空及换行符
  • 方法二:
    • 启用渲染选项:删除空行trim_blocks,删除块左侧空lstrip_blocks
    • 补充选项:Strict check,若有值未传则报错

1.4 渲染

1.4.1 渲染函数

  • /root/main/main.py

    #!/usr/bin/python
    # -*- codinig: UTF-8 -*-import os
    import sys
    import jinja2# 定义模板渲染函数:模板路径,填充数据以json格式
    def render(tpl_path='index.html', **kwargs):# 拆分路径:路径与文件名path, filename = os.path.split(tpl_path)# 渲染后的文件内容:模板父文件夹路径,模板文件名,传入字典return jinja2.Environment(loader=jinja2.FileSystemLoader(path or './'),trim_blocks=True,lstrip_blocks=True).get_template(filename).render(**kwargs)# 命令行操作函数
    def cmd_format(**data):# 获取命令行参数列表filepath = sys.argv# 若未输入参数就通过if语句用默认模板filepath.append('')if filepath[1]:out = render(filepath[1], **data)print(out)else:out = render(**data)print(out)if __name__ == '__main__':# 数据填充字典:json格式datainput = {'head': "这是标题",'context': "这是内容"}# 这里是命令行方式,也可以直接调用render函数cmd_format(**datainput)
    
  • 模板/root/main/index.html
    <!DOCTYPE html>
    <html lang="en">
    <head><meta charset="UTF-8"><title>{{ head }}</title>
    </head>
    <body><div><h1>{{ context }}</h1></div>
    </body>
    </html>
    
  • 运行python3 main.py
  • 终端输出
    <!DOCTYPE html>
    <html lang="en">
    <head><meta charset="UTF-8"><title>这是标题</title>
    </head>
    <body><div><h1>这是内容</h1></div>
    </body>
    </html>
    

1.4.2 继承和super函数

  • 模板继承:父模板中留block语句块,子模板继承父模板,并只需要写block语句块即可
  • super函数:父模板中block语句块中的语句,在子模板中用{{ super() }}语句可拿到,否则子覆盖父
  • /root/main/index.html
    <!DOCTYPE html>
    <html lang="en">
    <head><meta charset="UTF-8"><title>Title</title>
    </head>
    <body><h1>欢迎</h1><h2>以下是块内容</h2>{% block content %}<h3>这是块内的语句</h3>{%- endblock %}<h2>再见</h2>
    </body>
    </html>
    
  • /root/main/login.html
    {% extends "index.html" %}{% block content %}
    {{ super() }}<form>用户名:<input type="text" name="user">密码:<input type="text" name="pwd"></form>
    {% endblock %}
    
  • 运行python3 main.py login.html
  • 终端输出
    <!DOCTYPE html>
    <html lang="en">
    <head><meta charset="UTF-8"><title>Title</title>
    </head>
    <body><h1>欢迎</h1><h2>以下是内容</h2>   <h3>这是块内的语句</h3>    <form>用户名:<input type="text" name="user">密码:<input type="text" name="pwd"></form>   <h2>再见</h2>
    </body>
    </html>
    

二、word模板

  • docxtpl模块:使用Jinja2思路,以docx为word模板
  • docxtpl 主要依赖两个包:python-docx 用来读写word,jinja2用来管理插入到模板中的标签
  • 官方文档:传送门

  • 语法种类:注释:{#p #},变量取值:{{ }}转义{{ variable|e }}),控制结构:{%p %},p代表段落,否则会出现1.3节的空行现象,注释和控制结构每行只能出现一个,灵活运用1.3.1方法一连接长句子
  • 安装:pip3 install docxtpl

2.1 渲染函数

  • /root/main/main.py

    #!/usr/bin/python
    # -*- codinig: UTF-8 -*-from docxtpl import DocxTemplate
    import sys
    import jinja2# 定义模板渲染函数:模板路径,输出路径,填充数据以字典格式
    def render(tpl_path='index.docx', output='sample.docx', **kwargs):tpl = DocxTemplate(tpl_path)# 添加参数:清除空行jinja_env = jinja2.Environment(trim_blocks=True, lstrip_blocks=True)# 渲染函数:传入数据、jinja2环境变量tpl.render(kwargs, jinja_env)tpl.save(output)print("completed")# 命令行构造函数
    def cmd_format(**data):filepath = sys.argv# 保证有三个参数:防止少于两个参数的话报错filepath.append('')filepath.append('')# 指定:模版文件路径、输出文件路径(路径必须存在,否则报错)if filepath[1] and filepath[2]:render(filepath[1], filepath[2], **data)# 指定:模版文件路径、输出文件为./sample.docxelif filepath[1]:render(filepath[1], **data)# 默认:模版文件./index.docx、输出文件为./sample.docxelse:render(**data)if __name__ == '__main__':# 数据填充字典:json格式datainput = {'head': "内容",'context': "context内容"}# 这里是命令行方式,也可以直接调用render函数cmd_format(**datainput)
    
  • 模版:/root/main/index.docx

  • 运行python3 main.py

  • 输出:/root/main/sample.docx

2.2 表格

  • 模版/root/main/index.docx

2.2.1 动态水平合并

  • 模版写法

    {%tc for col in context %} {% hm %}标题 {%tc endfor %}
    {%tc for col in context %} {{col}} {%tc endfor %}

    hm:水平动态合并,如下图效果

  • 效果

    context:[‘a’, ‘b’, ‘c’]


2.2.2 动态垂直合并

  • 模版写法

    {%tr for row in context %}
    {% vm %}竖标题 {{row}}
    {%tr endfor %}

    hm:水平动态合并,如下图效果

  • 效果

2.3 插入图片

  • 模版:/root/main/index.docx

    {{ title_pic1 }}
    {{ title_pic2 }}
    {{ title_pic3 }}
    
  • 渲染函数
    #!/usr/bin/python
    # -*- codinig: UTF-8 -*-import sys
    import jinja2
    from docxtpl import DocxTemplate, InlineImage
    from docx.shared import Mm, Pt# 定义模板渲染函数:模板路径,输出路径,填充数据以字典格式
    def render(tpl_path='index.docx', output='sample.docx', **kwargs):tpl = DocxTemplate(tpl_path)# 添加参数:清除空行jinja_env = jinja2.Environment(trim_blocks=True, lstrip_blocks=True)# 展开image项的每个子项,重新添加进kwargsif 'images' in kwargs:for pic in kwargs['images']:width = pic.get('width')height = pic.get('height')if width and height:# 给数据字典增加项:图片的单位是像素(Pt)、毫米(Mm)kwargs.setdefault(pic.get('name'), InlineImage(tpl, pic.get('path'), width=Pt(width), height=Pt(height)))elif width:kwargs.setdefault(pic.get('name'), InlineImage(tpl, pic.get('path'), width=Pt(width)))else:kwargs.setdefault(pic.get('name'), InlineImage(tpl, pic.get('path'), height=Pt(height)))del kwargs['images']# 渲染函数:传入数据、jinja2环境变量tpl.render(kwargs, jinja_env)tpl.save(output)print("completed")# 命令行构造函数
    def cmd_format(**data):filepath = sys.argv# 保证有三个参数:防止少于两个参数的话报错filepath.append('')filepath.append('')# 指定:模版文件路径、输出文件路径(路径必须存在,否则报错)if filepath[1] and filepath[2]:render(filepath[1], filepath[2], **data)# 指定:模版文件路径、输出文件为./sample.docxelif filepath[1]:render(filepath[1], **data)# 默认:模版文件./index.docx、输出文件为./sample.docxelse:render(**data)if __name__ == '__main__':# 数据填充字典:json格式datainput = {# 若没有内插图像,则删掉此项,不可为空,否则报错'images': [# 1、指定宽,2、指定高,3、指定宽高{'name': 'title_pic1', 'path': 'pic/test.png', 'height': 100},{'name': 'title_pic2', 'path': 'pic/test.png', 'width': 100},{'name': 'title_pic3', 'path': 'pic/test.png', 'width': 100, 'height': 100}]}# 这里是命令行方式,也可以直接调用render函数cmd_format(**datainput)
    
  • 效果

三、Excel操作

3.1 概述

  • openpyxl:一个读写Excel的python库,安装pip3 install openpyxl
  • 层级
    • Workbook:对工作薄(Excel文件)对象的抽象
    • Worksheet:对表单对象的抽象
    • Cell:对单元格对象的抽象
  • 操作工作簿

3.2 工作簿对象Wrokbook

  • 新建空Excel

    import openpyxl
    # 创建工作簿对象
    wb = openpyxl.Workbook()
    ...
    # 保存工作簿对象
    wb.save("新建表格.xlsx")
    
  • 打开已存在Excel
    import openpyxl
    # 打开已存在的Excel文件并返回工作簿对象
    wb = openpyxl.load_workbook("新建表格.xlsx")
    ...
    wb.save("新建表格.xlsx")
    
  • workbook对象属性
    写法 解释
    wb.read_only 判断文件是否以只读打开,返回布尔值
    wb.encoding 返回文件编码方式,如’utf-8’
    wb.properties 返回文档元数据对象,如作者、创建时间、版本…
    改写wb.properties.version = 1.0
  • 操作Worksheet方法
    # 增表单:第二个参数为插入索引值,可选
    In [1]: wb.create_sheet('boss')
    Out[1]: <Worksheet "boss">###################################################
    # 删表单:方法一,若不存在,报错KeyError
    In [2]: wb.remove(wb['boss'])
    # 方法二:del wb['boss'],若不存在,报错KeyError###################################################
    # 查表单:获取表单名称列表
    In [3]: wb.sheetnames
    Out[3]: ['student', 'teacher']
    # 获取表单对象:以名称方式
    In [4]: wb["student"]
    Out[4]: <Worksheet "student">
    # 获取当前活动表单对象
    In [5]: wb.active
    Out[5]: <Worksheet "student">
    

3.3 表单对象Worksheet

3.3.1 表单对象属性

  • 表单对象属性

    写法 解释
    wb.title 表格标题字符串,例如'student'
    wb.dimensions 返回表格中含有数据的表格大小,例如'A1:D4'
    ws.max_row 返回含数据的最大行数4,还有min_row,max_column,min_column

3.3.2 遍历表格

  • 按行遍历cell对象:按列columns同

    In [1]: for row in ws.rows:...:     print(row)
    # row为每行cell对象的元组,rows为生成器
    (<Cell 'student'.A1>, <Cell 'student'.B1>, <Cell 'student'.C1>, <Cell 'student'.D1>)
    (<Cell 'student'.A2>, <Cell 'student'.B2>, <Cell 'student'.C2>, <Cell 'student'.D2>)
    (<Cell 'student'.A3>, <Cell 'student'.B3>, <Cell 'student'.C3>, <Cell 'student'.D3>)
    (<Cell 'student'.A4>, <Cell 'student'.B4>, <Cell 'student'.C4>, <Cell 'student'.D4>)
    
  • 按行遍历值
    In [2]: for row in ws.values:...:     print(row)
    # row为每行数据的元组,values为生成器
    ('no', 'name', 'chinese', 'math')
    (1, 'duke', 97, 88)
    (2, 'park', 95, 89)
    (3, 'sam', 96, 87)
    
  • 限定范围按行遍历cell对象,iter_rows迭代器
    In [3]: for row in ws.iter_rows(min_row=2,max_row=3,min_col=2,max_col=3):...:     print(row)
    # row为限定数据
    (<Cell 'student'.B2>, <Cell 'student'.C2>)
    (<Cell 'student'.B3>, <Cell 'student'.C3>)
    

3.4 单元格对象Cell

  • 单元格对象属性

    写法 解释
    ws[‘B2’] 获取cell对象,例如<Cell ‘student’.B2>,ws(row=2, column=2) 效果同
    cell.row 获取行数2,cell.column获取列数
    cell.value 获取单元格值'duke'
    cell.coordinate 获取单元格坐标'B2'
  • 通过cell对象获取值
    In [1]: for row in ws.rows:...:     scores = [cell.value for cell in row]...:     print(scores)
    # 跟3.3.2节按行遍历值对比
    ['no', 'name', 'chinese', 'math']
    [1, 'duke', 97, 88]
    [2, 'park', 95, 89]
    [3, 'sam', 96, 87]
    
  • 工作簿到单元格数据
    In [1]: wb = openpyxl.load_workbook("新建表格.xlsx")
    # 链式获取与修改
    In [2]: wb['student'].cell(row=2,column=2).value='jack'
    # 有数据的表格尾部追加
    In [3]: unit = [4, 'smith', 93, 90]
    In [4]: wb['student'].append(unit)
    # 将更改保存到文件
    In [5]: wb.save("新建表格.xlsx")
    

回到总目录

Python运维(五)--Jinja2、word模板及Excel相关推荐

  1. python运维系统开发_Python系统运维开发实战

    课程主题: Python 高级运维开发实战 课程讲师: Alex 老师, triaquae python 开源运维管理软件创始人,知名 IT 公司运维开发架构师 课程安排: 每周六一天全天(早 9:0 ...

  2. Python运维(七)--自动化部署工具Ansible

    目录 一.概述 二. 安装 2.1 控制端 2.2 被控制端 2.3 连接测试(控制端) 三.Inventory管理 3.1 简介 3.2 命令 3.3 服务器匹配 3.4 Inventory行为参数 ...

  3. python运维必须会用的库

    python运维必须会用的库:     1 os,pathlib(系统操作库)     2 logging(运维用到的核心库,用于快速写入日志,非常好用)     3 pymysql,pymssql, ...

  4. python运维看什么书_学习Python在Linux运维上的应用应该看哪些书 什么样的学习路线...

    匿名用户 1级 2017-08-02 回答 Python岗位有哪些呢?主要的岗位有这些: Python全栈开发工程师(10k-20K) Python运维开发工程师(15k-20K) Python高级开 ...

  5. python运维脚本面试_运维开发工程师 面试题 shell编程

    1. 32位随机密码生成 cat /proc/sys/kernel/random/uuid | tr -d '-' 2.查看当前系统每个ip的tcp连接数 -n 强制显示IP地址 -t 显示TCP连接 ...

  6. python运维实战--跨堡垒机连接二级服务器上传文件

    python运维实战--跨堡垒机连接二级服务器上传文件 paramiko的有关概念和操作 Welcome to Paramiko! - Paramiko documentation 这个python脚 ...

  7. 一群热爱python运维的精英们!

    老男孩python运维开发精品培训第三期一部分学员毕业合影留念! 转载于:https://blog.51cto.com/oldboy/1363274

  8. python运维开发之socket网络编程01

    python运维开发之socket网络编程01说明:本文来自来自北京老男孩linux运维实战培训中心-运维开发课程免费视频内容,本文内容为系列内容,更多分享信息见:http://oldboy.blog ...

  9. python运维之轻松模拟开发FTP软件05

       以往众多运维者,大多都是在应用国外已经开发好的软件,如今的国内运维职位已经要求我们具备较强的创新能力,一些日常小工具小软件应该能做到手到拈来,这样我们才能在激烈的竞争中占据有利位置.请看: py ...

  10. python程序员需要掌握哪些技术-python运维要掌握哪些内容

    python运维需要会什么 随着移动互联网的普及,服务器运维所面临的挑战也随之越来越大.当规模增长到一定程度,手动管理方式已经无法应对,自动化运维成为解决问题的银弹. Python凭借其灵活性,在自动 ...

最新文章

  1. Image Watch的使用示例
  2. Java 泛型 super extends 边界
  3. 创建一个storageevent事件_事件循环:微任务和宏任务
  4. 优秀HTML5网站学习范例:从“饥饿游戏浏览器”谈用户体验
  5. 海贼王革命家—龙—实力到底如何?
  6. python 第三方模块之 APScheduler - 定时任务
  7. 一名创业者浴火涅磐的自白——对话阿里云MVP孙琦
  8. python标准库使用教程_Python标准库概览
  9. vue父子组件传值之异步之后子组件无法拿到父组件传的值
  10. [论文笔记]RoBERTa: A Robustly Optimized BERT Pretraining Approach
  11. 适配器模式之解释器模式
  12. 软件需求说明书/ 概要设计说明书/项目开发计划/详细设计说明书模版(说明要点及要点解释)
  13. jsp连接mysql 菜鸟_在JSP中访问数据库大全
  14. linux下用套接字抓arp包,TCP抓包-linux
  15. python三维地质建模_GemPy三维地质建模工具包
  16. 外链式样式表_WEB前端 CSS样式表
  17. pdf转换工具有哪些?试一试这几个方法!
  18. Clickhouse外部储存表引擎(HDFS、MySQL、JDBC、Kafka、File)
  19. HTML网页下,在div标签中嵌套其他html页面
  20. 关于DM36x IPNC中IRCUT的使用

热门文章

  1. excel数据拆分如何快速做?
  2. 基于emq x开源版实现服务重启后主题和消息恢复的完整方案
  3. 【微博SDK调用逻辑】微博SDK的调用逻辑,最好自己还是写一个例子,试一下!!!...
  4. vue - vue3与vue2.x的区别(一) :目录结构不一致
  5. zabbix-agent2监控redis、mongodb
  6. python实现数组键值排序
  7. matlab画图,常用线条样式,导出高清图
  8. 聊聊一道简单的javascript面试题
  9. 吉利星瑞噪音分贝测试软件,吉利星瑞性能测试:确实是最好的自主A级车
  10. 3DMAX和MAYA,你还在纠结选择哪个吗?为什么不看这里的标准答案?