python从TXT创建PDF文件——reportlab
使用reportlab创建PDF文件
电子书一般都是txt格式的,某些电子阅读器不能读取txt的文档,如DPT-RP1。因此本文从使用python实现txt到pdf的转换,并且支持生成目录,目录能够生成连接进行点击(前提是在txt文件中能够知道每个章节的位置),支持中文。
reportlab的使用可以查看reportlab官方文档。txt转pdf详细代码如下:
# coding: utf-8
# setting sts font utf-8
import sys
reload(sys)
sys.setdefaultencoding('utf-8')
from reportlab.pdfbase import pdfmetrics
from reportlab.pdfbase.ttfonts import TTFont
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.platypus import BaseDocTemplate, Frame, PageTemplate, Paragraph
from reportlab.platypus.tableofcontents import TableOfContents
from reportlab.platypus import PageBreak
from reportlab.lib.pagesizes import A4
pdfmetrics.registerFont(TTFont('STSONG', './STSONG.TTF')) #register Font
pdfmetrics.registerFont(TTFont('simhei', './simhei.ttf')) #register Font
styles = getSampleStyleSheet()
styles.add(ParagraphStyle(fontName='STSONG', name='STSONG', leading=20, fontSize=12, firstLineIndent=22, wordWrap='CJK'))
styles.add(ParagraphStyle(fontName='simhei', name='simhei', leading=25, fontSize=14, wordWrap='CJK')) # content Font
class MyDocTemplate(BaseDocTemplate):
def __init__(self, filename, **kw):
self.allowSplitting = 0
apply(BaseDocTemplate.__init__, (self, filename), kw)
# Entries to the table of contents can be done either manually by
# calling the addEntry method on the TableOfContents object or automatically
# by sending a 'TOCEntry' notification in the afterFlowable method of
# the DocTemplate you are using. The data to be passed to notify is a list
# of three or four items countaining a level number, the entry text, the page
# number and an optional destination key which the entry should point to.
# This list will usually be created in a document template's method like
# afterFlowable(), making notification calls using the notify() method
# with appropriate data.
def afterFlowable(self, flowable):
"Registers TOC entries."
if flowable.__class__.__name__ == 'Paragraph':
text = flowable.getPlainText()
style = flowable.style.name
if style == 'Heading1':
level = 0
elif style == 'simhei':
level = 1
else:
return
E = [level, text, self.page]
#if we have a bookmark name append that to our notify data
bn = getattr(flowable,'_bookmarkName',None)
if bn is not None: E.append(bn)
self.notify('TOCEntry', tuple(E))
# this function makes our headings
def doHeading(data, text, sty):
from hashlib import sha1
# create bookmarkname
bn = sha1(text).hexdigest()
# modify paragraph text to include an anchor point with name bn
h = Paragraph(text + '<a name="%s"/>' % bn, sty)
# store the bookmark name on the flowable so afterFlowable can see this
h._bookmarkName = bn
data.append(h)
# Page Number
def footer(canvas, doc):
page_num = canvas.getPageNumber()
canvas.saveState()
P = Paragraph("%d" % page_num ,
styles['Normal'])
w, h = P.wrap(doc.width, doc.bottomMargin)
P.drawOn(canvas, doc.leftMargin + w/2, h)
canvas.restoreState()
# load txt file
def loadTxt(txt_path):
with open(txt_path, 'r') as f:
txt_datas = f.readlines()
return txt_datas
def toPDF(txt_datas, pdf_path):
PDF = MyDocTemplate(pdf_path, pagesize=A4)
frame = Frame(PDF.leftMargin, PDF.bottomMargin, PDF.width, PDF.height,
id='normal')
template = PageTemplate(frames=frame, onPage=footer)
PDF.addPageTemplates([template])
data = []
# table of contents
toc = TableOfContents()
# setting contents fontName and fontSize
toc.levelStyles = [
ParagraphStyle(fontName='simhei', fontSize=20, name='TOCHeading1', leftIndent=20, firstLineIndent=-20, spaceBefore=10,
leading=16),
ParagraphStyle(fontName='simhei', fontSize=18, name='TOCHeading2', leftIndent=40, firstLineIndent=-20, spaceBefore=5, leading=12),
]
data.append(toc) # add contents
data.append(PageBreak()) #next page
NUM = 0
# add txt
for txt_data in txt_datas:
txt_data = txt_data.lstrip() # remove left space
if len(txt_data) == 0: # no text
continue
try:
txt_data = txt_data.decode("gb2312")
except:
txt_data = txt_data.decode("gbk")
if txt_data[0] == u"第" and (u"章" in txt_data):
doHeading(data, txt_data, styles['simhei'])
else:
data.append(Paragraph(txt_data, styles['STSONG']))
NUM = NUM + 1
print('{} line'.format(NUM))
print('Build pdf!')
PDF.multiBuild(data)
if __name__ == "__main__":
txt_path = "财运天降.txt".decode("utf8")
pdf_path = "财运天降.pdf".decode("utf8")
txt_datas = loadTxt(txt_path)
toPDF(txt_datas, pdf_path)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
本代码在windows和python2下进行测试,主要注意有:
系统默认字体设置:
import sys
reload(sys)
sys.setdefaultencoding('utf-8')
1
2
3
中文字体支持:
pdfmetrics.registerFont(TTFont('STSONG', './STSONG.TTF')) #register Font
pdfmetrics.registerFont(TTFont('simhei', './simhei.ttf')) #register Font
styles = getSampleStyleSheet(http://www.my516.com)
styles.add(ParagraphStyle(fontName='STSONG', name='STSONG', leading=20, fontSize=12, firstLineIndent=22, wordWrap='CJK'))
styles.add(ParagraphStyle(fontName='simhei', name='simhei', leading=25, fontSize=14, wordWrap='CJK')) # content Font
1
2
3
4
5
中文目录字体:
toc.levelStyles = [
ParagraphStyle(fontName='simhei', fontSize=20, name='TOCHeading1', leftIndent=20, firstLineIndent=-20, spaceBefore=10,
leading=16),
ParagraphStyle(fontName='simhei', fontSize=18, name='TOCHeading2', leftIndent=40, firstLineIndent=-20, spaceBefore=5, leading=12),
]
1
2
3
4
5
目录定位,这个需要根据你实际的txt文章进行定位修改
if txt_data[0] == u"第" and (u"章" in txt_data):
1
中文解码,由于繁体中文不能解码为gb2312,因此使用try-except的方式
try:
txt_data = txt_data.decode("gb2312")
except:
txt_data = txt_data.decode("gbk")
1
2
3
4
其效果如下:
网上随便找了个txt文章:
生成pdf目录:
生成pdf内容:
---------------------
python从TXT创建PDF文件——reportlab的更多相关文章
- 深入学习Python解析并解密PDF文件内容的方法
前面学习了解析PDF文档,并写入文档的知识,那篇文章的名字为深入学习Python解析并读取PDF文件内容的方法. 链接如下:https://www.cnblogs.com/wj-1314/p/9429 ...
- 深入学习python解析并读取PDF文件内容的方法
这篇文章主要学习了python解析并读取PDF文件内容的方法,包括对学习库的应用,python2.7和python3.6中python解析PDF文件内容库的更新,包括对pdfminer库的详细解释和应 ...
- 51单片机创建PDF文件
PDF文件有特定的格式要求,本以为.TXT与.PDF之间可以相互转换,只需要修改后缀名就可以了,然而事实并非如此. 如下为.PDF文件打开的编码显示. 如果需要创建PDF文件,只需要按照PDF的编码格 ...
- Java 创建PDF文件包的2种方法
1. 概述 PDF文件包可方便在仅打开一个窗口的情况下阅读多个文档,通过将多个PDF文档或其他非PDF文档封装在一起,打开文件包后可以随意切换查看文件包中的文档,在需要编辑更改的情况,也可以打开文本包 ...
- 使用iText库创建PDF文件
前言 译文连接:http://howtodoinjava.com/apache-commons/create-pdf-files-in-java-itext-tutorial/ 对于excel文件的读 ...
- 怎么用OCR图文识别软件在MS Office中创建PDF文件
ABBYY PDF Transformer+是一款可创建.编辑及将PDF文件转换为其他可编辑格式的OCR图文识别软件,不仅可以从纸质文档.图像文件和任何其他流行格式创建PDF文件(相关文章请参考如何从 ...
- 01.在Java中如何创建PDF文件
1.简介 在这篇快速文章中,我们将重点介绍基于流行的iText和PdfBox库从头开始创建 PDF 文档. 2. Maven 依赖 <dependency> <groupId> ...
- 利用Python将多个PDF文件合并
from PyPDF2 import PdfFileMerger import os files = os.listdir()#列出目录中的所有文件 merger = PdfFileMerger() ...
- 【转】Python 深入浅出 - PyPDF2 处理 PDF 文件
实际应用中,可能会涉及处理 pdf 文件,PyPDF2 就是这样一个库,使用它可以轻松的处理 pdf 文件,它提供了读,割,合并,文件转换等多种操作. 文档地址:http://pythonhosted ...
随机推荐
- xth的第 12 枚硬币(codevs 1366)
题目描述 Description 传说 xth 曾经拥有11枚完全相同硬币(你懂得),不过今年呢,rabbit又送了他一 枚硬币.这枚硬币和其他硬币外观相同,只有重量不同,或轻或重.Xth 一不小心, ...
- fixed_date , 赋权技巧 ,procedure执行方式, PL/SQL注意的地方
本文讨论4个知识点, 1. fixed_date参数 2. 赋权技巧 3. procedure执行的方式 4. PL/SQL中要注意的几个地方 fixed_date参数 客户想修改oracle的 系统 ...
- 将XML文件转化成NSData对象
NSData *xmlData = [[NSData alloc]initWithContentsOfFile:[NSString stringWithFormat:@"%@/People. ...
- jQuery toast message 地址 使用
jQuery toast message 地址 使用 https://github.com/akquinet/jquery-toastmessage-plugin/wiki
- 【Linux学习】Ubuntu下 sambaserver搭建
1.安装samba,smbfs 2.配置smb.conf文件 配置文件之前须要先备份一下须要配置的文件(养成好的习惯) 输入命令: 进入到smb.conf文件里,在文件的最后加入下列语句 保存后.退出 ...
- android:怎样用一天时间,写出“飞机大战”这种游戏!(无框架-SurfaceView绘制)
序言作为一个android开发人员,时常想开发一个小游戏娱乐一下大家,今天就说说,我是怎么样一天写出一个简单的"飞机大战"的. 体验地址:http://www.wandoujia. ...
- 基于Windows Azure 搭建基于SharePoint 2010 Intranet、Extranet、Internet (4): 配置传出邮件服务: 使用 outlook.com 发送邮件通知
前几篇文章,已经安装了SharePoint 2010,今天将演示如何配置传出邮件.由于某些原因,企业可能没有安装自己邮件服务器,此时我们可以使用公共的邮箱服务来发送邮件通知,比如outlook.com ...
- 使用百度地图API进行Android地图应用开发(Eclipse)
随着基于位置的服务的兴起,地图类App呈现爆发趋势.随着而来的是地图供应商开放大量的API.供开发人员开发基于PC或者移动端的应用程序. 如今我们研究使用百度地图SDK进行Android项目的开发. ...
- css3 动态背景
动态背景 利用多层背景的交替淡入淡出,实现一种背景在不停变换的效果,先看图. 效果图: DEMO地址 步骤 1.利用css的radial-gradient创建一个镜像渐变的背景.当中的80% 20%为 ...
- Android单选中listview中的一项
public class LipsListAdapter extends BaseAdapter { private Context context; private List<Lips> ...