python reportlab 为 Listitem 提供格式

问题描述 投票:0回答:3

如何使用 python 将字符添加到编号的 reportlab PDF 中。示例:

  1. 第一个元素
  2. 这是第二个元素

其他:
a) 第一项
b) 第二个

如何添加“.”、“)”、“-”,我已经运行了:

Myitems.append(ListFlowable([  
    ListItem(Paragraph("text", styleLeft),  
    leftIndent=20)],   
    bulletType='a', leftIndent=20, start=1))
python pdf reportlab
3个回答
1
投票

我在任何地方都找不到这个记录。答案似乎隐藏在源代码中:reportlab.platypus.flowables._bulletFormat.

def _bulletFormat(value,type='1',format=None):
    if type=='bullet':
        s = _bulletNames.get(value,value)
    else:
        s = _type2formatter[type](int(value))

    if format:
        if isinstance(format,strTypes):
            s = format % s
        elif isinstance(format, collections.Callable):
            s = format(s)
        else:
            raise ValueError('unexpected BulletDrawer format %r' % format)
    return s

从中我们可以看出,我们可以向

bulletFormat
提供
ListFlowable
参数,该参数将应用于有序列表中的数字/字母的值。我们还可以计算出该参数可以是一个 Callable(即函数),它采用单个字符串参数并返回单个字符串值,或者我们可以提供一个用于 % 格式的字符串。我不喜欢后者,但在大多数情况下它可能会表现得很好。

我给您留下了以下脚本,它演示了您需要什么。我添加了这在我的环境中为我产生的结果的屏幕截图。您可能需要使用字体和样式等。

#!/usr/bin/env python3

import unicodedata
from pathlib import Path
from reportlab.platypus import SimpleDocTemplate, Paragraph, ListFlowable, Spacer
from reportlab.lib.styles import getSampleStyleSheet

output = Path.cwd() / Path(__file__).with_suffix(".pdf").name
doc = SimpleDocTemplate(str(output))

styles = getSampleStyleSheet()
normal = styles["Normal"]
body = styles["BodyText"]
h2 = styles["Heading2"]

def second_tetration(value: str):
    try:
        n = int(value)
        try:
            # Only works up to 9 (i.e. single digits)
            exponent = unicodedata.lookup(unicodedata.name(str(n)).replace("DIGIT", "SUPERSCRIPT"))
        except KeyError:
            exponent = None

        if exponent is None:
            return f"{n}^{n} = {n ** n}"
        else:
            return f"{n}{exponent} = {n ** n}"
    except ValueError:
        return value

story = [
    Paragraph("Plain", h2),
    ListFlowable(
        [Paragraph(s, normal) for s in ["One", "Two", "Three"]]
    ),

    Paragraph("With a Full Stop (Period)", h2),
    ListFlowable(
        [Paragraph(s, normal) for s in [
            "First element",
            "This is the second element",
        ]],
        bulletFormat="%s.",  # ←
    ),

    Paragraph("With a Right Parenthesis", h2),
    ListFlowable(
        [Paragraph(s, normal) for s in [
            "First item",
            "Second one",
        ]],
        bulletType="a",
        bulletFormat="%s)",  # ←
    ),
    Paragraph(
        "Note that we must also change the bulletType here to get a sequence using "
        "letters instead of numbers.",
        body,
    ),

    Paragraph("Second Tetration", h2),
    ListFlowable(
        [Paragraph(s, normal) for s in [
            "One to the power one",
            "Two to the power two",
            "Three to the power three",
        ]],
        leftIndent=48,
        bulletFormat=second_tetration,  # ←
    ),
    Paragraph(
        """
        Here the bullet is changed to its second tetration; which is to say 'n to
        the power n'. Unlikely you want this, but a demonstration that your imagination
        is the limit here. Note that to really make use of this functionality you
        will have to play about with fonts and styles to ensure whatever characters
        you're returning have glyphs that can be rendered. Hint: grab a copy of
        <link href="https://www.gnu.org/software/freefont/">GNU FreeFont</link>.
        """,
        body,
    ),

]
doc.build(story)

代码作为要点


0
投票

如果文本来自chatgpt或vertax-ai等LLM,您可以使用

markdown2
库和
pdfkit
将文本转换为html,然后将html转换为pdf。这是代码:

import markdown2
import pdfkit
output_file = open("file.pdf", 'a+')
html_content = markdown2.markdown(report_text)
options = {
    'page-size': 'A4',
    'margin-top': '0.75in',
    'margin-right': '0.75in',
    'margin-bottom': '0.75in',
    'margin-left': '0.75in',
}
# print(html_content)
# Convert HTML to PDF
pdfkit.from_string(html_content, output_file, options=options)

记得在您的系统上安装

wkhtmltopdf
二进制文件。


-1
投票
from reportlab.lib.enums import TA_JUSTIFY
from reportlab.lib.pagesizes import letter
from reportlab.platypus import SimpleDocTemplate, Paragraph
from reportlab.lib.styles import getSampleStyleSheet

doc = SimpleDocTemplate("form_letter.pdf",pagesize=letter,
                        rightMargin=72,leftMargin=72,
                        topMargin=72,bottomMargin=18)

styles = getSampleStyleSheet()

Story=[]

ptext = '''
<seq>) </seq>Some Text<br/>
<seq>) </seq>Some more test Text
'''
Story.append(Paragraph(ptext, styles["Bullet"]))

doc.build(Story)
© www.soinside.com 2019 - 2024. All rights reserved.