Python处理Excel和PDF文档
一、使用Python操作Excel
Python来操作Excel文档以及如何利用Python语言的函数和表达式操纵Excel文档中的数据。
虽然微软公司本身提供了一些函数,我们可以使用这些函数操作Excel文档。但是,使用Excel自带的函数受限于Excel软件的功能限制。换句话说,只有微软提供了某种功能,我们才能使用相应的功能解决问题。如果微软没有提供相应的函数应对一个复杂的功能,那么,我们只能进行重复性操作。使用Python语言操作Excel则不然,我们可以灵活应用Python语言的所有功能,读取、计算和编辑Excel文档中的数据。
一)Python处理Excel之openpyxl
1、openpyxl简介和安装
1、openpyxl简介
openpyxl是一个读写Excel2010(xlsx/xlsm)文档的Python库,如果要处理更早格式的Excel文档,需要用到另外的库。openpyxl是一个比较综合的工具,能够同时读取和修改Excel文档。XlsxWriter也是一个与Excel处理相关的知名项目,仅支持创建和写入Excel文档,不支持读取Excel文档。
2、openpyxl安装
pip install openpyxl
2、使用openpyxl读取Excel文档
1、Excel的构成
一个Excel文档称为一个工作簿,在Office2010下,典型工作簿的文件扩展名为xlsx。一个工作簿可以包含多个表格(在Excel又称为sheet)。打开工作簿后会默认显示一个表格,这个表格一般称为活跃表。表格中包含若干单元格,所有单元格都有一个唯一的坐标。Excel通过行和列表示一个单元格,其中,行的坐标使用数字表示,列的坐标使用字母表示。
2、openpyxl处理Excel文件
openxpyxl中有三个不同层次的类,分别是Workbook、Worksheet和Cell。Workbook是对Excel工作簿的抽象,Worksheet是对表格的抽象,Cell是对单元格的抽象。每一个类都包含了若干属性和方法,以便于我们通过这些属性和方法获取表格中的数据。
例如,我们要打开一个Excel表格或者创建一个Excel文档,都需要创建一个Workbook对象。我们需要获取Excel文档中的某一张表,应该先创建一个Workbook对象,然后使用该对象的方法来得到一个Worksheet对象。如果要读取或者修改某个单元格,我们需要先获得Worksheet对象,然后再获取代表单元格的Cell对象。
一个Workbook对象代表一个Excel文档,因此,在操作一个Excel之前,应该先创建一个Workbook对象。对于创建一个新的Excel文档,直接进行Workbook类调用即可。对于读取一个已有的Excel文档,可以使用openpyxI模块的load_workbook函数。该函数接受多个参数,但只有filename参数为必传参数。filenmame可以是一个文件名,也可以是一个打开的文件对象。
import openpyxl wb=openpyxl.load_workbook('example.xls')
调用完load_workbook函数以后,我们就得到了一个Workbook对象。Workbook对象有很多的属性和方法,其中,大部分方法都与sheet相关。
Workbook对象的部分属性如下:
1 active:获取活跃的Worksheet; 2 read_only:是否以read_only模式打开Excel文档; 3 encoding:文档的字符集编码; 4 properties:文档的元数据,如标题,创建者,创建日期等; 5 worksheets:以列表的形式返回所有的Worksheet。
#操作 print(wb.active) print(wb.read_only) print(wb.encoding) print(wb.worksheets) #结果如下 <Worksheet "product"> False utf-8 [<Worksheet "pre">, <Worksheet "product">]
Workbook对象的方法大都与Worksheet相关。常用的方法如下:
1 sheetnames:获取所有表格的名称; 2 [sheetname]:通过表格名称获取Worksheet对象; 3 active:获取活跃的表格; 4 remove:删除一个表格; 5 create_sheet:创建一个空的表格; 6 copy_worksheet:在Workbook内拷贝表格
#实操 print(wb.sheetnames) print(wb['pre']) print(wb.active) print(wb.create_sheet(index=0, title='new sheet')) print(wb.sheetnames) print(wb.remove(wb['new sheet'])) print(wb.sheetnames) print(wb.copy_worksheet(wb['pre'])) ###将修改保存(从内存刷到磁盘) wb.save('example.xlsx') #结果 <Worksheet "new sheet"> ['new sheet', 'pre', 'product'] ['new sheet', 'pre', 'product'] <Worksheet "pre"> <Worksheet "pre Copy">
有了Worksheet对象以后,我们可以通过这个Worksheet对象获取表格的属性,得到单元格中的数据,修改表格中的内容。openpyxI提供了非常灵活的方式来访问表格中的单元格和数据。
常用的Worksheet属性如下:
1 title:表格的标题; 2 dimensions:表格的大小,这里的大小是指有含有数据的表格大小。例如,对于example.xlsx文件,dimensions属性的值为'Al:El1'; 3 maxrow:表格的最大行; 4 min_row:表格的最小行; 5 maxcolumn:表格的最大列; 6 mincolumn:表格的最小列; 7 rows:按行获取单元格(Cell对象); 8 columns:按列获取单元格(Cell对象); 9 freeze_panes:冻结窗格; 10 values:按行获取表格的内容(数据)。
#实操 ws = wb['pre'] print(ws.title) print(ws.max_row) #结果如下 pre 59
通过不同的属性名获取student这张表的属性。其中,columns、rows和values这几个属性都是通过生成器的方式返回数据。
openpyxl并不知道我们的表格中有多少数据,在数据量大的情况下,如果一次获取所有数据,势必会占用较多的内存。因此,openpyxl的设计中,需要返回数据时都是通过生成器的方式返回。对于附件中的student表,因为记录较少,我们可以使用list函数或tuple函数获取所有的数值。需要注意的是,columns与rows返回的是Cell对象,values返回的是数据。
freeze_panes这个参数比较特别,主要用于在表格较大时冻结顶部的行或左边的列。对于冻结的行或列,就算用户滚动电子表格,也是始终可见的。每个Worksheet对象都有一个freeze_panes属性,可以设置为一个Cell对象或一个单元格坐标的字符串,单元格上面的行和左边的列将会冻结(注意单元格所在的行和列并不会冻结)。例如,我们需要冻结第一行,那么freeze_panes取值应该为A2,如果要冻结第一列,freeze_panes取值为Bl。如果要同时冻结第一行和第一列,则freeze_panes取值为B2。freeze_panes取值为None表示不冻结任何窗格。
Worksheet常用的一些方法:
1 iter_rows:按行获取所有单元格(Cell对象); 2 iter_columns:按列获取所有的单元格; 3 append:在表格末尾添加数据; 4 merged_cells:合并多个单元格; 5 unmerge_cells:移除合并的单元格。
iter_rows方法和iter_columns方法在参数取默认值时,与rows属性和columns属性的作用相同。区别在于,iter_rows方法和iter_columns方法可以通过函数参数限定访问表格的范围。
print(list(ws.iter_rows(min_row=2,max_row=4,min_col=1,max_col=3)))
从Worksheet的属性和方法的使用中可以看到,很多属性和方法返回的不是某一个具体的数值,而是一个Cell对象。一个Cell对象就代表一个单元格,我们可以直接使用Excel坐标的方式获取Cell对象,也可以使用Worksheet的cell方法获取Cell对象。如下所示:
print(ws['A1']) print(ws.cell(row=1, column=2))
Cell对象比较简单,其常用的属性如下:
1 row:单元格所在的行; 2 column:单元格所在的列; 3 value:单元格的取值; 4 cordinate:单元格的坐标
3、openpyxl提供的各种API
使用4种不同的方法来打印student表中的内容。为了对数据的格式进行控制,我们使用print函数而不是print语句进行打印。
通过Worksheet的values方法打印表格中的数据,这也是打印数据最简单的方法。values通过生成器访问数据并按行返回,因此,我们使用for循环遍历表格的内容。
from __future__ import print_function for row in ws.values: print(*row)
使用Worksheet的rows属性来遍历表格中的数据。rows属性按行返回Cell对象,因此,我们使用列表推导来获取每一个Cell对象的值。如下所示:
for row in ws.rows: print(*[cell.value for cell in row])
Worksheet的iter_rows方法在不加任何参数的情况下与rows属性效果相同,因此这种方法与前一种方法看起来很像
for row in ws.iter_rows(): print(*[cell.value for cell in row])
最后这种方式是最麻烦的方式,也是大家最容易想到的方式。我们首先获取表格的最小行数和最大行数,然后获取最小列数与最大列数,通过行和列的索引确定一个唯一元格。确定单元格以后,打印单元格的值。这种方式是每确定一个单元格打印一次,因此,我们在print函数中将end参数取值为空格来避免换行,并在内层for循环结束以后,显示地进行换行。如下所示:
for i in range(ws.min_row, ws.max_row + 1): for j in range(ws.min_column, ws.max_column + 1): print(ws.cell(row=i ,column=j).value, end=' ') print()
3、使用openpyxl修改Excel
openpyxl不但可以读取Excel文档,而且还可以修改Excel文档,包括修改单元格的 数据、合并单元格、修改单元格的字体、在Excel文档中画图等。
一个Workbook对象就代表了一个工作簿,因此,新建一个工作簿就是创建一个 Workbook对象。创建完Workbook对象以后,默认会有一个名为“sheetl”的表格,我们 可以通过表格的名称或get_active_sheet方法来获取这个表格。获取表格以后,可以通过给 表格的title属性赋值的方式来修改表格的名称。
from openpyxl import Workbook wb =Workbook() wb.sheetnames ws = wb.active ws.title ws.title = 'pre'
修改
ws['A1'] = 'hello world' wb.save('example.xlsx')
二)其他操作Excel的方式
1、xlrd主要是用来读取excel文件
1、安装xlrd
pip install xlrd
2、实操
import xlrd workbook = xlrd.open_workbook('dns_records.xls') sheet_names = workbook.sheet_names() for sheet_name in sheet_names: sheet2 = workbook.sheet_by_name(sheet_name) print(sheet_name) rows = sheet2.row_values(3) # 获取第四行内容 cols = sheet2.col_values(1) # 获取第二列内容 print(rows) print(cols)
2、xlwt主要是用来写excel文件
1、安装
pip install xlwt
2、实操
import xlwt wbk = xlwt.Workbook() sheet = wbk.add_sheet('sheet 1') sheet.write(0,1,'test text')#第0行第一列写入内容 wbk.save('test.xls')
3、xlutils结合xlrd可以达到修改excel文件目的
1、安装
pip install xlutils
2、实操
import xlrd from xlutils.copy import copy workbook = xlrd.open_workbook(u'有趣装逼每日数据及趋势.xls') workbooknew = copy(workbook) ws = workbooknew.get_sheet(0) ws.write(3, 0, 'changed!') workbooknew.save(u'有趣装逼每日数据及趋势copy.xls')
4、xlsxwriter可以写excel文件并加上图表
1、安装
pip install xlsxwriter
2、实操
1 import xlsxwriter 2 3 4 def get_chart(series): 5 chart = workbook.add_chart({'type': 'line'}) 6 for ses in series: 7 name = ses["name"] 8 values = ses["values"] 9 chart.add_series({ 10 'name': name, 11 'categories': 'A2:A10', 12 'values':values 13 }) 14 chart.set_size({'width': 700, 'height': 350}) 15 return chart 16 17 if __name__ == '__main__': 18 workbook = xlsxwriter.Workbook(u'H5应用中心关键数据及趋势.xlsx') 19 worksheet = workbook.add_worksheet(u"每日PV,UV") 20 headings = ['日期', '平均值'] 21 worksheet.write_row('A1', headings) 22 index = 0 23 for row in range(1,10): 24 for com in [0,1]: 25 worksheet.write(row,com,index) 26 index+=1 27 series = [{"name":"平均值","values":"B2:B10"}] 28 chart = get_chart(series) 29 chart.set_title ({'name': '每日页面分享数据'}) 30 worksheet.insert_chart('H7', chart) 31 workbook.close()
三)Python3实战
1、Python处理excel并json序列化,并写入文件中
import xlrd from collections import OrderedDict import json def login_pc_parameter(): #excel的路径 wb = xlrd.open_workbook('pc_login.xlsx') convert_list = [] #处理的sheet,默认是第一个(索引值为0) sh = wb.sheet_by_index(0) #显示excel的标题,一般是第一行内容 title = sh.row_values(0) for rownum in range(1, sh.nrows): #获取每行的数据 rowvalue = sh.row_values(rownum) #使用有序字典类,防止乱序 single = OrderedDict() for colnum in range(0, len(rowvalue)): # print(title[colnum], rowvalue[colnum]) single[title[colnum]] = rowvalue[colnum] convert_list.append(single) j = json.dumps(convert_list,ensure_ascii=False,indent=2) # print(convert_list) # print(j) with open("file3.json", "w",encoding="utf-8") as f: f.write(j) if __name__ == '__main__': login_pc_parameter()
二、使用Python操作PDF
PDF(Portable Document Format)是一种便携式文档格式,这种文档格式与操作系统平台无关。PDF文件无论是在Windows,Unix还是在苹果公司的MacOS操作系统中都是通用的,这一特点使它成为在Internet上进行电子文档发行和数字化信息传播的理想文档格式。虽然PDF便于传输和阅读,但是,编辑PDF却很不容易。PyPDF2对编辑PDF提供了有限的支持,我们可以使用PyPDF2模块读取、合并和写入PDF文档。
一)PyPDF2 安装与介绍
PyPDF2是一个纯Python的开源库,能够分割或合并PDF文件,也可以裁剪或转换 PDF文件中的页面。我们还可以使用PyPDF2查看PDF文件的元信息,对PDF文件进行加密,破解PDF文件的密码等。
官网:https://pythonhosted.org/PyPDF2/
安装
pip install PyPDF2
PyPDF2提供了4个主要的类,分别是PdfFileWriter、PdfFileReader、PdfFileMerger和PageObject。前三个类分别用以读取PDF文件、写入PDF文件与合并PDF文件。PageObject类代表了一个PDF页面,可以使用PdfFileReader类的getPage方法得到一个PageObject对象。
二)使用PdfFileReader读取PDF文档
学习一个库,最好的方式就是使用IPython进行练习。IPython能够看到程序的中间结果,也可以方便地获取帮助信息。接下来,我们就使用IPython学习PyPDF2的使用。在 IPython的交互模式下输入以下代码:
1、获取pdf文档共有多少页
import PyPDF2 reader = PyPDF2.PdfFileReader(open(u'Python Linux系统管理与自动化运维.pdf', 'rb')) num_pages = reader.getNumPages() print(num_pages)
2、显示pdf文档的info信息
doc_info = reader.getDocumentInfo() print(doc_info)
结果如下
{'/CreationDate': "D:20171125012631+08'00'", '/Creator': 'Adobe Acrobat 11.0.10', '/ModDate': "D:20180430102312+08'00'", '/Producer': 'Adobe Acrobat Pro 11.0 Paper Capture Plug-in', '/Title': ''}
三)使用PdfFileWrite创建PDF文档
对PDF文件进行加密、裁剪PDF文件、调整PDF页面的顺序等。我们需要编辑PDF页面。例如,去除PDF文件中的第一页,从一个PDF文件中提取几个页面保存到另一个文件。PyPDF2并不能直接编辑PDF文件,但是,我们可以利用PyPDF2从一个PDF文档拷贝需要的页面到另一个PDF文档,通过这种迂回的方式实现编辑PDF的功能。
例如,我们现在要修改Python Linux系统管理与自动化运维.pdf文件,仅仅保存该文件的第2页、第5页和第6页。我们将这几个页面抽取出来,保存到另外一个PDF文件中,并对这个PDF文件进行加密。如下所示:
1、将需要的内容写入新的pdf文件
import PyPDF2 reader= PyPDF2.PdfFileReader(open(u'Python Linux系统管理与自动化运维.pdf', 'rb')) output= PyPDF2.PdfFileWriter() output.addPage(reader.getPage(1)) output.addPage(reader.getPage(4)) output.addPage(reader.getPage(5)) output.getNumPages()
创建了一个PdtFileWriter对象和一个PdtFileReader对象。接着,我们使用PdtFileReader对象的getPage方法获取需要的PDF页面,并通过PdtFileWriter对象的addPage方法增加页面。PdtFileWriter类有很多方法,如添加空白页的addBlankPage方法、添加书签的addBookmark方法、添加元信息的addMetadata方法以及对PDF进行加密的encrypt方法。在PdtFileWriter类的所有方法中,最常用的是addPage方法。
getNumPages方法获取PdtFileWriter拥有的PDF页面数。
2、使用encrypt方法对PDF文件进行加密。
output.encrypt('123456') outputStream = (open(u'Python Linux系统管理与自动化运维_test.pdf', 'wb')) output.write(outputStream) outputStream.close()
四)修改PDF页面
需要修改PDF的页面,PyPDF2也提供了部分支持,如旋转页面、添加水印。PageObject类中有部分方法可以修改PDF页面,其中,rotateClockwise和rotateCounterClockwise方法用来旋转页面。这两个方法只接受一个参数,且参数取值必须是90的倍数,表示旋转多少度。下面的代码将redbooks.pdf文件的首页旋转180度,并保存到一个新的文件中。
1、旋转文档
import PyPDF2 reader = PyPDF2.PdfFileReader(open(u'Python Linux系统管理与自动化运维.pdf', 'rb')) writer = PyPDF2.PdfFileWriter() page = reader.getPage(20) page.rotateClockwise(90) writer.addPage(page) outputStream = open("test.pdf", "wb") writer.write(outputStream) outputStream.close()
2、给文档添加水印
import PyPDF2 reader = PyPDF2.PdfFileReader(open(u'Python Linux系统管理与自动化运维.pdf', 'rb')) watermark = PyPDF2.PdfFileReader(open(u'Python Linux系统管理与自动化运维.pdf', 'rb')) writer = PyPDF2.PdfFileWriter() for i in range(reader.getNumPages()): page = reader.getPage(i) page.mergePage(watermark.getPage(0)) writer.addPage(page) output_stream = open("watermark-test.pdf", 'wb') writer.write(output_stream) output_stream.close()