wkhtmltopdf повторяющееся фоновое изображение на всех страницах

Я изо всех сил пытаюсь сделать повторяющийся фон для сгенерированного PDF.

У меня есть сертификат, который автоматически генерируется, и дизайн сертификата имеет рамку, которая должна повторяться на всех страницах...

Я старался

.main_container{
   background: url({{ resourceDir ~ 'img/certificate_margin.jpg' }}) 0 0;
   padding-top:15px;
   z-index: 99;
   background-size: cover;
   width:658px;
   height:975px;
}

но после отображения первой страницы я получаю только содержимое и белую страницу. Кому-нибудь удалось решить эту проблему как-нибудь? Или это вообще возможно сделать?

мой конфигурационный файл:

knp_snappy:
    pdf:
        enabled:    true
        binary:     "%wkhtmltopdf_binary_path%"
        options:
            page-size: A4
            dpi: 150
            image-dpi: 150
            encoding: utf-8

и код генерации:

$unsignedPdfContent = $this->snappy->getOutputFromHtml(
    $this->templating->render(
        $this->getTemplate(), [
            'certificate' => $this->certificate,
            'resourceDir' => __DIR__.'/../Resources/public/'
        ]
    )
);

5 ответов

Решение

Мне удалось "решить" проблему.

Основываясь на этом вопросе, почему wkhtmltopdf разрыва страницы не имеет никакого эффекта? Я фактически заставил страницу вручную разрываться после фиксированной точки и создать новую страницу с тем же фоном.

ОК, это "хакерский" способ, но он сделал свою работу...

теперь мой код выглядит так

CSS

.main_container{
    background: url({{ resourceDir ~ 'img/certificate_margin.jpg' }}) 0 0;
    padding-top:15px;
    padding-left:5px;
    z-index: 99;
    background-size: cover;
    width:652px;
    height:975px;
    position:relative;
 }
.break{
        display: block;
        clear: both;
        page-break-after: always;
}

И веточка

...
<body>
<div class="main_container break" style='position:relative'>

    first page content 

    {% block body %}

    {% endblock %}

    {% include 'BlablaBundle:Pdf:_partial_certificate/_footer_contact.html.twig' with {'page': 'Seite 1/2'} %}
</div>

<div class="main_container" style='position:relative'>

    second page content

        {% include 'BlablaBundle:Pdf:_partial_certificate/_footer_contact.html.twig' with {'page': 'Seite 2/2'} %}
</div>
</body>
...

Мне нужно было что-то, чтобы пометить каждую страницу PDF-файла, созданного wkhtmltopdf как черновик, поэтому я попробовал предложение @herr-nentu, но оно не сработало, и я внес в него некоторые корректировки.

Просто добавьте тег стиля в раздел заголовка вашего файла TWIG / HTML со следующим CSS:

      <style>
/* Only tested background image with an absolute URL */
html .watermark {
 background: url('https://via.placeholder.com/700x963?text=DRAFT') 0 0 !important;
 padding-top: 0 !important;
 padding-left: 0 !important;
 z-index: 99 !important;
 background-size: cover !important;
 width: 700px !important;
 height: 963px !important;
 position: relative !important;
}
</style>

Затем добавьте .watermark в тег body вашего файла TWIG / HTML:

      ...
<body class="watermark">
 <!-- HTML contents to display as PDF -->
</body>

Примечание для изображения: я использовал прозрачное фоновое изображение шириной 700 пикселей и высотой 963 пикселей (немного меньше размера A4) с текстом DRAFT, расположенным посередине.

Надеюсь, это поможет ...:D

Я решаю это, наконец. Просто добавьте тег стиля в раздел заголовка вашего файла TWIG/HTML со следующим CSS:

      <style>
    body {
      width: 100%;
      height: 0;
      background: url("https://www.api2pdf.com/wp-content/uploads/2018/09/draft.png") repeat-y center;
      background-size: 20%;
    }
</style>

главное не использовать background-attachment: fixed;

То, что упомянул Фест, верно до определенного момента.

По какой-то причине это не всегда работает с моей реализацией. Итак, основываясь на другом посте и моих собственных рекомендациях, вам нужно всего лишь добавить следующий код в свой html-файл:

      body {
    background: url("https://via.placeholder.com/700x963?text=DRAFT");
    background-position: center;
    background-repeat: repeat-y;
    background-size: 100%;
    background-attachment: fixed;
}

К этому времени фон должен повторяться, но не в том месте. Решение состоит в том, чтобы исправить размер изображения, так как 700x963 не обрежет его, и это зависит от вашей конфигурации pdf.

Давайте вспомним, что вы можете сообщить wkhtml две важные вещи: размер страницы и поля (верхнее, нижнее, левое, правое). В зависимости от выбранного вами размера страницы, перейдите по следующей ссылке , чтобы получить точное значение в дюймах (например, «Letter» — 8,5x11 дюймов). Теперь, в зависимости от полей, которые вы установили для wkhtml, вам придется вычесть эти поля из размеров страницы (например, если у нас все еще есть «Письмо» в качестве размера страницы, и мы установили 1 дюйм для всех полей, результат должен быть 6,5х9 дюймов). Ваше изображение должно быть именно этого размера.

      // The previous paragraph can be interpreted as:

// Letter page-size
const page_size = {
  width: "8.5in", 
  height: "11in",
}

const image_width = to_px(page_size.width) - to_px(margin_left) - to_px(margin_right)
const image_height = to_px(page_size.height) - to_px(margin_top) - to_px(margin_bottom)
const url = "https://via.placeholder.com/" + image_width + "x" + image_height + "?text=DRAFT"

Пара рекомендаций:

  • Используйте эти размеры в дюймах, а не в пикселях, для wkhtml и вашего css. (Вот как я это делаю, это может работать с пикселями, но я не уверен)
  • Если одно из полей0, не забудьте указать единицу измерения (например,0in), иначе wkhtml выйдет из строя.
  • Передайте следующую конфигурацию в wkhtml:
    • --background
    • --encoding UTF-8поэтому он может печатать символы ($)
    • --enable-smart-shrinkingчтобы не путаться в размерах
  • Изображение не должно иметь прозрачности. wkhtml может испортить изображение, имеющее прозрачность, в любой момент и на любой странице (у меня были большие документы, где фоновое изображение отрисовывалось правильно только на первых 6 страницах). Я до сих пор не знаю, ограничено ли это только фоновыми изображениями.
  • Используйте абсолютные URL-адреса для изображений. wkhtml может не сообщать об ошибке, но вы не увидите свое изображение.

Подумав об этой проблеме, я рекомендую просто делегировать что-то вроде pdftk и используйте ту же логику для водяных знаков для повторяющегося фонового изображения.

https://www.pdflabs.com/docs/pdftk-man-page/

Другие вопросы по тегам