Day21-CSV文件和PDF文件操作

一、CSV文件操作

问题1:什么是CSV文件?

逗号分隔值(Comma-Separated Values,CSV,有时也成为”字符分隔值“,因为分隔字符也可以不是逗号)文件格式,可用计算机自带的记事本或者excel打开。csv其文件以纯文本形式存储表格数据(数字和文本),纯文本意味着该文件是一个字符序列,不含必须象二进制数字那样被解读的数据。CSV文件由任意数目的记录组成,记录间以某种换行符分隔;每条记录由字段组成,字段间的分隔符是其它字符或字符串,最常见的是逗号或制表符。通常,所有记录都有完全相同的自段序列。通常都是纯文本文件。

CSV特征

在实践中,CSV泛指具有如下特征:

①纯文本,使用某个字符集,比如ASCII、Unicode;

②由记录组成(典型的是每行一条记录);

③每条记录被分隔符分隔为字段(典型分隔符有逗号、分号或制表符;有时分隔符可以包括可选的空格);

④每条记录都有同样的字段序列。

CSV文件规则

①开头是不留空,以行为单位。

②可含或不含列名,含列名则居文件第一行。

③一行数据不跨行,无空行。

④以半角逗号作分隔符,列为空也要表达其存在。

⑤列内容如存在半角引号(即"),替换成半角双引号转义(即"")转义,即使用半角引号将该字段值包含起来。

⑥文件读写时引号、逗号操作规则互逆。

⑦内码格式不限,可为ASCII、Unicode或者其它。

⑧不支持数字。

⑨不支持特殊字符。

CSV文件格式

一般说来集图用的.CSV文件的格式是这样的:

文件名, 文件大小(以字节为单位), CRC校验值, 注释(可省略)

注意:当省略注释时,CRC校验值后面的逗号不可省略,否则会将校验值认为是注释。

CSV文件格式被用户、商业和科学广泛应用,最广泛的应用是在程序之间转移表格数据,大量程序都支持某种CSV变体。

————以上学习内容引自百度百科https://baike.baidu.com/item/CSV/10739?fr=aladdin

1.CSV文件读操作

1.1创建reader

两种方式:

(1)csv.reader(文件对象) — 获取指定csv文件中的内容,返回一些迭代器,迭代器中的元素是每一行数据对应一个列表

(2)csv.DictReader(文件对象) — 获取指定csv文件中的内容,返回一些迭代器,迭代器中的元素是每一行数据对应一个字典

#首先导入模块
import csv 

#创建reader。注:在PyCharm导入的csv文件对象和创建的py文件处于同一个工程中。
reader1 = csv.reader(open('files/北京高档酒店价格分析.csv'))
reader2 = csv.DictReader(open('files/北京高档酒店价格分析.csv'))

1.2获取内容 — 获取迭代器中的元素(列表或者字典)

两种方式:一是使用next(迭代器)逐个依次获取元素;二是遍历迭代器获取全部元素。

#方式一:逐个获取元素
print(next(reader1))        # ['\ufeff酒店名称', '地区', '地址', '卫生评分', '服务评分', '设施评分', '位置评分', '评价数', '装修时间', '房间类型', '房价', '经度', '纬度', '公司', '出行住宿', '校园生活']

print(next(reader1))        # ['北京朗丽兹西山花园酒店', '海淀区', '海淀永丰路与北清路十字路口往南800米路南', '4.8', '4.8', '4.7', '4.4', '143', '2014', '豪华套间', '9970', '116.292419', '40.095804', '0', '0', '0']

方式二:遍历获取全部元素
# 练习:打印每个酒店对应的平均评分
# 北京朗丽兹西山花园酒店  4.6
for x in reader2:
    # '4.9 + 4.8 + 4.6 + 4.7'
    score = eval(f"{x['卫生评分']} + {x['服务评分']} + {x['设施评分']} + {x['位置评分']}") / 4
    print(x['\ufeff酒店名称'], score)
2.CSV文件写操作

2.1创建列表的writer —csv.writer(文件对象)

writer = csv.writer(open('files/学生信息.csv', 'w', newline=''))

2.1.1写入数据

writer文件对象.writerow(一行内容对应的列表)
writer文件对象.writerows(列表中的元素是每一行内容对应的小列表)
writer.writerow(['姓名', '性别', '年龄', '分数'])
writer.writerows([
    ['小明', '男', 18, 90],
    ['小花', '女', 20, 88]
])

2.2创建字典的writer

csv.DictWriter(文件对象, 字典所有的键)
writer2 = csv.DictWriter(
    open('files/学生信息2.csv', 'w', newline='', encoding='utf-8'),
    ['姓名', '性别', '年龄', '分数']
)

2.2.1写入数据

1) 将字典的键作为第一行内容写入csv文件中
writer2.writeheader()
2) 以字典的方式写入数据
writer2.writerow({'姓名': '小明', '年龄': 18,  '分数': 90, '性别': '男'})
writer2.writerows([
    {'姓名': '小花', '年龄': 20,  '分数': 88, '性别': '女'},
    {'姓名': '张三', '年龄': 28,  '分数': 76, '性别': '男'}
])

二、PDF文件操作

PDF即Portable Document Format,译为“便携式文档格式”,是由Adobe Systems用于与应用程序、操作系统、硬件无关的方式进行文件交换所发展出的文件格式。PDF文件以PostScript语言图像模型为基础,无论在哪种打印机上都可保证精确的颜色和准确的打印效果,即PDF文件会忠实地再现原稿的每一个字符、颜色以及图像。

Adobe 设计PDF文件格式的目的是跨平台支持多媒体集成信息的出版和发布,尤其是提供对网络信息发布的支持。PDF文件格式可以将文字、字型、格式、颜色及独立于设备和分辨率的图形图像等封装在一个文件中。该格式文件还可以包含超文本链接、声音和动态影像等电子信息,支持特长文件,集成度和安全可靠性都较高。

PDF技术要点

PDF主要由三项技术组成:

①衍生自PostScript,用以生成和输出图形。

②字型嵌入系统,可使字型随文件一起传输。

③结构化存储系统,用以绑定这些元素和任何相关内容到单个文件,带有适当的数据压缩系统。

PDF文件使用了工业标准的压缩算法,通常比PostScript文件小,易于传输与存储。PDF还是页独立的,一个PDF文件包含一个或多个‘页’,可以单独处理各页,特别适合多处理器系统的工作。

PDF格式

PDF文件结构主要可以分为四个部分:首部、文件体、交叉引用表、尾部

————以上学习内容引自百度百科https://baike.baidu.com/item/pdf/317608

1.PDF读操作

首先导入模块

from PyPDF2 import PdfFileReader, PdfFileWriter
  • PdfFileReader 可以理解为读取器
  • PdfFileWriter 可以理解为写入器
    读取器只能将读取的内容一页一页交给写入器

1.1创建reader

1)创建reader: PdfFileReader(文件对象)
2)获取总页数: reader文件对象.numPages
3)获取指定页:reader文件对象.getPage(页数)
reader = PdfFileReader(open('files/美食分享.pdf', 'rb'))

page_num = reader.numPages
print(page_num)

# 页数从0开始
page1 = reader.getPage(0)
page2 = reader.getPage(1)

1.2PDF文件写操作

# 1)创建writer
# 创建一个空白的pdf文件(一页内容都没有)
writer = PdfFileWriter()

# 2)添加页
# writer对象.addPage(页对象)  - 添加从别的pdf文件中获取到的页
writer.addPage(page1)

# 添加空白页
writer.addBlankPage()

# 3)保存数据
writer.write(open('files/new.pdf', 'wb'))

练习:将两个PDF文件内容交叉合并

from PyPDF2 import PdfFileReader, PdfFileWriter

reader1 = PdfFileReader(open('files/美食分享.pdf', 'rb'))
reader2 = PdfFileReader(open('files/存储引擎的讲解.pdf', 'rb'))

page_num1 = reader1.numPages
page_num2 = reader2.numPages

min_page = min(page_num1, page_num2)

new_pdf = PdfFileWriter()

for index in range(min_page):
    new_pdf.addPage(reader1.getPage(index))
    new_pdf.addPage(reader2.getPage(index))
    
for page_num1 > page_num2:
    reader = reader1
    max_page = page_num1
else:
    reader = reader2
    max_page = page_num2
for index in range(min_page, max_page):
    new_pdf.addPage(reader.getPage(index))
    
new_pdf.write(open('files/交叉合并.pdf', 'wb'))
三、给PDF文件添加水印

PdfFileReader和PdfFileWriter的配合使用,逻辑如下:

①读取器将所有PDF文件读取一遍。
②读取器将读取的内容交给写入器。
③写入器统一输出到一个新pdf文件。

①和②实际上不是彼此独立的步骤,而是读取器读取完一个pdf后,就讲这个pdf全部页循环一遍,挨页交给写入器,最后等读取工作全部结束后再输出。

情况一:已经有水印,只需要添加,不需要自己创建新的水印

1.准备水印文件和原文件

#导入模块
from PyPDF2 import PdfFileReader, PdfFileWriter

water_reader = PdfFileReader(open('files/watermark.pdf', 'rb'))   		# 水印文件—获取水印的文件
file_reader = PdfFileReader(open('files/存储引擎的讲解.pdf', 'rb'))		 #原文件—需要添加水印的pdf文件

2.获取水印对应的页

#假设水印在文件的第一页
water_page = water_reader.getPage(0)

3.准备需要添加水印的页

#需要添加水印的页为原文件的第一页
page1 = file_reader.gerPage(0)

4.合并水印页和需要添加水印的页

# 使用mergePage
page1.mergePage(water_page)

5.准备空的paf用来保存水印页

new_pdf = PdfFileWriter()
new_pdf.addPage(page1)
new_pdf.write(open('files/新存储引擎的讲解.pdf', 'wb'))

情况二:创建水印文件

导入模块

from reportlab.pdfgen import canvas      # 提供pdf文件
from reportlab.pdfbase import pdfmetrics        # 注册字体
from reportlab.pdfbase.ttfonts import TTFont    # 提供字体对象

1.注册字体

pdfmetrics.registerFont(TTFont('font1', 'files/bb.ttf'))
pdfmetrics.registerFont(TTFont('font2', 'files/dd.ttf'))

2.创建空白pdf

empty_pdf = canvas.Canvas('files/water.pdf')

3.渲染文字

(1)设置字体—setFont(字体名, 字体大小)

empty_pdf.setFont('font1', 20)	# font1为前面注册的字体

(2)设置文字颜色—setFillColorRGB(r, g, b, 透明度)

计算机三原色:红色r、绿色g、蓝色b(0~255)

注意:r\g\b的取值范围是01;透明度的取值范围是01

旋转:empty_pdf.rotate(旋转度数)

(3)渲染文字(写字)—drawString()

empty_pdf.drawString(30, 20, 'Alice')

(4)保存文件—save

empty_pdf.save()