使用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的更多相关文章

  1. 深入学习Python解析并解密PDF文件内容的方法

    前面学习了解析PDF文档,并写入文档的知识,那篇文章的名字为深入学习Python解析并读取PDF文件内容的方法. 链接如下:https://www.cnblogs.com/wj-1314/p/9429 ...

  2. 深入学习python解析并读取PDF文件内容的方法

    这篇文章主要学习了python解析并读取PDF文件内容的方法,包括对学习库的应用,python2.7和python3.6中python解析PDF文件内容库的更新,包括对pdfminer库的详细解释和应 ...

  3. 51单片机创建PDF文件

    PDF文件有特定的格式要求,本以为.TXT与.PDF之间可以相互转换,只需要修改后缀名就可以了,然而事实并非如此. 如下为.PDF文件打开的编码显示. 如果需要创建PDF文件,只需要按照PDF的编码格 ...

  4. Java 创建PDF文件包的2种方法

    1. 概述 PDF文件包可方便在仅打开一个窗口的情况下阅读多个文档,通过将多个PDF文档或其他非PDF文档封装在一起,打开文件包后可以随意切换查看文件包中的文档,在需要编辑更改的情况,也可以打开文本包 ...

  5. 使用iText库创建PDF文件

    前言 译文连接:http://howtodoinjava.com/apache-commons/create-pdf-files-in-java-itext-tutorial/ 对于excel文件的读 ...

  6. 怎么用OCR图文识别软件在MS Office中创建PDF文件

    ABBYY PDF Transformer+是一款可创建.编辑及将PDF文件转换为其他可编辑格式的OCR图文识别软件,不仅可以从纸质文档.图像文件和任何其他流行格式创建PDF文件(相关文章请参考如何从 ...

  7. 01.在Java中如何创建PDF文件

    1.简介 在这篇快速文章中,我们将重点介绍基于流行的iText和PdfBox库从头开始创建 PDF 文档. 2. Maven 依赖 <dependency> <groupId> ...

  8. 利用Python将多个PDF文件合并

    from PyPDF2 import PdfFileMerger import os files = os.listdir()#列出目录中的所有文件 merger = PdfFileMerger() ...

  9. 【转】Python 深入浅出 - PyPDF2 处理 PDF 文件

    实际应用中,可能会涉及处理 pdf 文件,PyPDF2 就是这样一个库,使用它可以轻松的处理 pdf 文件,它提供了读,割,合并,文件转换等多种操作. 文档地址:http://pythonhosted ...

随机推荐

  1. 同开三本DJANGO,需要提升一下本职工作的能力啦

    慢慢将一些概念固化到基因内,才有可能和SPRING MVC,MEAN之类的好好作比较吧. 全都是基于1.8版本的教材,爽!!!

  2. ZooKeeper环境搭建(单机/集群)(转)

    前提: 配置文件主要是在$ZOOKEEPER_HOME/conf/zoo.cfg,刚解压时为zoo_sample.cfg,重命名zoo.cfg即可. 配置文件常用项参考:http://www.cnbl ...

  3. oracle rac cache fusion

    转载自 http://blog.csdn.net/tianlesoftware/article/details/6534239 Introduction This post is about orac ...

  4. Java学习笔记之 IO包 字节流

    IO包最重要的五个类和一个接口 File/OutputStream/InputStream(字节流)/Writer/Reader(字符流) 一个接口:Serializable   File类: 字节流 ...

  5. Spring MVC新手教程(一)

    直接干货 model 考虑给用户展示什么.关注支撑业务的信息构成.构建成模型. control 调用业务逻辑产生合适的数据以及传递数据给视图用于呈献: view怎样对数据进行布局,以一种优美的方式展示 ...

  6. Android开发之PullToRefresh的Click点击事件的监听实现长按删除Item

    本文为原创博客.出自http://blog.csdn.net/minimicall 到今天为止,搜芽的卖家版本号应该来说已经基本完毕.攻坚克难的一路过来.速度也控制的比較好. 项目过程进度 从任务分配 ...

  7. Java时间转换

    package com.fh.util; import java.sql.Timestamp; import java.text.DateFormat; import java.text.ParseE ...

  8. Html5笔记 表格 布局

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  9. 【Java并发编程实战】—– AQS(四):CLH同步队列

    在[Java并发编程实战]-–"J.U.C":CLH队列锁提过,AQS里面的CLH队列是CLH同步锁的一种变形. 其主要从双方面进行了改造:节点的结构与节点等待机制.在结构上引入了 ...

  10. log4net preserveLogFileNameExtension 和 watch

    preserveLogFileNameExtension <log4net> <appender name="fileappender" type="l ...