ReportLab段落格式化换行符

时间:2018-01-04 19:41:40

标签: python python-3.x python-2.7 pdf reportlab

我是ReportLab的新手,我正在创建一个简单的文档,员工将文本输入到网站上的文本区域,将其保存到数据库中,然后从数据库中提取以通过ReportLab创建PDF。我看到的问题是,如果用户输入的文本包含2个段落之间的换行符,则在创建PDF时不会遵循该换行符。

当我通过相同的Python脚本将文本内容直接打印到屏幕上时,一切都是正确的:

  

与流行的看法相反,Lorem Ipsum不仅仅是随机文本。它   源于公元前45年的一段古典拉丁文学作品   它已有2000多年的历史。理查德麦克林托克,拉丁教授   在弗吉尼亚州的汉普登 - 悉尼学院,查找了一个比较模糊的人   拉丁语单词,consectetur,来自Lorem Ipsum段落,然后去   通过古典文学中的词汇,发现了   无可置疑的来源。 Lorem Ipsum来自1.10.32和   由西塞罗撰写的“de Finibus Bonorum et Malorum”(极端的善与恶)的1.10.33,写于公元前45年。这本书是一篇论文   道德理论,在文艺复兴时期非常流行。第一行   Lorem Ipsum,“Lorem ipsum dolor sit amet ..”,来自一条线路   第1.10.32节。

     

与流行的看法相反,Lorem Ipsum不仅仅是随机文本。它   源于公元前45年的一段古典拉丁文学作品   它已有2000多年的历史。理查德麦克林托克,拉丁教授   在弗吉尼亚州的汉普登 - 悉尼学院,查找了一个比较模糊的人   拉丁语单词,consectetur,来自Lorem Ipsum段落,然后去   通过古典文学中的词汇,发现了   无可置疑的来源。 Lorem Ipsum来自1.10.32和   由西塞罗撰写的“de Finibus Bonorum et Malorum”(极端的善与恶)的1.10.33,写于公元前45年。这本书是一篇论文   道德理论,在文艺复兴时期非常流行。第一行   Lorem Ipsum,“Lorem ipsum dolor sit amet ..”,来自一条线路   第1.10.32节。

然而,在PDF中它看起来像:

  

与流行的看法相反,Lorem Ipsum不仅仅是随机文本。它   源于公元前45年的一段古典拉丁文学作品   它已有2000多年的历史。理查德麦克林托克,拉丁教授   在弗吉尼亚州的汉普登 - 悉尼学院,查找了一个比较模糊的人   拉丁语单词,consectetur,来自Lorem Ipsum段落,然后去   通过古典文学中的词汇,发现了   无可置疑的来源。 Lorem Ipsum来自1.10.32和   由西塞罗撰写的“de Finibus Bonorum et Malorum”(极端的善与恶)的1.10.33,写于公元前45年。这本书是一篇论文   道德理论,在文艺复兴时期非常流行。第一行   Lorem Ipsum,“Lorem ipsum dolor sit amet ..”,来自一条线路   第1.10.32节。对于流行的看法,Lorem Ipsum并不简单   随机文字。它源于一段古典拉丁文学   从公元前45年开始,它已有2000多年的历史。 Richard McClintock,拉丁文   弗吉尼亚州汉普顿 - 悉尼学院的教授抬头看了一眼   来自Lorem Ipsum段落的更加模糊的拉丁语单词,consectetur,和   经历古典文学中的词汇,   发现了无可置疑的来源。 Lorem Ipsum来自各个部分   西塞罗的“de Finibus Bonorum et Malorum”(极端的善与恶)的1.10.32和1.10.33,写于公元前45年。这本书是一篇论文   伦理学理论,在文艺复兴时期非常流行。该   Lorem Ipsum的第一行,“Lorem ipsum dolor sit amet ..”,来自   第1.10.32节中的一行。

起初我认为这是数据库中的文本格式问题,但在我能够在PDF创建之前正确打印出内容后,我知道这不是问题。

我是否错过了段落的简单样式输入?我有点失落,因为我还不知道ReportLab的所有细节。

以下是脚本中的ReportLab代码段。 employeeQuestion1是在创建PDF之前以正确的格式打印出来的。

def stylesheet():
    styles= {
        'default': ParagraphStyle(
            'default',
            fontName='SourceSansPro-Bold',
            fontSize=10,
            leading=12,
            leftIndent=0,
            rightIndent=0,
            firstLineIndent=0,
            alignment=TA_LEFT,
            spaceBefore=0,
            spaceAfter=0,
            bulletFontName='Times-Roman',
            bulletFontSize=10,
            bulletIndent=0,
            textColor= black,
            backColor=None,
            wordWrap=None,
            borderWidth= 0,
            borderPadding= 0,
            borderColor= None,
            borderRadius= None,
            allowWidows= 1,
            allowOrphans= 0,
            textTransform=None,
            endDots=None,         
            splitLongWords=1,
        ),
    }
    styles['employee_response'] = ParagraphStyle(
        'employee_response',
        parent=styles['default'],
        fontName='SourceSansPro-Regular',
        fontSize=10,
        spaceAfter=10,
        leftIndent=20
    )
    return styles

def build_flowables(stylesheet):
    return [
        Paragraph('{0}'.format(employeeQuestion1), stylesheet['employee_response']),
    ]

def build_pdf(filename, flowables):
    doc = SimpleDocTemplate(filename, 
        rightMargin=inch/2,
        leftMargin=inch/2,
        topMargin=inch/2,
        bottomMargin=inch/2,
        pagesize=letter,
    )

    doc.addPageTemplates(
        [
            PageTemplate(
                frames=[
                    Frame(
                        doc.leftMargin,
                        doc.bottomMargin,
                        doc.width,
                        doc.height,
                        id=None
                    ),
                ]
            ),
        ]
    )
    doc.build(flowables)
    build_pdf('/etc/review_app/reviews/{0}.pdf'.format(pdfFileName), build_flowables(stylesheet()))

感谢您的帮助!

1 个答案:

答案 0 :(得分:0)

我通过将新行转换为public void Receive(string hostName, string queueName, string type, IEnumerable<string> routingKeys, string exchange) { //Initializes the MediatorHandler`s factory InitializeFactory(); var mediatorHandler = _mediatorHandlers[type]; //RabbitMQ configuration var userName = _configuration["Messaging:UserName"]; var password = _configuration["Messaging:Password"]; var numberOfConsumers = int.Parse(_configuration["Messaging:NumerOfConsumers"]); var channels = int.Parse(_configuration["Messaging:Channels"]); var factory = new ConnectionFactory() { HostName = hostName, UserName = userName, Password = password }; var connection = factory.CreateConnection(); for (int i = 1; i <= channels; i++) { var channel = connection.CreateModel(); var prefetchQuantity = _configuration["Messaging:PrefetchQuantity"]; channel.BasicQos(0, Convert.ToUInt16(prefetchQuantity), false); //Declaring the exchange channel.ExchangeDeclare(exchange, ExchangeType.Direct); //Declaring the queue and creating its routing key bindings channel.QueueDeclare(queueName, true, false, false, null); foreach (var routingKey in routingKeys) { channel.QueueBind(queueName, exchange, routingKey); } for (int j = 1; j <= numberOfConsumers; j++) { var consumer = new EventingBasicConsumer(channel); consumer.Received += (model, e) => { try { mediatorHandler.Handle(model, e, _mediator); channel.BasicAck(e.DeliveryTag, false); } catch (Exception exception) { Console.WriteLine(exception); channel.BasicNack(e.DeliveryTag, false, true); } }; channel.BasicConsume(queue: queueName, autoAck: false, consumer: consumer); } } } 标记解决了这个问题:

<br />

希望这可以帮助有同样问题的人