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()
posted @ 2018-05-01 14:56  思维无界限  阅读(7367)  评论(0编辑  收藏  举报