Python学习日志12 - 办公自动化

Python学习日志

RBHGO的主页欢迎关注

温馨提示:创作不易,如有转载,注明出处,感谢配合~

目录

文章目录

    • Python学习日志
      • 目录
        • 前言
        • 进入正题
      • Python学习日志12课 - 办公自动化
        • (1).读写文本文件
          • 读文件
          • 读二进制文件
          • 读取文件(计算MD5哈希码)
          • 写文件
          • 文件复制
        • (2).Python操作CSV文档
          • 读csv文件
          • 写csv文件
        • (3).Python操作Excel文档
          • 读写`.xls`文件
          • Python中的时间
          • 读写`.xlsx`文件
          • Excel生成统计图表
        • (4).Python操作word文档
          • 修改(创建)样本文章
        • (5).Python操作PDF文档
          • 创建PDF文件
          • 基本操作
          • 加密
          • 加水印
        • 总结

前言

上一次我们主要分享的是面对对象的编程,确实是不太好理解,这需要时间的沉淀。在这里还是和大家稍微在提一下重要的地方,首先明白核心的概念类、对象,类是创建对象的模板,对象是可以接受消息的实体,另外要注意的是对象的要素;再就是三步走(定义类、创建对象、给对象发消息),三步走中以定义类的数据抽象和行为抽象最为难做;最后了解三大(四大)支柱,封装、继承、多态、(抽象)。虽然看起来不多的内容,其实可操作性和信息量是巨大的,希望大家都有所感悟,早日能得心应手的运用面对对象编程吧。

进入正题

这篇想和大家分享一些不烧脑的,这也是比较有用的,就是用Python实现办公自动化。其实办公自动化写起来也不是说简单,只是至少你写出来的程序复用性很高,Python实现办公自动化也不敢说很强大,至少他完成了’初心‘,就是帮我们解决重复的劳动步骤,让过程变得愉悦一点。

温馨提示:

以下操作都是基于不使用Python数据分析的神器之一 —> 名为pandas的三方库,这个后面的时候再分享。

Python学习日志12课 - 办公自动化

实际开发中常常会遇到对数据进行持久化的场景,所谓持久化是指将数据从无法长久保存数据的存储介质(通常是内存)转移到可以长久保存数据的存储介质(通常是硬盘)中。实现数据持久化最直接简单的方式就是通过文件系统将数据保存到文件中。用户只需要记住数据被写入到了哪个文件中,我们可以非常方便的通过文件来读写数据,再使用文件系统保存数据。

在Python中要实现文件操作是非常简单的。我们可以使用Python内置的open函数来打开文件,在使用open函数时,我们可以通过函数的参数指定文件名操作模式字符编码等信息,接下来就可以对文件进行读写操作了。这里所说的操作模式是指要打开什么样的文件(字符文件或二进制文件)以及做什么样的操作(读、写或追加),具体如下表所示。

操作(mode= ) 作用效果
'r' 读取 (默认)
'b' 二进制模式(读写分别:rb, wb
't' 文本模式(默认)
'+' 更新(既可以读又可以写)截断w+,前面加r+,追加a+
'x' 写入,如果文件已经存在会产生异常
'w' 写入(文件有内容会先截断之前的内容),无文件会创建
'a' 追加,将内容写入到已有文件内容的末尾,无文件会创建

温馨提示:在使用open函数时,如果打开的文件是字符文件(文本文件),可以通过encoding参数来指定读写文件使用的字符编码。

(1).读写文本文件

读文件
file = open(file='C:/Users/RBHGO/登高.txt', mode='r', encoding='utf-8')
    # 如果读不到数据,read方法会返回None
    # 读文件一部分一部分的读对磁盘比较友好
try:
    data = file.read(16)
    while data:
        print(data, end='')
        data = file.read(16)
	# 在使用完之后,要释放掉空间
finally:
    file.close()

除了使用文件对象的read方法读取文件之外,还可以使用for-in循环逐行读取或者用readlines方法将文件按行读取到一个列表容器中,我提供一种方法,大家有兴趣的话可以试一试其他方法。

温馨提示:很多报错,其实大部分都是路径写错,所以一定要搞清楚文件路径在进行读取,而且建议路径上最好不要有中文名。

读二进制文件

这里顺便分享了如和查看文件的长度(大小),不建议直接使用len()的原因是和为什么要一部分一部分文件是一样的,避免文件过大造成麻烦,和损失。

from io import SEEK_END, SEEK_SET

# 读二进制(字节)文件
file = open(file='C:/Users/RBHGO/66.jpg', mode='rb')
# 移动文件指针从头到尾,seek可以查看文件大小
# 或者也可以写file.seek(0, 2)
file.seek(0, SEEK_END)
# tell告诉指针移动的字节数
print(file.tell())
# 将文件指针移动到文件最开始的位置
# file.seek(0, 0)
file.seek(0, SEEK_SET)

# print(len(file.read())),当读一个长度较大的文件时,这个方法就不如上面的方法
try:
    data = file.read(512)
    while data:
        print(data, end='')
        data = file.read(512)
finally:
    file.close()
读取文件(计算MD5哈希码)

不知道大家下载文件的时候有没有记得,下载那一排内容中都会有一行编码,它的作用就是防伪,如果下下来的文件的编码与网址上的一样说明没问题,相当于身份验证,只是大部分时候我们都懒得验证。

"""
读取Python官方解释器文件,计算MD5哈希码(签名、指纹、摘要)

MD5 Sum文件的 MD5码 ---> 哈希算法(签名、指纹)
以前用MD5码 ---> 现在用SHA-256码(比之前长一倍)

Author: RBHGO
Declaration: Mia San Mia ~~~
"""
from hashlib import md5
hasher = md5()
# hasher2 = sha256()
file = open('C:/language/python-3.9.6-amd64.exe', 'rb')
try:
    data = file.read(512)
    while data:
        # 更新MD5对象数据
        hasher.update(data)
        data = file.read(512)
finally:
    file.close()
# 获得十六进制形式的MD5哈希摘要
print(hasher.hexdigest())
写文件

'w'创建一个文件,'w'的作用是写入如果文件有内容会先截断之前的内容,无文件会创建一个文件,如果写入的是二进制文件就用'wb'

"""
with -> 上下文语法 -> 进入和离开with的时候会自动执行某些操作
下面的写法在离开with上下文的时候,会自动执行file对象的close()方法
'w'是写文件,有文件就替换文件内容,没有文件创建新文件
'a'将文件指针移动到原有文件的末尾再写入新内容,若文件没有也会创建
"""

with open(file='resources/小雨康桥的皮燕子.txt', mode='w', encoding='utf-8') as file:
    file.write('我想做燕子\n')
    file.write('只需简单思想\n')
    file.write('只求风中流浪\n')
    file.write('我想做树\n')
    file.write('不长六腑五脏\n')
    file.write('不会寸断肝肠\n')
    file.write('我做不成燕子\n ')
    file.write('所以我飞不过感情的壤\n')
    file.write('我做不成树\n')
    file.write('因此也撑不破伤心的网\n')

想在文件原有的内容后加上新内容可以使用'a',它的作用就是追加,将内容写入到已有文件内容的末尾,无文件也会创建一个文件。

with open('resources/小雨康桥的皮燕子.txt', mode='a', encoding='utf-8') as file:
    # 不想用'a'追加的话,可以用'r+'加上移动指针到结尾来追加
    file.seek(0, 2)
    file.write('来生做燕子吧\n')
    file.write('随意找棵树休息翅膀\n ')
    file.write('然后淡然飞向远方\n')
    file.write('来生做树吧\n')
    file.write('当枝头燕子飞走时\n')
    file.write('再不去留念的张望\n')
文件复制
def file_copy(source_file, target_file):
    """文件拷贝"""
    with open(source_file, mode='rb') as source:
        with open(target_file, mode='wb') as target:
            data = source.read(512)
            while data:
                target.write(data)
                data = source.read(512)


if __name__ == '__main__':
    file_copy('resources/小雨康桥的皮燕子.txt',
              'C:/Users/RBHGO/Desktop/小雨康桥的皮燕子.txt')

(2).Python操作CSV文档

CSV(Comma Separated Values)全称逗号分隔值文件是一种简单、通用的文件格式,被广泛的应用于应用程序(数据库、电子表格等)数据的导入和导出以及异构系统之间的数据交换。

CSV文件有以下特点:

  1. 纯文本,使用某种字符集(如ASCII、Unicode、GB2312)等);
  2. 由一条条的记录组成(典型的是每行一条记录);
  3. 每条记录被分隔符(如逗号、分号、制表符等)分隔为字段(列);
  4. 每条记录都有同样的字段序列。
读csv文件
# 自己做拆分
with open('resources/2018年北京积分落户数据.csv', encoding='utf-8') as file:
    content = file.readline()
    while content:
        values = content.replace('\n', '').split(',')
        print(values)
        content = file.readline()

还有一种方法,是通过csv模块的reader函数可以创建出csvreader对象,该对象是一个迭代器,可以通过next函数或for-in循环读取到文件中的数据。

# 使用CSV模块
import csv
# 如果用utf-8编码,这里可能会有问题!!!所以编码设置为utf-8-sig,带签名的utf-8
with open('resources/2018年北京积分落户数据.csv', encoding='utf-8-sig') as file:
    # 参数delimiter -> 设置分割符(默认是逗号)
    # 如果文件内不是逗号分隔,如是#号分隔时:reader = csv.reader(file, delimeter='#')
    # 参数quotechar -> 包裹字符串的符号(默认是英文的双引号) -> 去掉字符串里的多余符号
    reader = csv.reader(file)
    for row in reader:
        print(row)
写csv文件

使用Python标准库中的csv模块,该模块的writer函数会返回一个csvwriter对象,通过该对象的writerowwriterows方法就可以将数据写入到CSV文件中

"""
写CSV文件
writerow方法的参数是一个列表或元组(代表一行中所有的数据,默认用逗号分隔)

Author: RBHGO
Declaration: Mia San Mia ~~~
"""
import csv

with open('resources/temperature.txt', encoding='utf-8') as file1:
    with open('resources/result.csv', 'w', encoding='utf-8', newline='') as file2:
        writer = csv.writer(file2, delimiter='|')
        writer.writerow(['ID', 'temperature', 'information'])
        content = file1.readline()
        while content:
            no, temp = content.split()
            temp = float(temp)
            if temp >= 37.2:
                if temp <= 38.5:
                    info = '发热'
                else:
                    info = '高热'
                writer.writerow([no, temp, info])
            content = file1.readline()

(3).Python操作Excel文档

掌握用Python程序操作Excel文件,可以让日常办公自动化的工作更加轻松愉快,而且在很多商业项目中,导入导出Excel文件都是特别常见的功能。Python操作Excel需要三方库的支持,如果要兼容Excel 2007以前的版本,也就是xls格式的Excel文件,可以使用三方库xlrdxlwt,前者用于读Excel文件,后者用于写Excel文件。如果使用较新版本的Excel,即操作xlsx格式的Excel文件,也可以使用openpyxl库,当然这个库不仅仅可以操作Excel,还可以操作其他基于Office Open XML的电子表格文件。

读写.xls文件

读取并显示该早版本的Excel文件的内容,可以通过如下所示的代码来完成

"""
Python操作 Excel(读取)
三方库:
- xlrd / xlwt / xlutils ---> 兼容低版本的Excel文件(xls)
- openpyxl ---> office 2007+ ---> xlsx

Author: RBHGO
"""
import xlrd

# 工作簿 ---> 一个Excel文件 ---> (Work)book
wb = xlrd.open_workbook('resources/阿里巴巴2020年股票数据.xls')
# 获取所有工作表的名字
print(wb.sheet_names())
# 获取指定的工作表---> Worksheet
wb.sheet_by_name('Sheet1')  # 按名字拿
sheet = wb.sheet_by_index(0)  # 按索引拿
print(type(sheet))
# 获取工作表的行数和列数
print(sheet.nrows, sheet.ncols)
# 获取指定的行 ---> Row
print(sheet.row(0))
print(sheet.row_slice(0, start_colx=0, end_colx=3))
# 获取指定的列 ---> Column
print(sheet.col(4))
print(sheet.col(4, start_rowx=1, end_rowx=11))
# 获取单元格的数据 ---> Cell ---> value
print(sheet.cell(2, 2))

# 遍历整个表单
print(f'交易日期\t\t\t最高价\t最低价\t开盘价\t收盘价\t成交量\t\t调整收盘价')
for row in range(1, sheet.nrows):
    for col in range(sheet.ncols):
        value = sheet.cell(row, col).value
        if col == 0:
            year, month, date, *_ = xlrd.xldate_as_tuple(value, 0)
            print(f'{
       year}{
       month:0>2d}{
       date:0>2d}日', end='\t')
        elif col == 5:
            print(f'{
       int(value):<10d}', end='\t')
        else:
            print(f'{
       value:.2f}', end='\t')
    print()

写入Excel文件可以通过xlwt 模块的Workbook类创建工作簿对象,通过工作簿对象的add_sheet方法可以添加工作表,通过工作表对象的write方法可以向指定单元格中写入数据,最后通过工作簿对象的save方法将工作簿写入到指定的文件或内存中。

"""
Python操作 Excel(编写)

Author: RBHGO
"""
import xlwt
import random

# 第一步:创建工作簿(Workbook)
wb = xlwt.Workbook()

# 第二步:添加工作表(Worksheet)
sheet = wb.add_sheet('期末成绩')  # type: xlwt.Worksheet

# 第三步:向单元格写入数据
header_style = xlwt.XFStyle()
header_pattern = xlwt.Pattern()
header_pattern.pattern = xlwt.Pattern.SOLID_PATTERN
header_pattern.pattern_fore_colour = 2
header_style.pattern = header_pattern
header_font = xlwt.Font()
# 字体颜色
header_font.colour_index = 1
header_style.font = header_font


titles = ('姓名', '语文', '英语', '数学')
for col_index, title in enumerate(titles):
    sheet.write(0, col_index, title, header_style)

for row_index in range(1, 6):
    name = input('学生姓名:')
    sheet.write(row_index, 0, name)
    for col_index in range(1, 4):
        sheet.write(row_index, col_index, random.randrange(50, 101))


# 第四步:保存工作簿
wb.save('resources/一年级二班考试成绩.xls')
Python中的时间

既然提到了时间,就顺便分享一下日期时间模块

from datetime import datetime
date1 = datetime(1999, 11, 1)
print(date1)
date2 = datetime(1989, 9, 13, 23, 59, 59)
print(date2)
date3 = datetime.now()
print(date3)

# 两个日期相减会得到时间差对象(timedelta)
delta = date3 - date2
print(delta, type(delta))

# 获取两个日期相差的天数和时间相差的秒数
print(delta.days, delta.seconds)

# 格式化时间日期
print(date2.strftime('%Y年%m月%d日%H时%M分%S秒'))

在写Excel文件时,我们还可以为单元格设置样式,主要包括字体(Font)、对齐方式(Alignment)、边框(Border)和背景(Background)的设置,xlwt对这几项设置都封装了对应的类来支持。要设置单元格样式需要首先创建一个XFStyle对象,再通过该对象的属性对字体、对齐方式、边框等进行设定。这是一个比较复杂的过程,但是只要你做好一次,程序是可以进行复用的,只要改一下参数,不同要求下属于你的样式就会一直跟随你。

"""
Python操作Excel改变单元格状态(样式) ---> xls

Author: RBHGO
"""
import xlrd
import xlwt


def get_status_by_temp(temp):
    """温度状态"""
    if temp < 37.2:
        status_info = '正常'
    elif temp < 38.5:
        status_info = '发热'
    else:
        status_info = '高热'
    return status_info


def get_style_by_temp(temp):
    """温度颜色"""
    style = xlwt.XFStyle()
    font = xlwt.Font()
    if temp < 37.2:
        # font.colour_index = xlwt.Style.colour_map['green']
        font.colour_index = 3
    elif temp < 38.5:
        font.colour_index = 5
    else:
        font.colour_index = 2
    style.font = font
    return style


def main():
    wb1 = xlrd.open_workbook('resources/体温测量登记表.xls')
    sheet1 = wb1.sheet_by_index(0)
    data = []
    for row in range(1, sheet1.nrows):
        record = []
        for col in range(sheet1.ncols):
            record.append(sheet1.cell(row, col).value)
        data.append(record)

    wb2 = xlwt.Workbook()
    sheet2 = wb2.add_sheet('带颜色标记的体温数据')
    sheet2.write(0, 0, '编号')
    sheet2.write(0, 1, '体温')
    sheet2.write(0, 2, '状态')

    counter = 0
    for row_index, record in enumerate(data):
        no, temp = record
        if temp >= 37.2:
            counter += 1
        sheet2.write(row_index + 1, 0, no)
        sheet2.write(row_index + 1, 1, temp, get_style_by_temp(temp))
        sheet2.write(row_index + 1, 2, get_status_by_temp(temp))

    sheet2.write(102, 0, '异常人数')
    sheet2.write(102, 1, f'{
       counter}人')
    sheet2.write(103, 0, '总人数')
    sheet2.write(103, 1, f'{
       len(data)}人')

    wb2.save('resources/体温测量登记表汇总.xls')


if __name__ == '__main__':
    main()

既然能操作单元格,让Excel做一些运算自然也是可以的。

"""
Python操作Excel读写(进行运算) ---> xls

Author: RBHGO
"""

import xlrd
import xlwt
from xlutils.copy import copy

wb1 = xlrd.open_workbook('resources/一年级二班考试成绩表.xls')
# type:是告诉电脑对象的类型,否则会出现后面没有代码提示的问题
wb2 = copy(wb1)  # type: xlwt.Workbook
sheet = wb2.get_sheet(0)
sheet.write(0, 4, '平均分')
for row_index in range(1, 6):
    sheet.write(row_index, 4, xlwt.Formula(f'average(B{
       row_index + 1}:D{
       row_index + 1})'))
wb2.save('resources/一年级二班考试成绩表.xls')
读写.xlsx文件

使用openpyxl库对Excel文件进行读写。

"""
读取Excel文件(xlsx)

Author: RBHGO
"""
import openpyxl
import datetime

# 加载一个工作簿 ---> Workbook
wb = openpyxl.load_workbook('resources/阿里巴巴2017年股票数据.xlsx')
print(type(wb))
# 获取工作表的名字
print(wb.sheetnames)
# 获取工作表 ---> Worksheet
sheet = wb.worksheets[0]
# sheet = wb['Sheet1']  # 会失去代码提示
print(type(sheet))
print(sheet.max_row, sheet.max_column)
# 头尾在Excel中的位置
print(sheet.dimensions)

# 循环遍历所有的单元格(用openpyxl范围是从一开始数)
# print(f'交易日期\t\t\t开盘价\t最高价\t最低价\t收盘价\t调整收盘价\t\t成交量')
# for row in range(2, sheet.max_row + 1):
#     for col in range(1, sheet.max_column + 1):
#         value = sheet.cell(row, col).value
#         if col == 1:
#             print(value.strftime('%Y年%m月%d日'), end='\t')
#         elif col == 6:
#             print(f'{int(value):<10d}', end='\t')
#         else:
#             print(f'{value:.2f}', end='\t')
#     print()

# 第二种遍历方法
for row_ch in range(1, 253):
    for col_ch in 'ABCDEFG':
        value = sheet[f'{
       col_ch}{
       row_ch}'].value
        if type(value) == datetime.datetime:
            print(value.strftime('%Y年%m月%d日'), end='\t')
        elif type(value) == int:
            print(f'{
       value:<10d}', end='\t')
        elif type(value) == float:
            print(f'{
       value: .4f}', end='\t')
        else:
            print(value, end='\t\t')
    print()

openpyxl库包括了读写操作,而且读写用一个方法cell

"""
写Excel文件(xlsx)

Author: RBHGO
"""
import random
import openpyxl

# 第一步:创建工作簿(Workbook)
wb = openpyxl.Workbook()

# 第二步:添加工作表(Worksheet)
# sheet = wb.create_sheet('期末成绩')
sheet = wb.active
sheet.title = '期末成绩'

titles = ('姓名', '语文', '数学', '英语')
for col_index, title in enumerate(titles):
    sheet.cell(1, col_index + 1, title)

names = ('关羽', '张飞', '赵云', '马超', '黄忠')
for row_index, name in enumerate(names):
    sheet.cell(row_index + 2, 1, name)
    for col_index in range(1, 4):
        sheet.cell(row_index + 2, col_index + 1, random.randrange(50, 101))

# 第四步:保存工作簿
wb.save('resources/一年级二班考试成绩表.xlsx')

openpyxl库实现单元格样式改变

"""
操作Excel改变单元格状态(样式) ---> xlsx

Author: RBHGO
"""
import openpyxl
from openpyxl.styles import Font, Alignment, Border, Side

# 对齐
alignment = Alignment(horizontal='center', vertical='center')
# 字体
side = Side(color='ff7f50', style='mediumDashed')

wb = openpyxl.load_workbook('resources/一年级二班考试成绩表.xlsx')
sheet = wb.worksheets[0]

sheet.row_dimensions[1].height = 30
sheet.column_dimensions['E'].width = 120

sheet['E1'] = '平均分'
sheet.cell(1, 5).font = Font(size=18, bold=True, color='ff1493', name='HYj1gf')
sheet.cell(1, 5).alignment = alignment
sheet.cell(1, 5).border = Border(left=side, top=side, right=side, bottom=side)
for i in range(2, 7):
    sheet[f'E{
       i}'] = f'=average(B{
       i}:D{
       i})'
    sheet.cell(i, 5).font = Font(size=12, color='4169e1', italic=True)
    sheet.cell(i, 5).alignment = alignment

wb.save('resources/一年级二班考试成绩表.xlsx')

openpyxl库实现运算

"""
操作Excel读写(进行运算) ---> xlsx

Author: RBHGO
"""
import openpyxl

wb = openpyxl.load_workbook('resources/一年级二班考试成绩表.xlsx')
sheet = wb.worksheets[0]

sheet['E1'] = '平均分'
for i in range(2, 7):
    sheet[f'E{
       i}'] = f'=average(B{
       i}:D{
       i})'
Excel生成统计图表

我们都知道Excel不仅仅用来处理数据很方便,同时也可拿来做数据分析的工作;其中同通过数据生成透视表,还有柱状图、折线图、饼图都是可以实现的。我们以柱状图作为例子,从openpyxl库的openpyxl.chart方法中导入BarChart模块来操作Excel生成图,然后导入的Reference模块来对图形进行定制(表头、标题、颜色等)。

"""
Python操作Excel生成统计图表
    - 透视表:根据A -> 统计B

Author: RBHGO
"""
from openpyxl import Workbook
from openpyxl.chart import BarChart, Reference

wb = Workbook(write_only=True)
ws = wb.create_sheet()

rows = [
    ('类别', '销售A组', '销售B组'),
    ('手机', 50, 100),
    ('平板', 50, 60),
    ('笔记本', 80, 70),
    ('外设', 200, 180),
]

for row in rows:
    ws.append(row)

chart1 = BarChart()
chart1.type = 'col'
chart1.style = 10
chart1.title = '销售统计图'
chart1.y_axis.title = '销量'
chart1.x_axis.title = '商品类别'

data = Reference(ws, min_col=2, min_row=1, max_row=5, max_col=3)
cats = Reference(ws, min_col=1, min_row=2, max_row=5)
chart1.add_data(data, titles_from_data=True)
chart1.set_categories(cats)
chart1.shape = 4
ws.add_chart(chart1, 'A10')

wb.save('resources/demo.xlsx')

(4).Python操作word文档

掌握用Python程序操作Word文件,同样可以让日常学习、办公自动化的工作更加轻松愉快,其中经典的应该就是修改样本文章,快速生成多个样本文章,再数量较大的情况下这样重复的工作的工作量会减轻不少。通常我们处理word会下载python-docx库,使用Document模块来进行操作;如果还要处理图片就需要pillow库。

"""
用 Python处理 word
安装三方库 -> python-docx ---> pip install pythor-docx pillow
pillow ---> PIL ---> Python Image Library ---> 处理图像

Author: RBHGO
"""
from docx import Document
from docx.shared import Cm
# 因为他不是一个类,而是一个函数,得指定真正的document告诉计算机,才会有代码提示
# 因为名字冲突,还得创建一个别名
from docx.document import Document as Doc

# 创建文件
document = Document()  # type: Doc

# 加大标题
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'
)

# 添加图片
document.add_picture('C:/users/RBHGO/66.jpg', width=Cm(3.75))

# 创建表格
records = (
    (3, '101', 'Spam'),
    (7, '422', 'Eggs'),
    (4, '631', 'Spam, spam, eggs, and spam')
)

table = document.add_table(rows=1, cols=3)
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('resources/demo.docx')
修改(创建)样本文章

修改样本文章的要点就在于,不能直接修改文本,这样会改变文本原本的设置,照成我们不想要的效果。run方法就是答案,只把要修改的一段拿出来修改,这样修改过的文本不会改变原本设置,得到我们想要的结果。

"""
修改样板文章

Author: RBHGO
"""
from docx import Document
from docx.document import Document as Doc

doc = Document('resources/离职证明.docx')  # type: Doc
# for i, p in enumerate(doc.paragraphs):
#     print(i, p.text)
# 不能直接改文本,应该只改段落中的一段
for p in doc.paragraphs:
    if '普通猪' in p.text:
        for run in p.runs:
            if '普通猪' in run.text:
                run.text = run.text.replace('普通猪', 'GG_Bond')
doc.save('resources/离职证明.docx')

了解了修改,自然要知道如何生成。

"""
生成样本模板

Author: RBHGO
"""
from docx import Document
from docx.document import Document as Doc

employees = [
    {
     
        'name': 'RBHGO',
        'id': '******************',
        'sdate': '2021年7月19日',
        'edate': '2021年12月10号',
        'department': '市场研究公司数据部',
        'position': 'Python数据分析师'
    }
    {
     
        'name': 'MESSI',
        'id': '******************',
        'sdate': '2000年9月',
        'edate': '2021年8月10号',
        'department': '巴塞罗那足球运动员',
        'position': '全能前场'
    }

]

for emp_dict in employees:
    doc = Document('resources/离职证明模板.docx')  # type: Doc
    for p in doc.paragraphs:
        if '{' not in p.text:
            continue
        for run in p.runs:
            if '{' not in run.text:
                continue
            # 将占位符换成实际内容
            start, end = run.text.find('{'), run.text.find('}')
            key, place_holder = run.text[start + 1:end], run.text[start:end + 1]
            run.text = run.text.replace(place_holder, emp_dict[key])

    doc.save(f'resources/{
       emp_dict["name"]}离职证明.docx')

(5).Python操作PDF文档

PDF也是一种比叫常用的文档类型,无论是学习、工作中,重要的文件大多是以PDF的形式呈现的;还有一个就是简历,我们投放的线上简历,大多公司要求的也是以PDF文档的类型呈现的。在Python中我们可以下载PyPDF2库来实现对PDF文档的操作,这里主要讲给PDF设置密码或者设置水印。

创建PDF文件

创建PDF文档需要三方库reportlab的支持,该库的使用方法可以参考它的官方文档,安装的方法如下所示。

pip install reportlab

下面通过一个例子为大家展示reportlab的用法。

import random

from reportlab.lib import colors
from reportlab.lib.pagesizes import A4
from reportlab.pdfgen import canvas
from reportlab.platypus import Table, TableStyle

# 创建Canvas对象(PDF文档对象)
doc = canvas.Canvas('demo.pdf', pagesize=A4)
# 获取A4纸的尺寸
width, height = A4
# 读取图像
image = canvas.ImageReader('guido.jpg')
# 通过PDF文档对象的drawImage绘制图像内容
doc.drawImage(image, (width - 250) // 2, height - 475, 250, 375)
# 设置字体和颜色
doc.setFont('Helvetica', 32)
doc.setFillColorRGB(0.8, 0.4, 0.2)
# 通过PDF文档对象的drawString输出字符串内容
doc.drawString(10, height - 50, "Life is short, I use Python!")
# 保存当前页创建新页面
doc.showPage()
# 准备表格需要的数据
scores = [[random.randint(60, 100) for _ in range(3)] for _ in range(5)]
names = ('Alice', 'Bob', 'Jack', 'Lily', 'Tom')
for row, name in enumerate(names):
    scores[row].insert(0, name)
scores.insert(0, ['Name', 'Verbal', 'Math', 'Logic'])
# 创建一个Table对象(第一个参数是数据,第二个和第三个参数是列宽和行高)
table = Table(scores, 50, 20)
# 设置表格样式(对齐方式和内外边框粗细颜色)
table.setStyle(TableStyle([
    ('ALIGN', (0, 0), (-1, -1), 'CENTER'),
    ('INNERGRID', (0, 0), (-1, -1), 0.25, colors.red),
    ('BOX', (0, 0), (-1, -1), 0.25, colors.black)
]))
table.split(0, 0)
# 通过Table对象的drawOn在PDF文档上绘制表格
table.drawOn(doc, (width - 200) // 2, height - 150)
# 保存当前页创建新页面
doc.showPage()
# 保存PDF文档
doc.save()

温馨提示:上面的代码使用了很多字面常量来指定位置和尺寸,在商业项目开发中应该避免这样的硬代码(hard code),因为这样的代码可读性差,维护难。如果需要动态生成PDF文档且PDF文档的格式是相对固定的,可以将上面的字面常量处理成符号常量。

记住:符号常量优于字面常量。Python语言没有内置定义常量的语法,但是可以约定变量名使用全大写字母的变量就是常量。

基本操作

下面的例子是一些对PDF的基本操作。

代码中通过创建PdfFileReader对象的方式来读取PDF文档,该对象的getPage方法可以获得PDF文档的指定页并得到一个Page对象,利用Page对象的rotateClockwiserotateCounterClockwise方法可以实现页面的顺时针和逆时针方向旋转

"""
Python操作 -> PDF文件
读取PDF并抽取文字
pip install pypdf2

Author: RBHGO
"""
import PyPDF2

from PyPDF2.pdf import PageObject

# 读取PDF文件
reader = PyPDF2.PdfFileReader('resources/XGBoost.pdf')
# 写入PDF文件
writer = PyPDF2.PdfFileWriter()
for page_num in range(reader.numPages):
    current_page = reader.getPage(page_num)  # type: PageObject
    # 从页面中抽取文字
    # print(current_page.extractText()
    # 页面旋转90度
    current_page.rotateClockwise(90)
    writer.addPage(current_page)
    # 添加空白页
    writer.addBlankPage()
with open('resources/XGBoost-modified.pdf', 'wb') as file:
    writer.write(file)
加密

对单个或者多个PDF文档加上密码,使用PyPDF2中的PdfFileWrite对象可以为PDF文档加密,通过使用PyPDF2库中的encrypt方法,这样就可以同时给多个文档加密。

"""
给多个文件加密码

Author: RBHGO
"""
import PyPDF2

names = ('XGBoost', 'healthy')
for name in names:
    reader = PyPDF2.PdfFileReader(f'resources/{
       name}.pdf')
    writer = PyPDF2.PdfFileWriter()
    for page_num in range(reader.numPages):
        writer.addPage(reader.getPage(page_num))

    writer.encrypt('456654852258753951')
    with open(f'resources/{
       name}-encrypted.pdf', 'wb') as file:
        writer.write(file)
加水印

对单个或者多个PDF文档加上水印,通过使用PyPDF2库中的mergePage方法,其实也就是讲要操作的PDF与水印PDF文档进行合并,这样就得到了加水印的文档,加上遍历这样就可以同时给多个文档加密,和加上密码的操作差不多。

"""
多个文件加水印

Author: RBHGO
"""

import PyPDF2

from PyPDF2.pdf import PageObject

names = ('XGBoost', 'healthy')
for name in names:
    reader1 = PyPDF2.PdfFileReader(f'resources/{
       name}.pdf')
    reader2 = PyPDF2.PdfFileReader('resources/watermark.pdf')
    writer = PyPDF2.PdfFileWriter()

    watermark_page = reader2.getPage(0)
    for page_num in range(reader1.numPages):
        current_page = reader1.getPage(page_num)  # type: PageObject
        # 通过合并PDF添加水印
        current_page.mergePage(watermark_page)
        writer.addPage(current_page)

    with open(f'resources/{
       name}-watermarked.pdf', 'wb') as file:
        writer.write(file)

总结

通过读写文件的操作,我们可以实现数据持久化。在Python中可以通过open函数来获得文件对象,可以通过文件对象的readwrite方法实现文件读写操作。CSV文件的应用比较广泛,大家需要了解CSV文件可以使用文本编辑器或类似于Excel电子表格这类工具打开和编辑,当使用Excel这类电子表格打开CSV文件时,你甚至感觉不到CSV和Excel文件的区别。Python程序操作Excel的方法,可以解决日常办公中很多繁琐的处理Excel电子表格工作,最常见就是将多个数据格式相同的Excel文件合并到一个文件以及从多个Excel文件或表单中提取指定的数据。同样Python也可以对Word、PDF、PPT等多种文档形式进行操作,当然都只是简单的操作,本意本来就是帮大家解决重复劳动问题的。上面只是和大家分享Python可以用来实现办公自动化,没把也没办法把每一种方法都介绍的非常的详细,因为做法实在是太多,如果您对某一项很有兴趣,就去着手学习吧,没有很难的思想,只是方法和模块很多。我们没有必要把每一招都记下来,需要的时候马上看一看,只要做出一个,基本上都可以实现复用的;还在做重复工作的你心动了么?快去试一试办公自动化吧!

感谢学习陪伴,您的点赞,评论就是我更新的动力

你可能感兴趣的:(Python学习日志,python,办公软件,经验分享)