flowable 中文文档_取出word文档文字内容生成加了目录、标号和页码的PDF文件

word文档内的一页:

71d101ec91e632e7b7170306e8ffd4d7.png

将文本取出来,生成自定义格式的PDF文件:

b6b7d14b36583baef5d2b4bbdb8aa742.png

从word取出文本时标题的标号和页码是取不出来的,要自己加。另外就是目录也要自己生成和添加:

357f4398519ccb7865f12fe41c5fe884.png

代码和解释如下:

from reportlab.lib.styles import ParagraphStyle as PS   # 段落格式from reportlab.platypus import PageBreak                # 分页符from reportlab.platypus.paragraph import Paragraph      # 生成段落用from reportlab.platypus.doctemplate import PageTemplate, BaseDocTemplate    # 用于生成页面模版,文档模版from reportlab.platypus.tableofcontents import TableOfContents      # 用于生成目录from reportlab.platypus.frames import Frame             # 生成页面模版是定义页面内的框架framefrom reportlab.lib.units import cm, inch                # 尺度单位# 注册中文字体from reportlab.pdfbase.ttfonts import TTFontfrom reportlab.pdfbase import pdfmetricspdfmetrics.registerFont(TTFont('lively', '/Library/Fonts/Chinese/ChaoZiSheZengYuBoShouShuJian-2.ttf'))pdfmetrics.registerFont(TTFont('apple', '/Library/Fonts/Chinese/XiaoHuYao-2.ttf'))# 定义标题、普通段落和代码的段落格式h1 = PS(name = 'Heading1', fontSize = 16, leading = 24, fontName = 'lively', spaceAfter = 15)h2 = PS(name = 'Heading2', fontSize = 14, leading = 20, leftIndent = 10, fontName = 'lively', spaceBefore = 10, spaceAfter = 10)h3 = PS(name = 'Heading3', fontSize = 12, leading = 16, leftIndent = 20, fontName = 'lively', spaceBefore = 10, spaceAfter = 10)normalText = PS(name = 'normal', fontSize = 12, leading = 14, firstLineIndent = 25, fontName = 'apple')code = PS(name = 'code', fontSize = 10, leading = 14, leftIndent = 35,fontName = 'apple')class MyDocTemplate(BaseDocTemplate):   # 是BaseDocTemplate的子类    def __init__(self, filename, **kw):        BaseDocTemplate.__init__(self, filename, **kw)        template = PageTemplate('normal', [Frame(2.5*cm, 2.5*cm, 15*cm, 25*cm, id='F1')], onPageEnd=self.footer)        # 定义页面模版,页脚可有可无        self.addPageTemplates(template)     # 加入页面模版    # 打开word取出文字内容,生成段落flowable放进story    def feedContent(self, filename, story):        from docx import Document           # 帮忙处理word文档        docWord = Document(filename)                # 打开word文档,生成word文档对象        h1Num = 0; h2Num = 0; h3Num = 0             # 因为要给标题加序号,三级序号,所以用变量记录所在层级的序号        for para in docWord.paragraphs:             # 遍历word文档的各个段落            docStyle = para.style.name                  # 取出word文档中的段落格式            if docStyle == 'Heading 1':                 # 如果是第一级标题,先加上序号再填进story                h1Num += 1                                  # 标记第一级标题的序号增1                seq = str(h1Num) + '、 '                    # 第一级标题的格式为1、                story.append(Paragraph(seq + para.text, h1))    # 生成段落followable加入story            elif docStyle == 'Heading 2':   # 第二级标题                h2Num += 1                                  # 标记第二级标题的序号增1                seq = str(h1Num) + '.' + str(h2Num) + ' '                   # 第二级标题格式1.1                story.append(Paragraph(seq + para.text, h2))            elif docStyle == 'Heading 3':   # 第三级标题                h3Num += 1                                  # 标记第三级标题的序号增1                seq = str(h1Num) + '.' + str(h2Num) + '.' + str(h3Num) + ' '                # 第三级标题的序号1.1.1                story.append(Paragraph(seq + para.text, h3))            elif docStyle == 'Code':                    # 普通段落和代码直接填进story,对代码的处理效果不理想                story.append(Paragraph(para.text, code))            else:                story.append(Paragraph(para.text, normalText))    # 生成一个flowable后判断是否为标题,是标题填进目录,二三级目录生成书签链接    def afterFlowable(self, flowable):  # 注册目录的条目        if flowable.__class__.__name__ == 'Paragraph':            text = flowable.getPlainText()      # 取出文字            style = flowable.style.name         # 取出段落格式            if style == 'Heading1':             # 第一级标题                self.notify('TOCEntry', (0, text, self.page))            if style == 'Heading2':             # 第二级标题                key = 'h2-{}'.format(self.seq.nextf('heading2'))    # 生成书签名                self.canv.bookmarkPage(key)     # 生成书签页                self.notify('TOCEntry', (1, text, self.page, key))                # 'TOCEntry':通知类型;(1, text, self.page, key):                # (目录层级、文本内容、当前页数、可选的书签名)            if style == 'Heading3':             # 第三级标题                key = 'h3-{}'.format(self.seq.nextf('heading3'))                self.canv.bookmarkPage(key)                self.notify('TOCEntry', (2, text, self.page, key))    # 页脚给出第几页    def footer(self, myCanvas, myDoc):        myCanvas.setFont('lively',10)           # 设置字体        myCanvas.drawRightString(7.6*inch,.5*inch, "{}".format(self.page))          # 画页脚toc = TableOfContents()                         # 生成目录对象toc.levelStyles = [h1, h2, h3]                  # 定义目录的格式,三层,每层的格式用段落格式定义story = []                                      # 列表story存放生成的各个flowablestory.append(toc)                               # 将目录对象填进story,此时目录只是架子,内容还没填进去story.append(PageBreak())                       # 分页符docPDF = MyDocTemplate('mintoc.pdf')            # 生成PDF文档对象docPDF.feedContent('excerpt.docx', story)       # 打开word文档,取出内容生成flowable放进story中docPDF.multiBuild(story)# 这个文档的生成要过两遍,第一遍加了个目录的空架子,# 文档内容生成之后才能把目录内容填进去,所以用multiBuild()而不是build()

3c71dc21965b001a1b1232c88ab31059.png

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值