鸭嘴兽如何“猜测”大胆和斜体的风格?

时间:2017-07-06 20:08:02

标签: python reportlab platypus

这是我的代码。我的第一个函数基于/Lib/site-packages/reportlab/lib/styles.py源代码,用于创建style的数组:

def create_styles(p_tuples):
    retour = StyleSheet1()
    parent = None
    for p_name, font_name, font in p_tuples:
        # (!) change path if Linux:
        ttf_file = "C:/Windows/Fonts/{}.ttf".format(font)
        pdfmetrics.registerFont(TTFont(font_name, ttf_file))
        if parent is None:
            p = ParagraphStyle(name=p_name,
                               fontName=font_name,
                               fontSize=10,
                               leading=12)
            retour.add(p)
            parent = p
        else:
            retour.add(ParagraphStyle(name=p_name,
                                      parent=parent,
                                      fontName=font_name,
                                      fontSize=10,
                                      leading=12))
    return retour

然后我用我安装的字体构建我自己的数组:

def render_to_response(self, context, **response_kwargs):
    # this is a response for Django, but the question is about styles
    response = HttpResponse(content_type='application/pdf; charset=utf-8')
    # ! Hint : no filename -> the browser extracts it from the URL!
    #   -> create URLs like http://pdfreportlab.com/extract/myfilename.pdf
    #   this is the way to go to have 100% working UTF-8 filenames!
    response['Content-Disposition'] = 'attachment; filename=""'

    my_styles = self.create_styles([
        ('ms-regular', 'montserrat-regular',
         'Montserrat-Regular'),
        ('ms-black', 'montserrat-black',
         'Montserrat-Black'),
        ('ms-black-italic', 'montserrat-black-italic',
         'Montserrat-BlackItalic'),
        ('ms-bold', 'montserrat-bold',
         'Montserrat-Bold'),
        ('ms-bold-italic', 'montserrat-bold-italic',
         'Montserrat-BoldItalic'),
    ])
    doc = SimpleDocTemplate(response)
    elements = []
    c = canvas.Canvas(response, pagesize=A4, )
    for idx in my_styles.byName:
        p = Paragraph("Hello World <i>italic</i> <b>bold</b>",
                      style=my_styles[idx])
        width, height = p.wrapOn(c, A4[0], A4[1])
        elements.append(p)
    doc.build(elements)
    return response

除了<i></i><b></b>标签被忽略的(非常令人讨厌的)事实之外,一切都在发挥作用!它只使用样式中的当前字体。

你怎么能修改我的代码,以便它考虑到标签,我最终得到文本本身的标签样式?

1 个答案:

答案 0 :(得分:1)

如果您希望Platypus自动选择字体,则需要注册字体系列 - 您为每种字体变体创建了不同的样式,因此<i><b>标签当然无效 - 它不知道要使用哪些字体,因为传递的样式引用单个字体。

以下是使用字体系列构建样式的方法:

from reportlab.lib.styles import ParagraphStyle
from reportlab.pdfbase.pdfmetrics import registerFont, registerFontFamily
from reportlab.pdfbase.ttfonts import TTFont


def create_paragraph_style(name, font_name, **kwargs):
    ttf_path = "C:/Windows/Fonts/{}.ttf"
    family_args = {}  # store arguments for the font family creation
    for font_type in ("normal", "bold", "italic", "boldItalic"):  # recognized font variants
        if font_type in kwargs:  # if this type was passed...
            font_variant = "{}-{}".format(font_name, font_type)  # create font variant name
            registerFont(TTFont(font_variant, ttf_path.format(kwargs[font_type])))
            family_args[font_type] = font_variant  # add it to font family arguments
    registerFontFamily(font_name, **family_args)  # register a font family
    return ParagraphStyle(name=name, fontName=font_name, fontSize=10, leading=12)

然后您可以创建段落样式:

pstyle = create_paragraph_style("ms", "montserrat",
                                normal="Montserrat-Regular",
                                bold="Montserrat-Bold",
                                boldItalic="Montserrat-BoldItalic")

当然,假设您的字体目录中包含这些名称的TTF文件。

然后,您可以将其添加到样式表中(特别是如果您想要父继承 - 请确保将其添加为要转发到ParagraphStyle创建的参数)或直接将其用作:

p = Paragraph("Hello World <i>italic</i> <b>bold</b> <b><i>boldItalic</i></b>", style=pstyle)

(独立的斜体不会受到影响,因为我们没有在家庭中定义它,所以)。