【问题标题】:How to add bold and normal text in one line using drawString method in reportlab (python)如何在reportlab(python)中使用drawString方法在一行中添加粗体和普通文本
【发布时间】:2015-02-28 04:44:54
【问题描述】:

我是 reportlab lib 的新手,我正在学习它同时从事大学项目。 我在wxpython 中创建了一个桌面应用程序,它可以将数据保存为 PDF。

我想在我的 pdf 中添加 2 行。其中行以名为名称的用户输入开始,然后是一些单词,再次在第二行是一些单词,用户名,然后是一些单词......

我尝试使用一些 Paragraphcanvas 方法和类,但无法获得所需的输出。

期望的输出:

Alex 正在从事大学项目。

reportlab 是非常好的库,Alex 喜欢它。

我的代码:

import os
import reportlab
from reportlab.pdfgen import canvas
from reportlab.lib.pagesizes import A4
from reportlab.pdfbase import pdfmetrics
from reportlab.pdfbase.pdfmetrics import registerFontFamily
from reportlab.pdfbase.ttfonts import TTFont

# Registered font family
pdfmetrics.registerFont(TTFont('Vera', 'Vera.ttf'))
pdfmetrics.registerFont(TTFont('VeraBd', 'VeraBd.ttf'))
pdfmetrics.registerFont(TTFont('VeraIt', 'VeraIt.ttf'))
pdfmetrics.registerFont(TTFont('VeraBI', 'VeraBI.ttf'))
# Registered fontfamily
registerFontFamily('Vera',normal='Vera',bold='VeraBd',italic='VeraIt',boldItalic='VeraBI')

# Output pdf file name.
can = canvas.Canvas("Bold_Trail.pdf", pagesize=A4)

# Setfont for whole pdf.
can.setFont('Vera', 12)

# student name variable.
student_name ="Alex"

# Content.
line1 = " is working on college project."
line2 = "Reportlab is very good lib, "
line3 = " liked it.<br>"

# Joining whole content together.
content = "<strong>" + student_name + "</strong>" + line1
content2 = line2 + "<strong>"+student_name + "</strong>" + line3

# drawString location calculation.
x = 0; y = 8.5 * 72

# First string.
can.drawString(x,y, content)

y = y - 72

# Second String.
can.drawString(x,y, content2)

# Create PDF.
can.save()

除了使用 XML 方法 &lt;strong&gt;&lt;b&gt; 之外,还有其他方法在上述程序中不起作用吗?

单词应该保持在一行。

【问题讨论】:

    标签: python canvas reportlab richtext


    【解决方案1】:

    我找到了一种使用 XML 标记格式化段落文本的方法。首先,您需要注册字体系列,然后它应该可以工作。下面我以下载一组.ttf文件为例进行注册,之后XML标签就正常工作了。

    from reportlab.pdfbase import pdfmetrics
    from reportlab.pdfbase.ttfonts import TTFont
    from reportlab.pdfbase.pdfmetrics import registerFontFamily
    
    pdfmetrics.registerFont(TTFont('OpenSansR', 'OpenSans-Regular.ttf'))
    pdfmetrics.registerFont(TTFont('OpenSansL', 'OpenSans-Light.ttf'))
    pdfmetrics.registerFont(TTFont('OpenSansB', 'OpenSans-Bold.ttf'))
    registerFontFamily('OpenSans', normal='OpenSansR', bold='OpenSansB', italic='OpenSansL', boldItalic='OpenSansB')
    

    【讨论】:

      【解决方案2】:

      您可以使用canvas 对象的setFont 方法,在需要时将字体设置为Bold,否则设置为Normal

      * 更新 *

      为了计算x 的正确值,您可以使用stringWidth 方法,根据其内容、字体名称和字体大小计算字符串的长度。您必须从reportlab.pdfbase.pdfmetrics 导入它:

      [...]
      from reportlab.pdfbase.pdfmetrics import stringWidth
      [...]
      
      # student name variable.
      student_name = 'Alex'
      
      # Content.
      line1 = " is working on college project."
      line2 = "Reportlab is very good lib, "
      line3 = " liked it"
      
      # drawString location calculation.
      x = 0
      y = 8.5 * 72
      
      # First string.
      can.setFont('Helvetica-Bold', 8)
      can.drawString(x, y, student_name)
      can.setFont('Helvetica', 8)
      textWidth = stringWidth(student_name, 'Helvetica-Bold', 8) 
      x += textWidth + 1
      can.drawString(x, y, line1)
      
      y = y - 72
      
      # Second String.
      x = 0
      can.setFont('Helvetica', 8)
      can.drawString(x, y, line2)
      textWidth = stringWidth(line2, 'Helvetica', 8) 
      x += textWidth + 1
      can.setFont('Helvetica-Bold', 8)
      can.drawString(x, y, student_name)
      textWidth = stringWidth(student_name, 'Helvetica-Bold', 8) 
      x += textWidth + 1
      can.setFont('Helvetica', 8)
      can.drawString(x, y, line3)
      
      # Create PDF.
      can.save()
      

      或者你可以看看ParagraphStyleParagraphfrom reportlab.lib.styles import ParagraphStylefrom reportlab.platypus import Paragraph),但我不确定你是否可以在同一个字符串中连接两种不同的样式。

      【讨论】:

      • 谢谢,成功了!我还将寻找建议的课程(段落)。
      • 不客气!是的,我很确定有一种方法可以使用ParagraphStyle 实现这一目标,它可能会更优雅......
      • 一个问题。为什么将学生姓名乘以 5 ?以及后来的 4.5 ?我不明白那个值是什么。
      • 这就是我所说的“x 的计算绝对可以改进”:我将这些值与“Alex”这个名字相匹配。请查看我的更新答案以获得更动态的解决方案。
      • 再次感谢您。现在我对这个概念很清楚了:)
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-04-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多