Kozea / WeasyPrint

The awesome document factory
https://weasyprint.org
BSD 3-Clause "New" or "Revised" License
7.11k stars 678 forks source link

Background image flickers #2165

Closed anuj9196 closed 3 months ago

anuj9196 commented 4 months ago

Using the Statistical Report template with the exact CSS

@page {
    size: A4;
    margin: 1cm;

    @top-left {
        background: #fbc847;
        content: counter(page);
        height: 1cm;
        text-align: center;
        width: 1cm;
    }

    @top-center {
        background: #fbc847;
        content: '';
        display: block;
        height: .05cm;
        opacity: .5;
        width: 100%ds;
    }
    @top-right {
        {#content: string(heading);#}
        content: element(header);
        font-size: 9pt;
        height: 1cm;
        vertical-align: middle;
        width: 100%;
    }
}

@page :blank {
    @top-left { background: none; content: '' }
    @top-center { content: none }
    @top-right { content: none }
}
@page :first {
    background: url({{ cover_url }}) no-repeat center;
    background-size: cover;
    margin: 0;
}

But the background image flickers once and then is hides behind the white background

https://github.com/Kozea/WeasyPrint/assets/6560085/8dcc8f6f-d2eb-4384-bd9d-1e619af8786e

liZe commented 4 months ago

Hi!

Could you please share the PDF you get?

anuj9196 commented 4 months ago

@liZe Here is the pdf

15910e04-8901-4515-bbe8-b546356f0387_responses (2).pdf

liZe commented 4 months ago

Here’s my sample:

<html>
  <head>
    <meta charset="utf-8">
    <link href="report.css" rel="stylesheet">
    <title>Report</title>
    <meta name="description" content="Report example">
    <style>
      @page {
    size: A4;
    margin: 1cm;
    @top-left {
        background: #fbc847;
        content: counter(page);
        height: 1cm;
        text-align: center;
        width: 1cm;
    }
    @top-center {
        background: #fbc847;
        content: '';
        display: block;
        height: .05cm;
        opacity: .5;
        width: 100%;
    }
    @top-right {
        content: element(header);
        font-size: 9pt;
        height: 1cm;
        vertical-align: middle;
        width: 100%;
    }
}

@page :blank {
    @top-left { background: none; content: '' }
    @top-center { content: none }
    @top-right { content: none }
}
@page :first {
    background: url(report-cover.jpg) no-repeat center;
    background-size: cover;
    margin: 0;
}
    </style>
  </head>

  <body>
    <article id="cover">
      <h1>Report example</h1>
      <address>
        WeasyPrint
        26 rue Emile Decorps
        69100 Villeurbanne France
      </address>
      <address>
        contact@courtbouillon.org
        https://courtbouillon.org
      </address>
    </article>

    <article id="columns">
      <h2 id="columns-title">Test</h2>
    </article>
  </body>
</html>

I have the background image correctly displayed in the PDF: report.pdf

Please provide the whole generated HTML (not a template) and CSS you use if you want me to reproduce your problem.

anuj9196 commented 4 months ago

I'm using Django for pdf rendering and here is the HTML and view files

template3.html

{% load static %}
<html>
  <head>
    <meta charset="utf-8">
    <title>Report</title>
      <link rel="stylesheet" href="{% static 'pdf_report/assets/css/report.css' %}">
    <meta name="description" content="Report example">
    <style>
        @page {  
            size: A4;  
            margin: 1cm;
            @top-left {  
                background: #fbc847;  
                content: counter(page);  
                height: 1cm;  
                text-align: center;  
                width: 1cm;  
            }
            @top-center {  
                background: #fbc847;  
                content: '';  
                display: block;  
                height: .05cm;  
                opacity: .5;  
                width: 100%;  
            }
            @top-right {  
                content: element(header);  
                font-size: 9pt;  
                height: 1cm;  
                vertical-align: middle;  
                width: 100%;  
            }  
        }
        @page :blank {  
            @top-left { background: none; content: '' }
            @top-center { content: none }
            @top-right { content: none }  
        }  
        @page :first {  
            background: url({{ cover_url }}) no-repeat center;  
            background-size: cover;  
            margin: 0;  
        }

        #cover {
            align-content: space-between;
            display: flex;
            flex-wrap: wrap;
            height: 297mm;
        }
        #cover address {
            background: #fbc847;
            flex: 1 50%;
            margin: 0 -2cm;
            padding: 1cm 0;
            white-space: pre-wrap;
        }
        #cover address:first-of-type {
          padding-left: 3cm;
        }
        #cover h1 {
          color: #fbc847;
          font-size: 38pt;
          margin: 5cm 2cm 0 2cm;
          page: no-chapter;
          width: 100%;
        }
    </style>
  </head>

  <body>
    <article id="cover">
      <h1>Report example</h1>
      <address>
        WeasyPrint
        26 rue Emile Decorps
        69100 Villeurbanne France
      </address>
      <address>
        contact@courtbouillon.org
        https://courtbouillon.org
      </address>
    </article>

    <article id="columns">
      <h2 id="columns-title">Test</h2>
    </article>
  </body>
</html>

app/views.py

from django.http import HttpResponse
from django.template.loader import get_template
from rest_framework.views import APIView

from weasyprint import HTML, CSS

class ReportRenderView(APIView):

    permission_classes = [AllowAny,]

    def get(self, request, *args, **kwargs):
        template_path = 'pdf_report/assessment/attempt/responses/template3.html'
        template = get_template(template_path)

        cover_url = request.build_absolute_uri(static('pdf_report/assets/img/report-cover.jpg'))

        log.info(f'cover url: {cover_url}')
        html = template.render({
            'cover_url': cover_url
        })

        pdf_file = HTML(string=html).write_pdf(
            optimize_images=True, jpeg_quality=60, dpi=150
        )
        file_name = "report_responses.pdf"

        response = HttpResponse(pdf_file, content_type='application/pdf')
        response['Content-Disposition'] = f'filename="{file_name}"'
        return response
anuj9196 commented 4 months ago

Checked the logs and here is the error message

/site-packages/weasyprint/images.py (line: 335):: Failed to load image at 'http://api.localhost:8000/static/pdf_report/assets/img/report-cover.jpg': URLError: <urlopen error [Errno -2] Name or service not known>
liZe commented 4 months ago

Failed to load image at…

Then you know why the image is not there 😄.

If you use Django, you really should use Django-WeasyPrint to fix all the problems related to static files.

anuj9196 commented 4 months ago

I know using this additional library might solve the issue (going to give it a try). But can you suggest some another way to solve this without using additional dependency?

liZe commented 4 months ago

But can you suggest some another way to solve this without using additional dependency?

It depends on why you get this problem:

liZe commented 3 months ago

Feel free to add a comment if there’s anything more we can do for you!