Python 文档操作
搞懂Python对图片和文档的基本操作
用程序来处理图像和办公文档经常出现在实际开发中,Python的标准库中虽然没有直接支持这些操作的模块,但我们可以通过Python生态圈中的第三方模块来完成这些操作。
操作图像
计算机图像相关知识
颜色:混合红、黄、蓝三种颜料可以得到其他的颜色,事实上这三种颜色就是被我们称为美术三原色的东西,它们是不能再分解的基本颜色。在计算机中,我们可以将红、绿、蓝三种色光以不同的比例叠加来组合成其他的颜色,因此这三种颜色就是色光三原色,所以我们通常会将一个颜色表示为一个RGB值或RGBA值(其中的A表示Alpha通道,它决定了透过这个图像的像素,也就是透明度)。
名称 | RGBA值 | 名称 | RGBA值 |
White | (255, 255, 255, 255) | Red | (255, 0, 0, 255) |
Green | (0, 255, 0, 255) | Blue | (0, 0, 255, 255) |
Gray | (128, 128, 128, 255) | Yellow | (255, 255, 0, 255) |
Black | (0, 0, 0, 255) | Purple | (128, 0, 128, 255) |
像素: 对于一个由数字序列表示的图像来说,最小的单位就是图像上单一颜色的小方格,这些小方块都有一个明确的位置和被分配的色彩数值,而这些一小方格的颜色和位置决定了该图像最终呈现出来的样子,它们是不可分割的单位,我们通常称之为像素(pixel)。每一个图像都包含了一定量的像素,这些像素决定图像在屏幕上所呈现的大小.
用Pillow操作图像
Pillow是由从著名的Python图像处理库PIL发展出来的一个分支,通过Pillow可以实现图像压缩和图像处理等各种操作。可以使用下面的命令来安装Pillow。
Pillow中最为重要的是Image类,读取和处理图像都要通过这个类来完成。
>>> from PIL import Image
>>>
>>> image = Image.open('./uploads/1.jpg')
>>> image.format, image.size, image.mode
('JPEG', (500, 750), 'RGB')
>>> image.show()
剪裁图像
>>> image = Image.open('./uploads/1.jpg')
>>> rect = 80, 20, 310, 360
>>> image.crop(rect).show()
参数说明
left:与左边界的距离
up:与上边界的距离
right:还是与左边界的距离
below:还是与上边界的距离
简而言之就是,左上右下。
生成缩略图
>>> image = Image.open('./uploads/1.jpg')
>>> size = 128, 128
>>> image.thumbnail(size)
>>> image.show()
缩放和黏贴图像
>>> image1 = Image.open('./uploads/1.jpg')
>>> image2 = Image.open('./uploads/2.jpg')
>>> rect = 80, 20, 310, 360
>>> guido_head = image2.crop(rect)
>>> width, height = guido_head.size
>>> image1.paste(guido_head.resize((int(width / 1.5), int(height / 1.5))), (172, 40))
旋转和翻转
>>> image = Image.open('./res/guido.png')
>>> image.rotate(180).show()
>>> image.transpose(Image.FLIP_LEFT_RIGHT).show()
操作像素
>>> image = Image.open('./res/guido.jpg')
>>> for x in range(80, 310):
... for y in range(20, 360):
... image.putpixel((x, y), (128, 128, 128))
...
>>> image.show()
滤镜效果
>>> from PIL import Image, ImageFilter
>>>
>>> image = Image.open('./res/guido.jpg')
>>> image.filter(ImageFilter.CONTOUR).show()
处理Excel电子表格
Python的openpyxl模块让我们可以在Python程序中读取和修改Excel电子表格,当然实际工作中,我们可能会用LibreOffice Calc和OpenOffice Calc来处理Excel的电子表格文件,这就意味着openpyxl模块也能处理来自这些软件生成的电子表格。
写入excel
import xlwt
# 创建一个workbook 设置编码
workbook = xlwt.Workbook(encoding = 'utf-8')
# 创建一个worksheet
worksheet = workbook.add_sheet('animal')
# 写入excel
# 参数对应 行, 列, 值
worksheet.write(1,0, label = 'cat')
# 保存
workbook.save('test.xlsx')
读取excel
from openpyxl import load_workbook
wb = load_workbook(filename = 'test.xlsx')
sheet_ranges = wb['range names']
print(sheet_ranges['D18'].value)
执行结果:
设置单元格宽度
import xlwt
workbook = xlwt.Workbook()
worksheet = workbook.add_sheet('animal')
worksheet.write(0, 0,'cat')
# 设置单元格宽度
worksheet.col(0).width = 3333
workbook.save('test.xlsx')
输入一个日期到单元格
import xlwt
import datetime
workbook = xlwt.Workbook()
worksheet = workbook.add_sheet('animal')
style = xlwt.XFStyle()
style.num_format_str = 'M/D/YY' # Other options: D-MMM-YY, D-MMM, MMM-YY, h:mm, h:mm:ss, h:mm, h:mm:ss, M/D/YY h:mm, mm:ss, [h]:mm:ss, mm:ss.0
worksheet.write(0, 0, datetime.datetime.now(), style)
workbook.save('test.xlsx')
向单元格添加一个公式
import xlwt
workbook = xlwt.Workbook()
worksheet = workbook.add_sheet('animal')
worksheet.write(0, 0, 5) # Outputs 5
worksheet.write(0, 1, 2) # Outputs 2
worksheet.write(1, 0, xlwt.Formula('A1*B1')) # Should output "10" (A1[5] * A2[2])
worksheet.write(1, 1, xlwt.Formula('SUM(A1,B1)')) # Should output "7" (A1[5] + A2[2])
workbook.save('test.xlsx')
添加超链接
import xlwt
workbook = xlwt.Workbook()
worksheet = workbook.add_sheet('animal')
worksheet.write(0, 0, xlwt.Formula('HYPERLINK("http://www.baidu.com";"baidu")')) # Outputs the text "Google" linking to http://www.baidu.com
workbook.save('test.xlsx')
合并列和行
import xlwt
workbook = xlwt.Workbook()
worksheet = workbook.add_sheet('animal')
worksheet.write_merge(0, 0, 0, 3, 'First Merge') # Merges row 0's columns 0 through 3.
font = xlwt.Font() # Create Font
font.bold = True # Set font to Bold
style = xlwt.XFStyle() # Create Style
style.font = font # Add Bold Font to Style
worksheet.write_merge(1, 2, 0, 3, 'Second Merge', style) # Merges row 1 through 2's columns 0 through 3.
workbook.save('test.xlsx')
内容对其方式
import xlwt
workbook = xlwt.Workbook()
worksheet = workbook.add_sheet('animal')
alignment = xlwt.Alignment() # Create Alignment
alignment.horz = xlwt.Alignment.HORZ_CENTER # May be: HORZ_GENERAL, HORZ_LEFT, HORZ_CENTER, HORZ_RIGHT, HORZ_FILLED, HORZ_JUSTIFIED, HORZ_CENTER_ACROSS_SEL, HORZ_DISTRIBUTED
alignment.vert = xlwt.Alignment.VERT_CENTER # May be: VERT_TOP, VERT_CENTER, VERT_BOTTOM, VERT_JUSTIFIED, VERT_DISTRIBUTED
style = xlwt.XFStyle() # Create Style
style.alignment = alignment # Add Alignment to Style
worksheet.write(0, 0, 'Cell Contents', style)
workbook.save('test.xls')
单元格议添加边框
import xlwt
workbook = xlwt.Workbook()
worksheet = workbook.add_sheet('animal')
borders = xlwt.Borders() # Create Borders
borders.left = xlwt.Borders.DASHED
# DASHED虚线,NO_LINE没有,THIN实线
# May be: NO_LINE, THIN, MEDIUM, DASHED, DOTTED, THICK, DOUBLE, HAIR, MEDIUM_DASHED, THIN_DASH_DOTTED, MEDIUM_DASH_DOTTED, THIN_DASH_DOT_DOTTED, MEDIUM_DASH_DOT_DOTTED, SLANTED_MEDIUM_DASH_DOTTED, or 0x00 through 0x0D.
borders.right = xlwt.Borders.DASHED
borders.top = xlwt.Borders.DASHED
borders.bottom = xlwt.Borders.DASHED
borders.left_colour = 0x40
borders.right_colour = 0x40
borders.top_colour = 0x40
borders.bottom_colour = 0x40
style = xlwt.XFStyle() # Create Style
style.borders = borders # Add Borders to Style
worksheet.write(0, 0, 'Cell Contents', style)
workbook.save('test.xls')
单元格设置背景色
import xlwt
workbook = xlwt.Workbook()
worksheet = workbook.add_sheet('My Sheet')
pattern = xlwt.Pattern() # Create the Pattern
pattern.pattern = xlwt.Pattern.SOLID_PATTERN # May be: NO_PATTERN, SOLID_PATTERN, or 0x00 through 0x12
pattern.pattern_fore_colour = 5 # May be: 8 through 63. 0 = Black, 1 = White, 2 = Red, 3 = Green, 4 = Blue, 5 = Yellow, 6 = Magenta, 7 = Cyan, 16 = Maroon, 17 = Dark Green, 18 = Dark Blue, 19 = Dark Yellow , almost brown), 20 = Dark Magenta, 21 = Teal, 22 = Light Gray, 23 = Dark Gray, the list goes on...
style = xlwt.XFStyle() # Create the Pattern
style.pattern = pattern # Add Pattern to Style
worksheet.write(0, 0, 'Cell Contents', style)
workbook.save('Excel_Workbook.xlsx')
处理Word文档
利用python-docx模块,Pytho 可以创建和修改Word文档,当然这里的Word文档不仅仅是指通过微软的Office软件创建的扩展名为docx的文档,LibreOffice Writer和OpenOffice Writer都是免费的字处理软件。
读取word
import docx
#打开demo.docx文档,返回一个Document对象,它有paragraphs属性时Paragraph对象的列表。
doc = docx.Document('test.docx')
print(len(doc.paragraphs))
print(doc.paragraphs[0].text)
print(doc.paragraphs[1].text)
#每个Paragraph对象也有一个runs属性,它是Run对象的列表。
print(len(doc.paragraphs[1].runs))
#Run对象也有一个text属性,包含那个延续的文本
print(doc.paragraphs[1].runs[0].text)
取得完整的文本
如果你只关心Word文档的文本,不关心样式信息,就可以利用getText()函数。 它接受一个.docx文件名,返回其中文本的字符串。
import docx
def getText(filename):
doc = docx.Document(filename)
fullText = []
for para in doc.paragraphs:
fullText.append(para.text)
return '\n'.join(fullText)
print(getText('demo.docx'))
设置Paragraph和Run对象的样式
对于Word文档,有3种类型的样式:
段落样式可以应用于Paragraph对象;
字符样式可以应用于Run对象;
链接的样式可以应用于这两种对象。
可以将Paragraph和Run对象的style属性设置为一个字符串,从而设置样式。如果style属性被设置为None,就没有样式于Paragraph或Run对象关联。在设置style属性时,不要在样式名称中使用空格。
例如,样式名称可能时Subtle Emphasis,你应该将属性设置为字符串’SubtleEmphasis’。如果对Run对象应用链接的样式,需要在样式名称末尾加上’Char’。例如,对于Paragraph对象设置Quote链接的样式,应该使用paragraphObj.style=’Quote’。但对于Run对象,应该使用runObj.style=’QuoteChar’。
Word的Run属性
通过text属性,Run可以进一步设置样式。每个属性都可以被设置为3个值之一:True(该属性总是启用,不论其他样式是否应用于Run)、False(该属性总是禁用)或None(默认使用该Run被设置的任何属性)。
Run对象的text属性:bold、italic、underline、strike、double_strike、all_caps等等。
import docx
doc = docx.Document('demo.docx')
doc.paragraphs[0].text
>> 'Document Title'
doc.paragraphs[0].style
>> 'Title'
doc.paragraphs[0].style = 'Normal'
doc.paragraphs[1].runs[0].style = 'QuoteChar'
doc.paragraphs[1].runs[1].underline = True
doc.paragraphs[1].runs[3].underline = True
doc.save('restyle.docx')
写入word
要创建自己的.docx文件,就调用docx.Document,返回一个新的、空白的Word Document对象。
Document对象的add_paragraph()方法将一段新文本添加到文档中,并返回添加的Paragraph对象的引用。
在添加文本之后,向Document对象的save()方法传入一个文件名字符串,将Document对象保存到文件。
from docx import Document
document = Document()
#直接添加标题
document.add_heading(u'Python 操作Word实例', 3)
#先定义标题,再添加内容
p_total = document.add_heading()
r_total = p_total.add_run("执行结果如下:")
r_total.font.bold = True
# 增加表格
table = document.add_table(rows=1, cols=3, style="Light List Accent 5")
hdr_cells = table.rows[0].cells
hdr_cells[0].text = 'testName'
hdr_cells[1].text = 'param'
hdr_cells[2].text = 'exc'
for i in range(5):
i = i + 1
testName = "testName"+str(i)
#img_name = "./test.jpg"
param = "param"+str(i)
exc="exc"+str(i)
row_cells = table.add_row().cells
row_cells[0].text = testName
row_cells[1].text = param
row_cells[2].text = exc
#添加二级标题
p_total = document.add_heading("", 2)
r_total = p_total.add_run(testName)
r_total.font.bold = True
# 保存文档
document.save("./test.docx")
处理PDF文档
PDF是Portable Document Format的缩写,使用.pdf作为文件扩展名。接下来我们就研究一下如何通过Python实现从PDF读取文本内容和从已有的文档生成新的PDF文件。
读取PDF内容
import PyPDF2
pdfFileObj = open('meetingminutes.pdf','rb')
pdfReader = PyPDF2.PdfFileReader(pdfFileObj)
# pdf内容多少页
print(pdfReader.numPages)
pageObj = pdfReader.getPage(0)
# 读取pdf内容
pageObj.extractText()
解密PDF
某些PDF文档有加密功能,以防止别人阅读,只有在打开文档前时提供口令后才能阅读。
import PyPDF2
pdfFile = open('encrypted.pdf','rb')
pdfReader = PyPDF2.PdfFileReader(pdfFile)
# 返回True说明时加密的PDF
print(pdfReader.isEncrypted)
#调用decrypt()函数,传入口令字符串,返回1说明口令正确,之后就可以进行读取操作了
pdfReader.decrypt('rosebud')
加密PDF
PdfFileWriter对象也可以为PDF文档进行加密。
import PyPDF2
pdfFile = open('test.pdf','rb')
pdfReader = PyPDF2.PdfFileReader(pdfFile)
pdfWriter = PyPDF2.PdfFileWriter()
#我们将meetingminutes.pdf的页面拷贝到PdfFIleWriter对象
for pageNum in range(pdfReader.numPages):
pageObj = pdfReader.getPage(pageNum)
pdfWriter.addPage(pageObj)
#用口令swordfish加密了PdfFileWriter对象
pdfWriter.encrypt('swordfish')
#打开了一个名为encryptminutes.pdf的新PDF,将PdfFileWriter的内容写入新的PDF
resultPdf = open('test1.pdf','wb')
pdfWriter.write(resultPdf)
resultPdf.close()
创建PDF
import PyPDF2
#打开PDF,创建File对象,还有创建PdfFileReader对象,从打开的PDF中读取数据
pdf1File = open('test1.pdf','rb')
pdf2File = open('test2.pdf','rb')
pdf1Reader = PyPDF2.PdfFileReader(pdf1File)
pdf2Reader = PyPDF2.PdfFileReader(pdf2File)
#PdfFileWriter对象,表示一个空白的PDF文档,可以往里面写数据
pdfWriter = PyPDF2.PdfFileWriter()
#通过页面循环写入到pdfWriter对象中,pdf1Reader.getPage(pageNum)返回的就是该页面的内容
for pageNum in range(pdf1Reader.numPages):
pageObj = pdf1Reader.getPage(pageNum)
pdfWriter.addPage(pageObj)
for pageNum in range(pdf2Reader.numPages):
pageObj = pdf2Reader.getPage(pageNum)
pdfWriter.addPage(pageObj)
#通过open()新建一个PDF文档,然后把pdfWriter的内容写入到pdfOutputFile中。
pdfOutputFile = open('test3.pdf','wb')
pdfWriter.write(pdfOutputFile)
pdfOutputFile.close()
pdf1File.close()
pdf2File.close()