Python处理csv、xlsx、pdf

一、csv文件的处理

CSV(Comma-Separated Values)即逗号分隔值,可以用Excel打开查看。由于是纯文本,任何编辑器也都可打开。与 Excel 文件不同,CSV 文件中:

  • 值没有类型,所有值都是字符串
  • 不能指定字体颜色等样式
  • 不能指定单元格的宽高,不能合并单元格
  • 没有多个工作表
  • 不能嵌入图像图表

1.1 csv读取数据

在CSV文件中,以 "," 作为分隔符,分隔两个单元格。像这样a,,c表示单元格a和单元格c之间有个空白的单元格。依此类推。

不是每个逗号都表示单元格之间的分界。所以即使CSV是纯文本文件,也坚持使用专门的模块进行处理。Python内置了csv模块。先看看一个简单的例子。

#!/usr/bin/env python
# -*- coding:utf-8 -*-
# @Time    : 2018/6/7 20:43
# @Author  : zhouyuyao
# @File    : demon1.py

import csv

filename = "E:/GitHub/Python-Learning/LIVE_PYTHON/2018-06-05/学位英语成绩合格汇总表.csv"
with open(filename) as f:
    reader = csv.reader(f)
    print(list(reader))

reader 不能直接打印,list(reader) 最外层是 list,里层的每一行数据都在一个list中,有点像这样

[['姓名', '性别', '民族', '专业名称', '成绩'], ['刘竞超', '男', '汉族', '工商企业管理', '60'], ··· ···]

如果我们想要知道 “刘竞超” 的成绩 reader[1][5],在 for 循环中遍历如下

#!/usr/bin/env python
# -*- coding:utf-8 -*-
# @Time    : 2018/6/7 20:43
# @Author  : zhouyuyao
# @File    : demon1.py

import csv

filename = "E:/GitHub/Python-Learning/LIVE_PYTHON/2018-06-05/学位英语成绩合格汇总表.csv"
with open(filename) as f:
    reader = csv.reader(f)
    for i in reader:
        # 行号从1开始
        print(reader.line_num,i)

输出的结果如下所示

1 ['姓名', '性别', '民族', '专业名称', '成绩']
2 ['刘竞超', '男', '汉族', '工商企业管理', '60']
3 ['刘毅', '女', '汉族', '金融管理', '70']
4 ['李自根', '男', '汉族', '园林', '75']
5 ··· ···

前面的数字是行号,从1开始,可以用 reader.line_num 获取。

要注意的是,reader 只能被遍历一次。由于 reader 是可迭代对象,可以使用 next方法一次获取一行。

#!/usr/bin/env python
# -*- coding:utf-8 -*-
# @Time    : 2018/6/7 20:43
# @Author  : zhouyuyao
# @File    : demon1.py

import csv

filename = "E:/GitHub/Python-Learning/LIVE_PYTHON/2018-06-05/学位英语成绩合格汇总表.csv"
with open(filename) as f:
    reader = csv.reader(f)
    # 读取一行,下面的reader中已经没有该行了
    head_row=next(reader)
    for i in reader:
        # 行号从2开始
        print(reader.line_num,i)

在这里值得一提的是,在PyCharm中复制路径的时候一直出现找不到文件,这是由于在python程序里面我们经常需要对文件进行操作,Windows 下的文件目录路径使用反斜杠 “\” 来分隔。但是,和大多数语言一样,Python 代码里面,反斜杠 “\” 是转义符,例如 “\n” 表示回车、“\t” 表示制表符等等。这样,如果继续用windows 习惯使用 “\” 表示文件路径,就会产生歧义。

      例如:“c:\test.txt” 这表示 c 盘根目录下的一个文件,还是表示一个字符串呢?因为 “\t” 也可以解释为制表符。如果让我们人来判断,这当然是一个很简单的问题。但是机器就无法做出正确的判断了,只有没有歧义的代码机器才会正确执行。

      解决办法,采用下面任何一种书写形式均可:

  • 使用斜杠“/”: "c:/test.txt"… 不用反斜杠就没法产生歧义了 
  • 将反斜杠符号转义: "c:\\test.txt"… 因为反斜杠是转义符,所以两个"\\"就表示一个反斜杠符号 
  • 使用Python的raw string: r"c:\test.txt" … python下在字符串前面加上字母r,表示后面是一个原始字符串raw string,不过raw string主要是为正则表达式而不是windows路径设计的,所以这种做法尽量少用,可能会出问题。

1.2 csv写入数据

有reader可以读取,当然也有writer可以写入。一次写入一行,一次写入多行都可以。

#!/usr/bin/env python
# -*- coding:utf-8 -*-
# @Time    : 2018/6/8 10:12
# @Author  : zhouyuyao
# @File    : demon2.py

import csv

# 使用数字和字符串的数字都可以
datas=[
    ['朱丽蓉', '女', '汉族', '金融管理', '84'],
    ['吴江滔', '女', '汉族', '企业财务管理', '78']
]

filename = "E:/GitHub/Python-Learning/LIVE_PYTHON/2018-06-05/学位英语成绩合格汇总表.csv"
with open(filename,"a",newline="") as f:
    writer = csv.writer(f)
    for row in datas:
        writer.writerow(row)

    # 写入多行
    writer.writerows(datas)

之后我们可以在csv文件中看到刚刚写入的数据

1 ['姓名', '性别', '民族', '专业名称', '成绩']
2 ['张沐青', '女', '汉族', '金融管理', '62']
3 ['金彦豪', '男', '朝鲜族', '环境工程', '67']
4 ['朱丽蓉', '女', '汉族', '金融管理', '84']
5 ['吴江滔', '女', '汉族', '企业财务管理', '78']
6 ['朱丽蓉', '女', '汉族', '金融管理', '84']
7 ['吴江滔', '女', '汉族', '企业财务管理', '78']

DictReader 和 DictWriter 对象

使用 DictReader 可以像操作字典那样获取数据,把表的第一行(一般是标头)作为 key。可访问每一行中那个某个 key 对应的数据。

#!/usr/bin/env python
# -*- coding:utf-8 -*-
# @Time    : 2018/6/8 10:12
# @Author  : zhouyuyao
# @File    : demon2.py

import csv

# 使用数字和字符串的数字都可以
datas = [
    {'姓名': '张沐青', '性别': '女', '民族': '汉族', '专业名称': '金融管理', '成绩': '62'}
]

filename = "E:/GitHub/Python-Learning/LIVE_PYTHON/2018-06-05/学位英语成绩合格汇总表.csv"

with open(filename, "a") as f:
    headers = [k for k in datas[0]]        # 取出待写入数据中的 key 值
    writer = csv.DictWriter(f, headers)
    '''
    __init__(self, f, fieldnames, restval="", extrasaction="raise",
                 dialect="excel", *args, **kwds):
        self.fieldnames = fieldnames    # list of keys for the dict
        self.restval = restval          # for writing short dicts
        if extrasaction.lower() not in ("raise", "ignore"):
            raise ValueError("extrasaction (%s) must be 'raise' or 'ignore'"
                             % extrasaction)
        self.extrasaction = extrasaction
        self.writer = writer(f, dialect, *args, **kwds)
    '''
    writer.writeheader()
    '''
    def writeheader(self):
        header = dict(zip(self.fieldnames, self.fieldnames))
            self.writerow(header)
    '''
    for row in datas:
        writer.writerow(row)
    # 写入多行
    # writer.writerows(datas)

with open(filename, 'r+') as csv_file:
    reader = csv.DictReader(csv_file)
    '''
        def __init__(self, f, fieldnames=None, restkey=None, restval=None,
                 dialect="excel", *args, **kwds):
        self._fieldnames = fieldnames   # list of keys for the dict
        self.restkey = restkey          # key to catch long rows
        self.restval = restval          # default value for short rows
        self.reader = reader(f, dialect, *args, **kwds)
        self.dialect = dialect
        self.line_num = 0
    '''
    print(str([row for row in reader]))

运行之后在IDE的显示结果如下

[OrderedDict([('姓名', '张沐青'), ('性别', '女'), ('民族', '汉族'), ('专业名称', '金融管理'), ('成绩', '62')]), OrderedDict([('姓名', '金彦豪'), ('性别', '男'), ('民族', '朝鲜族'), ('专业名称', '环境工程'), ('成绩', '67')]), OrderedDict([('姓名', '姓名'), ('性别', '性别'), ('民族', '民族'), ('专业名称', '专业名称'), ('成绩', '成绩')]), OrderedDict([('姓名', '张沐青'), ('性别', '女'), ('民族', '汉族'), ('专业名称', '金融管理'), ('成绩', '62')])]

用 Excel 打开 csv 文件显示如下

二、Excel 的处理

python 提供有第三方库来支持excel的操作,python处理excel文件用的第三方模块库,有xlrd、xlwt、xluntils和pyExcelerator,

除此之外,python处理excel还可以用win32com和openpyxl模块.

我们主要用xlrd、xlwt、xluntils这三个模块,pyExcelerator模块偶尔也会用:

pip install xlrd
pip install xlwt
pip install xlutils
pip install pyExcelerator

xlrd 只能进行读取excel文件,没法进行写入文件;

xlwt 可以写入文件,但是不能在已有的excel的文件上进行修改;

xluntils 可以在已有的excel文件上进行修改;

pyExcelerator 与xlwt类似,也可以用来生成excel文件

2.1 读取表单数据

1)按行取数据

#!/usr/bin/env python
# -*- coding:utf-8 -*-
# @Time    : 2018/6/8 13:58
# @Author  : zhouyuyao
# @File    : demon1.py
import xlrd

filename="E:/GitHub/Python-Learning/LIVE_PYTHON/2018-06-07/学位英语成绩合格汇总表.xls"

def readExcel():
    data = xlrd.open_workbook(filename)
    table = data.sheets()[0]            # 打开第一张表
    nrows = table.nrows                 # 获取表的行数
    for i in range(nrows):              # 循环逐行打印
        print(table.row_values(i))      # 通过row_values来获取每行的值

if __name__ == '__main__':
    readExcel()

读取结果

['姓名', '性别', '民族', '专业名称', '成绩']
['张沐青', '女', '汉族', '金融管理', 62.0]
['金彦豪', '男', '朝鲜族', '环境工程', 67.0]
['毛倩', '女', '汉族', '金融管理', 60.0]
['周冬', '男', '汉族', '企业财务管理', 64.0]

2)按列取数据

#!/usr/bin/env python
# -*- coding:utf-8 -*-
# @Time    : 2018/6/8 14:23
# @Author  : zhouyuyao
# @File    : demon2.py
filename="E:/GitHub/Python-Learning/LIVE_PYTHON/2018-06-07/学位英语成绩合格汇总表.xls"

import xlrd
data = xlrd.open_workbook(filename)
table2 = data.sheet_by_name("test2")       # "test2" 为 sheet 标签页的名称
for col in range(table2.ncols):
    print (table2.col_values(col))

读取结果如下

['姓名', '刘竞超', '刘毅', '李自根', '李思琦']
['性别', '男', '女', '男', '男']
['民族', '汉族', '汉族', '汉族', '汉族']
['专业名称', '工商企业管理', '金融管理', '园林', '工商管理']
['成绩', 60.0, 70.0, 75.0, 78.0]

3)创建新的并写入,不修改

#!/usr/bin/env python
# -*- coding:utf-8 -*-
# @Time    : 2018/6/8 14:30
# @Author  : zhouyuyao
# @File    : demon3.py
import xlwt
excel = xlwt.Workbook()

# 创建3个表
sheet1 = excel.add_sheet("test1",cell_overwrite_ok=True)
#                                cell_overwrite_ok 参数用来确认同一个cell单元是否可以重设值
sheet2 = excel.add_sheet("test2")
sheet3 = excel.add_sheet("test3")

# 只在第一个表sheet1里写数据,如下:
sheet1.write(0,0,"hello world1")
sheet1.write(1,0,"hello world2")
sheet1.write(2,0,"hello world3")
# 第一个是行,第二个是列,第三个是内容。

excel.save("./hello.xlsx")
print("创建hello.xlsx完成")

运行之后在代码文件的同级目录下将创建一个 hello.xlsx 文件,并且有三张表,第一张表中有三行内容,内容如下

6a0d21e51648e179369eecb144e7c7c0198.jpg

注:每一个 excel 文件就是一个工作簿。每个工作簿中有一张或若干张工作表。

4)字体效果

使用样式,字体类型、加粗等效果:

#!/usr/bin/env python
# -*- coding:utf-8 -*-
# @Time    : 2018/6/8 14:51
# @Author  : zhouyuyao
# @File    : demon4.py
import xlwt
excel = xlwt.Workbook()

# 创建3个表
sheet1 = excel.add_sheet("sheet1")
sheet2 = excel.add_sheet("sheet2")
sheet3 = excel.add_sheet("sheet3")

# 初始化样式
style = xlwt.XFStyle()

# 为样式创建字体
font = xlwt.Font()
font.name = u'微软雅黑'          # 指定字体名称
font.bold = True                # 是否加粗

# 设置样式的字体
style.font = font

# 使用样式
sheet3.write(0,1,u'微软雅黑',style)

# 保存该excel文件,有同名文件时直接覆盖
excel.save('world.xlsx')
print('创建world.xlsx文件完成!')

运行之后将在同级目录下创建一个  world.xlsx 文件,在第三张表的第一行第二列新增内容,如下所示

b99a894d2736969eb368138da984866a79b.jpg

5)处理超链接

#!/usr/bin/env python
# -*- coding:utf-8 -*-
# @Time    : 2018/6/8 14:58
# @Author  : zhouyuyao
# @File    : demon5.py

import codecs
import xlwt

book = xlwt.Workbook()
sheet_index = book.add_sheet('index')
line=0
for i in range(9):
    link = 'HYPERLINK("{0}.txt", "{1}_11111")'.format(i, i)
    # {0}.txt是要链接的文件,{1}_11111是链接文件的内容

    sheet_index.write(i, 0, xlwt.Formula(link))
    # 第一个行号,第二个列号,第三个是写入内容link,内容里面超链接
book.save('HowAreYou.xlsx')
for i in range(0, 9):
    file = str(i) + ".txt"
    with codecs.open(file, 'w') as f:
        f.write(str(i)*10)

运行之后将在同级目录下创建 8 个 txt 文件和一个 Excel 文件,打开 Excel 文件,点击一行的内容都将链接到一个txt 文件并打开它

32af29d3d2b1d80e5f3a076b24b6d699906.jpg

三、PDF文件的处理

转换成pdf的三种方法:

在工作中,会遇到把html文件转换成pdf文件

python给我们提供了pdfkit这个模块,直接安装使用就可以了

这里需要注意的是,为了更好的处理,我们需要在 Windows 上从  https://wkhtmltopdf.org/ 下载 wkhtmltopdf 应用,以便在代码中进行调用 (Windows 上为 exe 文件,Linux 上为二进制文件)。

下面就来介绍一个pdfkit模块的几种用法

首先,我们安装该模块:

pip install pdfkit

1)网页转换成 pdf(直接把 url 转换成 pdf 文件)

import pdfkit
pdfkit.from_url('http://google.com', 'out1.pdf')

2) Html转换成pdf

import pdfkit
pdfkit.from_file('test.html', 'out2.pdf')

3) 字符串转换成pdf

import pdfkit
pdfkit.from_string('Hello lingxiangxiang!', 'out3.pdf')

三种方法简单例子:

import pdfkit
pdfkit.from_file("hello.html", 1.pdf)
pdfkit.from_url("www.baidu.com", 2.pdf)
pdfkit.from_string("hello world", 3.pdf)

即可生成pdf文件~

举例:

抓取aming的linux教程,然后制作成pdf文件

先抓取每个的网页,然后生成pdf文件

(1)查看网页源代码

(2)查看源代码内容

<ul>
<li class="toctree-l1"><a class="reference internal" href="chapter1.html">第1章 前言</a></li>
<li class="toctree-l1"><a class="reference internal" href="chapter2.html">第2章 关于Linux的历史</a></li>
<li class="toctree-l1"><a class="reference internal" href="chapter3.html">第3章 对Linux系统管理员的建议</a><ul>
<li class="toctree-l2"><a class="reference internal" href="chapter3.html#id1">要安装什么版本的Linux操作系统</a></li>
<li class="toctree-l2"><a class="reference internal" href="chapter3.html#id2">图形界面还是命令窗口</a></li>
<li class="toctree-l2"><a class="reference internal" href="chapter3.html#id3">养成安全严谨的习惯</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="chapter4.html">第4章 安装Linux操作系统</a><ul>
<li class="toctree-l2"><a class="reference internal" href="chapter4.html#id1">安装虚拟机</a></li>
<li class="toctree-l2"><a class="reference internal" href="chapter4.html#id3">下载Linux操作系统镜像文件</a></li>
<li class="toctree-l2"><a class="reference internal" href="chapter4.html#centos">安装CentOS (图形化安装)</a></li>
<li class="toctree-l2"><a class="reference internal" href="chapter4.html#id6">安装CentOS (文本模式安装)</a></li>
</ul>
</li>

和url对应规律

http://www.apelearn.com/study_v2/chapter2.html

http://www.apelearn.com/study_v2/chapter5.html

http://www.apelearn.com/study_v2/chapter7.html

... ...

通过 https://regex101.com/ 正则网站,把需要的字段给过滤出来

<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"(.*)\">.*<\/a><\/li>

具体实现代码如下

#!/usr/bin/env python
# -*- coding:utf-8 -*-
# @Time    : 2018/6/8 15:28
# @Author  : zhouyuyao
# @File    : demon1.py
import os
import re
import pdfkit
import requests

if not os.path.exists("aminglinux"):
    os.mkdir("aminglinux")

os.chdir("aminglinux")

url = "http://www.apelearn.com/study_v2/"
s = requests.session()
text = s.get(url).text
reg = re.compile(r'<li class=\"toctree-l1\"><a class=\"reference internal\" href=\"(.*)\">.*<\/a><\/li>')
result = reg.findall(text)
res = list(set(result))

def html_to_pdf():
    for i in res:
        purl = "{0}{1}".format(url, i)
        print(purl)
        pdfFileName = i.replace("html", "pdf")
        print(pdfFileName)
        config = pdfkit.configuration(wkhtmltopdf=r"d:\Program Files\wkhtmltopdf\bin\wkhtmltopdf.exe")
        try:
            pdfkit.from_url(purl, pdfFileName, configuration=config)
        except:
            continue

if __name__ == '__main__':
    html_to_pdf()

运行之后将得到一个文件夹,内容是所选取网站目录下的所有 html 转换成 PDF 的文件

cd045bb075322d161b3e4c9bb73e73c6f5b.jpg

参考资料

1. https://www.cnblogs.com/yanglang/p/7126660.html  Python处理csv文件

2. https://blog.csdn.net/u010189241/article/details/39449847 Windows环境下Python代码的文件路径问题

3. https://blog.csdn.net/ko_tin/article/details/72627266 Python CSV Reader/Writer/DictReader/DictWriter例子

4. https://blog.csdn.net/u014234300/article/details/51221272  Python处理Excel(一):Excel的简单处理

5. https://www.cnblogs.com/chrischeng/p/7050027.html Python处理Excel文件

6. https://www.xlwings.org/

7. http://blog.51cto.com/286577399/2062339 Python 数据处理

转载于:https://my.oschina.net/u/3314358/blog/1827101

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值