Python学习第四周总结:办公自动化
办公自动化(Office Automation)
办公自动化
:将
现代化办公
和
计算机技术
结合起来的一种新型的办公方式。
简单来说,办公自动化主要是解决重复的简单的乏味的操作。
数据持久化:将内存中的数据模型转换为存储模型,以及将存储模型转换为内存中的数据模型的统称。内存中的数据不是持久的,将内存中的data转换到磁盘中。
- 通过文件系统将数据保存在文件中
读取文件的操作模式
| 操作模式 | 具体含义 |
|---|---|
|
读取 (默认) |
|
写入(会先截断之前的内容) |
|
写入,如果文件已经存在会产生异常 |
|
追加,将内容写入到已有文件的末尾 |
|
二进制模式 |
|
文本模式(默认) |
|
更新(既可以读又可以写) |
sys
– 系统特定的参数和功能
sys.getdefaultencoding()
:检查本地电脑Python默认使用的编码
import sys
print(sys.getdefaultcoding()) # utf-8, 这是我电脑的默认编码
-
open()
:打开文件,打开成功可进行读写操作;失败会引发异常。-
file = open('文件名', mode='操作模式', encoding='编码')
-
-
read()
:读取文件-
print(file.read(num))
:
num
表示需要读取的字符数,不填时输出全部字符
-
-
close()
:文件使用结束后,释放文件,也就是关闭文件。
文本操作
1.读取文本文件.txt(字符文件)
file = open('day01/resources/致橡树.txt', 'r', encoding='utf-8')
try:
# 如果读不到数据,read方法会返回None
data = file.read(32)
# 如果读到数据就运行循环,如果读不到数据,read方法会返回None,结束循环
while data:
print(data, end='')
data = file.read(32)
finally:
file.close()
finally —> 总是执行代码(不管正常异常,finally中的代码一定会被执行到)
2.读取二进制文件(字节文件)
# rb:读取二进制文件,r->read读,b->二进制
file = open('resources/long.jpg', mode='rb')
try:
data = file.read(1024)
while data:
print(data, end='')
data = file.read(1024)
finally:
file.close()
- 如果希望获得文件的字节数,可以先用seek方法将文件指针移动到文件末尾
- 然后通过tell方法获取文件指针移动的字节数,这个字节数就是文件的大小
- 获取字节数结束后,要将文件指针移动到原位
from io import SEEK_END, SEEK_SET
file = open('resources/long.jpg', mode='rb')
file.seek(0, SEEK_END) # (0, 2)
print(file.tell()) # 70051
file.seek(0, SEEK_SET) # (0, 0)
print(file.tell()) # 0
3.写文本文件
with用法
with – 上下文语法 – 进入和离开with的时候会自动执行某些操作,下面的写法在离开with上下文的时候,会自动执行file对象的close()方法
with 语句适用于对资源进行访问的场合,确保不管使用过程中是否发生异常都会执行必要的“清理”操作,释放资源,比如文件使用后自动关闭/线程中锁的自动获取和释放等。使用with的话,能够减少冗长,还能自动处理上下文环境产生的异常。
- 操作模式 – w – 创建新文件或截断原有文件的内容再进行写入
with open('春暖花开,面朝大海.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')
- 操作模式 – a – 创建新文件或将文件指针移动到原有文件的末尾再写入新内容,追加
with open('春暖花开,面朝大海.txt', mode='a', encoding='utf-8') as file:
file.write('愿你有一个灿烂的前程\n')
file.write('愿你有情人终成眷属\n')
小练习
文件复制小函数
def file_copy(source_file, target_file):
"""文件拷贝"""
with open(source_file, 'rb') as source:
with open(target_file, 'wb') as target:
data = source.read(512)
while data:
target.write(data)
data = source.read(512)
if __name__ == '__main__':
file_copy('long.jpg', 'day01/long.jpg')
异常值处理
如果
open
函数指定的文件并不存在或者无法打开,那么将引发异常状况导致程序崩溃。可以
使用Python的异常机制对可能在运行时发生状况的代码进行适当的处理
。
try:
file = []
except FileNotFoundError:
print('无法打开指定文件!')
finally:
file.close()
-
try
:将运行时会出现状况的代码放入 -
except
:捕获异常并进行相应的处理,可使用多个
except
-
finally
:关闭打开的文件,释放掉程序中获取的外部资源,无论发生异常还是未发生异常都会执行下面的代码块。
读写csv文件(逗号分隔值) —>
Comma Seperated Value
Comma Seperated Value
CSV文件有以下特点:
-
纯文本,使用某种字符集(如
ASCII
、
Unicode
、
GB2312
)等); - 由一条条的记录组成(典型的是每行一条记录);
- 每条记录被分隔符(如逗号、分号、制表符等)分隔为字段(列);
- 每条记录都有同样的字段序列。
-
delimiter
—> 设置分隔符(默认是英文的逗号) -
quotechar
—>包裹字符串的符号(默认是英文的双引号) -
row
—> 表示行号;
col
—> 表示列号 -
newline=''
—> 对csv进行写操作时,删除出现的空行 -
writerow
—> 添加参数到csv文件,该方法的参数是一个列表或元组(代表一行中所有的数据,默认用逗号分割)
读csv文件
import csv
with open('resources/2018年北京积分落户数据2.csv', 'r', encoding='utf-8-sig') as file:
reader = csv.reader(file, delimiter='#', quotechar='|')
for row in reader:
print(row)
写csv文件
用一案例引入写操作
将五个学生三门课程的考试成绩需要保存到一个CSV文件中,成绩随机数选取。
with open('day02/resources/score2.csv', 'w', encoding='utf-8-sig', newline='') as file2:
writer = csv.writer(file2, delimiter=',')
# writerow方法的参数是一个列表或元组(代表一行中所有的数据,默认用逗号分割)
writer.writerow(['姓名', '语文', '数学', '英语', '平均分'])
names = ['关羽', '张飞', '赵云', '马超', '黄忠']
for i in range(5):
Chinese = random.randint(50, 100)
Math = random.randint(40, 100)
English = random.randint(60, 100)
writer.writerow([names[1], Chinese, Math, English])
Python操作Excel文件
Excel是Microsoft(微软)为使用Windows和macOS操作系统开发的一款电子表格软件。
第三方库:
-
xlrd
和
xlwt
:是对
xls
格式的Excel文件操作,前者用于读操作,后者用于写操作。 -
openpyxl
:是对
xlsx
格式的Excel文件操作,可直接进行读写操作。
安装:(可以在
Terminal
终端机上下载)
pip install xlwt xlrd xlutils openpyxl
读取Excel文件(
.xls
格式)
.xls
-
xlrd.open_workbook('xls文件')
:打开指定的Excel文件并获取Book对象(工作簿) -
wb.sheet_names()
:获取所有工作表的名字 -
wb.sheet_by_index()
:获取指定的工作表-sheet -
sheet.nrows
:获取工作表的行数 -
sheet.ncols
:获取工作表的列数 -
sheet.row(0)
:获取指定的行 -
sheet.row_slice(0, start_colx=0, end_colx=3)
:获取指定的行的几列 -
sheet.col(0)
:获取指定的列 -
sheet.col_slice(0, start_rowx=1, end_rowx=11)
:获取指定的列的几行 -
sheet.cell(2, 2)
:获取指定
cell
对象(单元格,带标签,不是值,) -
sheet.cell(2, 2).value
:获取单元格中的值
import xlrd
wb = xlrd.open_workbook('day02/temp/阿里巴巴2020年股票数据.xls')
print(type(wb)) # <class 'xlrd.book.Book'>
print(wb.sheet_names()) # ['Sheet1']
sheet = wb.sheet_by_index(0)
print(type(sheet))
print(sheet.nrows, sheet.ncols)
print(sheet.row(0))
print(sheet.row_slice(0, start_colx=0, end_colx=3))
print(sheet.col(4))
print(sheet.col_slice(4, start_rowx=1, end_rowx=11))
cell = sheet.cell(2, 2)
print(cell)
print(type(cell))
print(cell.value)
# 遍历整个表单并将其格式化输出
print(f'交易日期\t\t\t最高价\t\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')
curr_date = xlrd.xldate_as_datetime(value, 0)
print(curr_date.strftime('%Y年%m月%d日'), end='\t')
elif col == 5:
print(f'{int(value):<10d}', end='\t')
else:
print(f'{value:.4f}', end='\t')
print()
写Excel文件(
.xls
格式)
.xls
-
xlwt.Workbook()
:创建工作簿对象(
Workbook
) -
wb.add_sheet()
:创建工作表对象(
Worksheet
) -
sheet.write(row, col, data)
:添加数据,
row
:行,
col
:列,
data
:数据
import xlwt
import random
student_name = ['关羽', '张飞', '赵云', '马超', '黄忠']
scores = [[random.randint(40, 100) for _ in range(3)] for _ in range(5)]
wb = xlwt.Workbook()
sheet = wb.add_sheet('一年级二班')
titles = ('姓名', '语文', '数学', '英语')
# 添加表头数据
for index, title in enumerate(titles):
sheet.write(0, index, title)
# 添加学生相关数据
for row in range(len(scores)):
sheet.write(row + 1, 0, student_name[row])
for col in range(len(scores[row])):
sheet.write(row + 1, col + 1, scores[row][col])
wb.save('考试成绩表.xls')
读取Excel文件(
.xlsx
格式)
.xlsx
-
openpyxl.load_workbook('xlsx文件')
:打开指定的Excel文件并获取Book对象(工作簿) -
wb.sheetnames()
:获取所有工作表的名字 -
wb.worksheet[0]
:获取工作表 -
sheet.dimensions
:获取工作表的范围 -
sheet.max_column
:获取工作表的列数 -
sheet.max_row
:获取指定的行 -
sheet.cell(2, 2)
:获取指定
cell
对象(单元格,带标签,不是值,) -
sheet.cell(2, 2).value
:获取单元格中的值
import datetime
import openpyxl
wb = openpyxl.load_workbook('day02/temp/阿里巴巴2020年股票数据.xlsx')
print(wb)
print(wb.sheetnames)
sheet = wb.worksheets[0]
print(type(sheet))
print(sheet.dimensions)
print(sheet.max_row, sheet.max_column)
print(sheet.cell(2, 2))
print(sheet.cell(2, 2).value)
print(sheet['C3'].value)
print(sheet['G255'].value)
for row_ch in range(2, 256):
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')
print()
写Excel文件(
.xlsx
格式)
.xlsx
-
openpyxl.workbook()
:创建工作簿(
Workbook
) -
wb.create_sheet()
:添加工作表(
Worksheet
) -
sheet.ress(row, col, data)
:添加数据,
row
:行,
col
:列,
data
:数据
import openpyxl
wb = openpyxl.Workbook()
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('一年级二班考试成绩.xlsx')
操作Excel生成统计图表
from openpyxl import Workbook
from openpyxl.chart import BarChart, Reference
wb = Workbook(write_only=True)
ws = wb.create_sheet()
rows = [
('类别', '销售A组', '销售B组'),
('手机', 40, 30),
('平板', 50, 60),
('笔记本', 80, 70),
('外围设备', 20, 10),
]
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('demo.xlsx')
Python操作Word文件
创建word文档
相关第三方库:
python-docx
、
pillow
python-docx
:不仅可以创建word文档,还可以编辑已存在的word文档。
pillow
:实现图像压缩和图像处理等各种操作。
-
document.add_heading('xxx', 0)
:添加标题,0是大标题,1是一级标题,2是三级标题,3…… -
document.add_paragraph('xxxx')
:添加段落 -
p.add_run
:段落追加文字
from docx.document import Document as Doc
from docx import Document
from docx.shared import Cm, Pt
from docx.document import Document as Doc
# 创建document对象
document = Document() # type: Doc
# 添加大标题
document.add_heading('快快乐乐学Python', 0)
# 添加段落
p = document.add_paragraph('Python是一门非常流行的编程语言,它')
run = p.add_run('简单')
run.bold = True
run.font.size = Pt(18)
p.add_run('而且')
run = p.add_run('优雅')
run.font.size = Pt(18)
run.underline = True
p.add_run('。')
# 添加一级标题
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(
'second item in ordered list', style='List Bullet'
)
# 添加有序列表
document.add_paragraph(
'first item in ordered list', style='List Number'
)
document.add_paragraph(
'second item in ordered list', style='List Number'
)
# 添加图片
document.add_picture('long.jpg', width=Cm(5.2))
# 添加分节符
document.add_section()
records = (
('吕布', '男', '988-5-5'),
('貂蝉', '女', '966-2-2')
)
# 添加表格
table = document.add_table(rows=1, cols=3)
table.style = 'Dark List'
hdr_cells = table.rows[0].cells
hdr_cells[0].text = '姓名'
hdr_cells[1].text = '性别'
hdr_cells[2].text = '出生日期'
for name, sex, birthday in records:
row_cells = table.add_row().cells
row_cells[0].text = name
row_cells[1].text = sex
row_cells[2].text = birthday
# 添加分页符
document.add_page_break()
# 保存文档
document.save('resources/demo.docx')
读取word文档并替换内容
from docx import Document
from docx.document import Document as Doc
doc = Document('resources/离职证明.docx') # type: Doc
# 对所有段落进行循环遍历
for p in doc.paragraphs:
if '周杰' in p.text:
# 对段落中的元素进行循环遍历
for run in p.runs:
if '周杰' in run.text:
run.text = run.text.replace('周杰', '周杰伦')
doc.save('resources/离职证明.docx')
基于样板文档批量创建word文档
from docx import Document
from docx.document import Document as Doc
employees = [
{
'name': '关羽',
'id': '10203040506',
'sdate': '2001年2月3日',
'edate': '2004年5月6日',
'department': '蜀国',
'position': '战士'
},
{
'name': '周瑜',
'id': '40506070809',
'sdate': '2004年5月6日',
'edate': '2007年8月9日',
'department': '吴国',
'position': '法师'
}
]
for emp_dict in employees:
doc = Document('temp/离职证明模板.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'temp/{emp_dict["name"]}离职证明.docx')
Python操作PDF文件
相关第三方库:
PyPDF2
读取PDF并抽取文字
import PyPDF2
from PyPDF2.pdf import PageObject
reader = PyPDF2.PdfFileReader('XGBoost.pdf')
writer = PyPDF2.PdfFileWriter()
for page_num in range(reader.numPages):
current_page = reader.getPage(page_num) # type: PageObject
# 从页面中抽取文字
# print(current_page.extractText())
current_page.rotateClockwise(90)
writer.addPage(current_page)
writer.addBlankPage()
with open('XGBoost-modified.pdf', 'wb') as file:
writer.write(file)
给PDF文件添加密码
import PyPDF2
reader = PyPDF2.PdfFileReader('XGBoost.pdf')
writer = PyPDF2.PdfFileWriter()
for page_num in range(reader.numPages):
writer.addPage(reader.getPage(page_num))
# 加密PDF文件
writer.encrypt('foobared')
with open('XGBoost-encrypted.pdf', 'wb') as file:
writer.write(file)
给PDF文件添加水印
import PyPDF2
from PyPDF2.pdf import PageObject
reader1 = PyPDF2.PdfFileReader('XGBoost.pdf')
reader2 = PyPDF2.PdfFileReader('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
current_page.mergePage(watermark_page)
writer.addPage(current_page)
with open('XGBoost-watermarked.pdf', 'wb') as file:
writer.write(file)
创建PDF文件
from reportlab.lib.pagesizes import A4
from reportlab.pdfbase import pdfmetrics
from reportlab.pdfbase.ttfonts import TTFont
from reportlab.pdfgen import canvas
# 注册字体文件
# 需要下载相应的字体
pdfmetrics.registerFont(TTFont('Font1', 'resources/fonts/Vera.ttf'))
pdfmetrics.registerFont(TTFont('Font2', 'fonts/青呱石头体.ttf'))
pdf_canvas = canvas.Canvas('demo.pdf', pagesize=A4)
width, height = A4
# 绘图
image = canvas.ImageReader('long.jpg')
pdf_canvas.drawImage(image, 20, height - 395, 250, 375)
# 显示当前页
pdf_canvas.showPage()
# 写字
pdf_canvas.setFont('Font2', 40)
pdf_canvas.setFillColorRGB(1, 0, 0, 1)
pdf_canvas.drawString(width // 2 - 120, height // 2, '你好,世界!')
pdf_canvas.setFont('Font1', 40)
pdf_canvas.setFillColorRGB(0, 1, 0, 0.5)
pdf_canvas.rotate(18)
pdf_canvas.drawString(250, 250, 'hello, world!')
# 保存
pdf_canvas.save()
正则表达式(
regular expression
)
regular expression
**正则表达式:**一种工具,用于在编写处理字符串的程序或网页时查找符号某些复杂规则的字符串。
正则表达式 —> 模式 —> 匹配字符串的模式 —> 复杂的匹配规则
相关知识
元字符
-
\b
:
metacharacter
,单词的开头或结尾,也就是单词的分界处,
只匹配一个位置
-
.
:除了换行符以外的任意字符 -
*
:代表数量,指定
*
前面的内容可以连续重复使用任意次以使整个表达式得到匹配 -
.*
:任意数量的不包含换行符的字符 -
\d
:匹配一个数字-
\d{2}
:2个元字符
\d
-
\d{8}
:8个元字符
\d
-
-
\s
:匹配任意的空白符,包括空格,制表符
Tab
,换行符,中文全角空格等。 -
\w
:匹配
字母
或
数字
或
下划线
或
汉字
-
+
:匹配重复1次或更多次 -
^
:匹配字符串的开始 -
$
:匹配字符串的结束
重复(限定符)
-
*
:重复0次或更多次 -
+
:重复1次或更多次 -
?
:重复0次或1次 -
{n}
:重复n次(等于n次) -
{n,}
:重复n次或更多次(大于n次) -
{n, m}
:重复n到m次(大于n次小于m次)
字符类
用
[ ]
创建新的字符集合
[aeiou]
:匹配任何一个英文元音字母
[.?!]
:匹配标点符号
(.?!)
分枝条件
分枝条件
:有几种规则,
使用分枝条件时,要注意各个条件的顺序
。
反义
-
\W
:匹配任意不是字母,数字,下划线,汉字的字符 -
\S
:匹配任意不是空白符的字符 -
\D
:匹配任意非数字的字符 -
\B
:匹配不是单词开头或结束的位置 -
[^x]
:匹配除了
x
意外的任意字符 -
[^aeiou]
:匹配除了
aeiou
这几个字母意以外的任意字符
Python使用正则表达式
Python使用正则表达式的两种方式:
-
不创建正则表达式对象,直接调用函数进行匹配操作
-
match
-
fullmatch
-
-
创建正则表达式对象(
Pattern
),通过给对象发消息实现匹配操作
–
compile
import re
username = input('请输入用户名: ')
# 通过compile编译正则表达式创建Pattern对象
username_pattern = re.compile(r'^\w{6,20}$')
print(type(username_pattern))
# 通过给Pattern对象发消息实现匹配检查
matcher = username_pattern.match(username)
print(type(matcher))
# 判断用户名是否错误
if matcher is None:
print('无效的用户名!!!')
else:
print(matcher.group())
从字符串中提取跟正则表达式匹配的部分
match – 匹配 – 从头开始进行匹配 —> Match对象 —> group()
search – 搜索 – 从任意位置匹配 —> Match对象 —> group()
findall – 从字符串中找出所有和正则表达式匹配的内容 —> list[str]
import re
content = """报警电话:110,我们班是Python-2105班,
我的QQ号是2277078243,我的手机号是153****8021,谢谢!"""
# 第一种
matcher = re.search(r'1[3-9]\d[*]{4}\d{4}', content)
if not matcher:
print('没有找到手机号')
else:
print(matcher.group())
# 第二种
print(len(content))
# 创建对象及匹配条件
pattern = re.compile(r'\d+')
# 发消息给对象
matcher = pattern.search(content)
while matcher:
print(matcher.group())
# 匹配字符串的开始下标和结束下标
print(matcher.start(), matcher.end())
matcher = pattern.search(content, matcher.end())
results = pattern.findall(content)
for result in results:
print(result)
# 第三种
results = re.findall(r'\d+', content)
for result in results:
print(result)
总结
- 通过读写文件的操作,可以实现数据持久化。
- 程序在运行时可能遭遇无法预料的异常状况,可以使用Python的异常机制来处理这些状况。
- CSV(Comma Separated Values)全称逗号分隔值文件是一种简单、通用的文件格式,被广泛的应用于应用程序(数据库、电子表格等)数据的导入和导出以及异构系统之间的数据交换。
- 掌握了Python程序操作Excel的方法,可以解决日常办公中很多繁琐的处理Excel电子表格工作。
- 符号常量由于字面常量。
- Python语言没有内置定义常量的语法,但是可以约定变量名使用全大写字母的变量就是常量。
