笔者在今天的工作中, 遇到了一个需求, 那就是如何将 Python 字符串生成 PDF. 比如, 需要把 Python 字符串'这是测试文件'生成为 PDF, 该 PDF 中含有文字'这是测试文件'.
经过一番检索, 笔者决定采用 wkhtmltopdf 这个软件, 它可以将 HTML 转化为 PDF.wkhtmltopdf 的访问网址为: https://wkhtmltopdf.org/downloads.html , 读者可根据自己的系统下载对应的文件并安装. 安装好 wkhtmltopdf, 我们再安装这个软件的 Python 第三方模块 --pdfkit, 安装方式如下:
pip install pdfkit
我们再讨论如下问题:
如何将 Python 字符串生成 PDF;
如何生成 PDF 中的表格;
解决 PDF 生成速度慢的问题.
如何将 Python 字符串生成 PDF
该问题的解决思路还是利用将 Python 字符串嵌入到 HTML 代码中解决, 注意换行需要用 < br > 标签, 示例代码如下:
- import pdfkit
- # PDF 中包含的文字
- content = '这是一个测试文件.' + '<br>' + 'Hello from Python!'
- HTML = '<html><head><meta charset="UTF-8"></head>' \
- '<body><div align="center"><p>%s</p></div></body></html>'%content
- # 转换为 PDF
- pdfkit.from_string(HTML, './test.pdf')
输出的结果如下:
- Loading pages (1/6)
- Counting pages (2/6)
- Resolving links (4/6)
- Loading headers and footers (5/6)
- Printing pages (6/6)
- Done
生成的 test.PDF 如下:
如何生成 PDF 中的表格
接下来我们考虑如何将 CSV 文件转换为 PDF 中的表格, 思路还是利用 HTML 代码. 示例的 iris.CSV 文件 (部分) 如下:
将 CSV 文件转换为 PDF 中的表格的 Python 代码如下:
- import pdfkit
- # 读取 CSV 文件
- with open('iris.csv', 'r') as f:
- lines = [_.strip() for _ in f.readlines()]
- # 转化为 HTML 中的表格样式
- td_width = 100
- content = '<table width="%s"border="1"cellspacing="0px"style="border-collapse:collapse">' % (td_width*len(lines[0].split(',')))
- for i in range(len(lines)):
- tr = '<tr>'+''.join(['<td width="%d">%s</td>'%(td_width, _) for _ in lines[i].split(',')])+'</tr>'
- content += tr
- content += '</table>'
- HTML = '<html><head><meta charset="UTF-8"></head>' \
- '<body><div align="center">%s</div></body></html>' % content
- # 转换为 PDF
- pdfkit.from_string(HTML, './iris.pdf')
生成的 PDF 文件为 iris.PDF, 部分内容如下:
解决 PDF 生成速度慢的问题
用 pdfkit 生成 PDF 文件虽然方便, 但有一个比较大的缺点, 那就是生成 PDF 的速度比较慢, 这里我们可以做个简单的测试, 比如生成 100 份 PDF 文件, 里面的文字为 "这是第 * 份测试文件!".Python 代码如下:
- import pdfkit
- import time
- start_time = time.time()
- for i in range(100):
- content = '这是第 %d 份测试文件!'%(i+1)
- HTML = '<html><head><meta charset="UTF-8"></head>' \
- '<body><div align="center">%s</div></body></html>' % content
- # 转换为 PDF
- pdfkit.from_string(HTML, './test/%s.pdf'%(i+1))
- end_time = time.time()
- print('一共耗时:%s 秒.' %(end_time-start_time))
在这个程序中, 生成 100 份 PDF 文件一共耗时约 192 秒. 输出结果如下:
- ......
- Loading pages (1/6)
- Counting pages (2/6)
- Resolving links (4/6)
- Loading headers and footers (5/6)
- Printing pages (6/6)
- Done
一共耗时: 191.9226369857788 秒.
如果想要加快生成的速度, 我们可以使用多线程来实现, 主要使用 concurrent.futures 模块, 完整的 Python 代码如下:
- import pdfkit
- import time
- from concurrent.futures import ThreadPoolExecutor, wait, ALL_COMPLETED
- start_time = time.time()
- # 函数: 生成 PDF
- def convert_2_pdf(i):
- content = '这是第 %d 份测试文件!'%(i+1)
- HTML = '<html><head><meta charset="UTF-8"></head>' \
- '<body><div align="center">%s</div></body></html>' % content
- # 转换为 PDF
- pdfkit.from_string(HTML, './test/%s.pdf'%(i+1))
- # 利用多线程生成 PDF
- executor = ThreadPoolExecutor(max_workers=10) # 可以自己调整 max_workers, 即线程的个数
- # submit()的参数: 第一个为函数, 之后为该函数的传入参数, 允许有多个
- future_tasks = [executor.submit(convert_2_pdf, i) for i in range(100)]
- # 等待所有的线程完成, 才进入后续的执行
- wait(future_tasks, return_when=ALL_COMPLETED)
- end_time = time.time()
- print('一共耗时:%s 秒.' %(end_time-start_time))
在这个程序中, 生成 100 份 PDF 文件一共耗时约 41 秒, 明显快了很多~
注意: 不妨了解下笔者的微信公众号: Python 爬虫与算法(微信号为: easy_web_scrape), 欢迎大家关注~
来源: https://www.cnblogs.com/jclian91/p/10880822.html