HTML Print format previews well, but PDF generation is apparently ignoring any CSS

Our Print format (see attached HTML) for Purchase Order gets previewed as expected, but the PDF button generates almost a plain text page:

Apparently the styling has been ignored for a big part of the document. Our site is hosted on erpnext.com, but apparently the support there is not the best one and they rejecting giving us any clue what the problem could be.

Has anyone an idea about it?

Thanks!

I assume you are trying to use flex. You will need to prefix your CSS as wkhtmltopdf does not support latest CSS.

Like this;

.flex {
    display: -webkit-box;
    display: -webkit-flex;
    display: -moz-box;
    display: -ms-flexbox;
    display: flex;
}

.inline-flex {
    display: -webkit-inline-box;
    display: -webkit-inline-flex;
    display: -moz-inline-box;
    display: -ms-inline-flexbox;
    display: inline-flex;
}

.flex-row {
    -webkit-box-orient: horizontal;
    -webkit-box-direction: normal;
    -webkit-flex-direction: row;
       -moz-box-orient: horizontal;
       -moz-box-direction: normal;
        -ms-flex-direction: row;
            flex-direction: row;
}

.flex-row-reverse {
    -webkit-box-orient: horizontal;
    -webkit-box-direction: reverse;
    -webkit-flex-direction: row-reverse;
       -moz-box-orient: horizontal;
       -moz-box-direction: reverse;
        -ms-flex-direction: row-reverse;
            flex-direction: row-reverse;
}

.flex-column {
    -webkit-box-orient: vertical;
    -webkit-box-direction: normal;
    -webkit-flex-direction: column;
       -moz-box-orient: vertical;
       -moz-box-direction: normal;
        -ms-flex-direction: column;
            flex-direction: column;
}

.flex-column-reverse {
    -webkit-box-orient: vertical;
    -webkit-box-direction: reverse;
    -webkit-flex-direction: column-reverse;
       -moz-box-orient: vertical;
       -moz-box-direction: reverse;
        -ms-flex-direction: column-reverse;
            flex-direction: column-reverse;
}

.flex-wrap {
    -webkit-flex-wrap: wrap;
        -ms-flex-wrap: wrap;
            flex-wrap: wrap;
}

.flex-wrap-reverse {
    -webkit-flex-wrap: wrap-reverse;
        -ms-flex-wrap: wrap-reverse;
            flex-wrap: wrap-reverse;
}

.flex-nowrap {
    -webkit-flex-wrap: nowrap;
        -ms-flex-wrap: nowrap;
            flex-wrap: nowrap;
}

.flex-justify-start {
    -webkit-box-pack: start;
    -webkit-justify-content: flex-start;
       -moz-box-pack: start;
        -ms-flex-pack: start;
            justify-content: flex-start;
}

.flex-justify-end {
    -webkit-box-pack: end;
    -webkit-justify-content: flex-end;
       -moz-box-pack: end;
        -ms-flex-pack: end;
            justify-content: flex-end;
}

.flex-justify-center {
    -webkit-box-pack: center;
    -webkit-justify-content: center;
       -moz-box-pack: center;
        -ms-flex-pack: center;
            justify-content: center;
}

.flex-justify-between {
    -webkit-box-pack: justify;
    -webkit-justify-content: space-between;
       -moz-box-pack: justify;
        -ms-flex-pack: justify;
            justify-content: space-between;
}

.flex-justify-around {
    -webkit-justify-content: space-around;
        -ms-flex-pack: distribute;
            justify-content: space-around;
}

.flex-justify-evenly {
    -webkit-box-pack: space-evenly;
    -webkit-justify-content: space-evenly;
       -moz-box-pack: space-evenly;
        -ms-flex-pack: space-evenly;
            justify-content: space-evenly;
}

.flex-align-start {
    -webkit-box-align: start;
    -webkit-align-items: flex-start;
       -moz-box-align: start;
        -ms-flex-align: start;
            align-items: flex-start;
}

.flex-align-end {
    -webkit-box-align: end;
    -webkit-align-items: flex-end;
       -moz-box-align: end;
        -ms-flex-align: end;
            align-items: flex-end;
}

.flex-align-center {
    -webkit-box-align: center;
    -webkit-align-items: center;
       -moz-box-align: center;
        -ms-flex-align: center;
            align-items: center;
}

.flex-align-baseline {
    -webkit-box-align: baseline;
    -webkit-align-items: baseline;
       -moz-box-align: baseline;
        -ms-flex-align: baseline;
            align-items: baseline;
}

.flex-align-stretch {
    -webkit-box-align: stretch;
    -webkit-align-items: stretch;
       -moz-box-align: stretch;
        -ms-flex-align: stretch;
            align-items: stretch;
}

.flex-content-start {
    -webkit-align-content: flex-start;
        -ms-flex-line-pack: start;
            align-content: flex-start;
}

.flex-content-end {
    -webkit-align-content: flex-end;
        -ms-flex-line-pack: end;
            align-content: flex-end;
}

.flex-content-center {
    -webkit-align-content: center;
        -ms-flex-line-pack: center;
            align-content: center;
}

.flex-content-between {
    -webkit-align-content: space-between;
        -ms-flex-line-pack: justify;
            align-content: space-between;
}

.flex-content-around {
    -webkit-align-content: space-around;
        -ms-flex-line-pack: distribute;
            align-content: space-around;
}

.flex-content-stretch {
    -webkit-align-content: stretch;
        -ms-flex-line-pack: stretch;
            align-content: stretch;
}

/* Flex Items */
.flex-self-auto {
    -webkit-align-self: auto;
        -ms-flex-item-align: auto;
                -ms-grid-row-align: auto;
            align-self: auto;
}

.flex-self-start {
    -webkit-align-self: flex-start;
        -ms-flex-item-align: start;
            align-self: flex-start;
}

.flex-self-end {
    -webkit-align-self: flex-end;
        -ms-flex-item-align: end;
            align-self: flex-end;
}

.flex-self-center {
    -webkit-align-self: center;
        -ms-flex-item-align: center;
                -ms-grid-row-align: center;
            align-self: center;
}

.flex-self-baseline {
    -webkit-align-self: baseline;
        -ms-flex-item-align: baseline;
            align-self: baseline;
}

.flex-self-stretch {
    -webkit-align-self: stretch;
        -ms-flex-item-align: stretch;
                -ms-grid-row-align: stretch;
            align-self: stretch;
}

.flex-grow-0 {
    -webkit-box-flex: 0;
    -webkit-flex-grow: 0;
       -moz-box-flex: 0;
        -ms-flex-positive: 0;
            flex-grow: 0;
}

.flex-grow-1 {
    -webkit-box-flex: 1;
    -webkit-flex-grow: 1;
       -moz-box-flex: 1;
        -ms-flex-positive: 1;
            flex-grow: 1;
}

.flex-shrink-0 {
    -webkit-flex-shrink: 0;
        -ms-flex-negative: 0;
            flex-shrink: 0;
}

.flex-shrink-1 {
    -webkit-flex-shrink: 1;
        -ms-flex-negative: 1;
            flex-shrink: 1;
}

.flex-basis-auto {
    -webkit-flex-basis: auto;
        -ms-flex-preferred-size: auto;
            flex-basis: auto;
}

.flex-basis-0 {
    -webkit-flex-basis: 0;
        -ms-flex-preferred-size: 0;
            flex-basis: 0;
}

.flex-basis-25 {
    -webkit-flex-basis: 25%;
        -ms-flex-preferred-size: 25%;
            flex-basis: 25%;
}

.flex-basis-50 {
    -webkit-flex-basis: 50%;
        -ms-flex-preferred-size: 50%;
            flex-basis: 50%;
}

.flex-basis-75 {
    -webkit-flex-basis: 75%;
        -ms-flex-preferred-size: 75%;
            flex-basis: 75%;
}

.flex-basis-100 {
    -webkit-flex-basis: 100%;
        -ms-flex-preferred-size: 100%;
            flex-basis: 100%;
}

.flex-order-0 {
    -webkit-box-ordinal-group: 1;
    -webkit-order: 0;
       -moz-box-ordinal-group: 1;
        -ms-flex-order: 0;
            order: 0;
}

.flex-order-1 {
    -webkit-box-ordinal-group: 2;
    -webkit-order: 1;
       -moz-box-ordinal-group: 2;
        -ms-flex-order: 1;
            order: 1;
}

.flex-order-2 {
    -webkit-box-ordinal-group: 3;
    -webkit-order: 2;
       -moz-box-ordinal-group: 3;
        -ms-flex-order: 2;
            order: 2;
}

.flex-order-3 {
    -webkit-box-ordinal-group: 4;
    -webkit-order: 3;
       -moz-box-ordinal-group: 4;
        -ms-flex-order: 3;
            order: 3;
}

.flex-order-4 {
    -webkit-box-ordinal-group: 5;
    -webkit-order: 4;
       -moz-box-ordinal-group: 5;
        -ms-flex-order: 4;
            order: 4;
}

.flex-order-5 {
    -webkit-box-ordinal-group: 6;
    -webkit-order: 5;
       -moz-box-ordinal-group: 6;
        -ms-flex-order: 5;
            order: 5;
}

.flex-order-last {
    -webkit-box-ordinal-group: 1000;
    -webkit-order: 999;
       -moz-box-ordinal-group: 1000;
        -ms-flex-order: 999;
            order: 999;
2 Likes

Hi,

thanks for the suggestion. I see that there is no HTML attached, please find it below.

    <head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Order</title>
  <!-- Bootstrap CSS -->
  <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" crossorigin="anonymous">
  <!-- Custom CSS -->
</head>
    <style>
        @media print {
          @page {
            size: A4;
            margin: 1cm;
          }
        }
      </style>

  <header class="container-fluid mb-4" style="font-size: 68%;">
    <div class="row">
      <div class="col">
        <div>*******************</div>
        <div>**************************</div>
        <div>BG-1528 София</div>
        <div>МОЛ: ************</div>
      </div>
      <div class="col">
        <div>Тел: +*****************</div>
        <div>Факс: +******************</div>
        <div>Mail: *****************</div>
        <div>Web: ******************</div>
      </div>
    <div class="col">
        <div>IBAN EUR: **********************</div>
        <div>IBAN BGN: **********************</</div>
        <div>BIC: ********</div>
        <div>*****************</div>
        <div>ЗДДС ИД: ************</div>
      </div>
    </div>
  </header>

  <div class="container-fluid mt-4">
    <div class="row mt-4">
      <div class="col-4">
        <h6>Поръчка No:</h6>
      </div>
      <div class="col-8">
        <h5>{{doc.name}}</h5>
      </div>
    </div>
    <div class="row mt-4">
      <div class="col-4">
          <div>Дата:</div>
          <div>Доставчик:</div>
          <div>Референция:</div>
          <div>Поръчал:</div>
      </div>
      <div class="col-8">
          <div style="font-weight: bold;">{{doc.transaction_date}}</div>
          <div style="font-weight: bold;">{{_(doc.supplier_name)}}</div>
          <div>--</div>
          <div>*************</div>
          <div>+000000000000</div>
      </div>
    </div>
    <div class="row mt-4">
      <div class="col-6">
        <h6>Адрес за Доставка:</h6>
          <div>******************</div>
          <div>******************</div>
          <div>******************</div>
          <div>**********</div>
          <div>България</div>
          <div>Телефон за контакт: +***************</div>
      </div>
      <div class="col-6">
        <h6>Данни за фактура:</h6>
          <div>*********************</div>
          <div>*********************</div>
          <div>***********</div>
          <div>България</div>
          <div>ИД по ЗДДС: ***********</div>
          <div>МОЛ: ********************</div>
      </div>
    </div>
    <div class="row mt-4 mb-2">
      <h6>Потвърждаваме поръчката на следните позиции:</h6>
    </div>
    <table class="table table-sm table-bordered" style="font-size: 75%;">
      <thead>
        <tr>
          <th class="col-1">Поз.</th>
          <th class="col-2">Име/Код</th>
          <th class="col-6">Описание</th>
          <th class="col-1">Кол.</th>
          <th class="col-1">Ед.</th>
          <th class="col-1">Желана доставка</th>
        </tr>
      </thead>
      <tbody>
        {%- for row in doc.items -%}
            <tr>
            <td class="col-1">{{ row.idx }}</td>
            <td class="col-2">{{ row.item_code }}</td>
            <td class="col-6">{{_(row.description) }}</td>
            <td class="col-1">{{ row.qty }}</td>
            <td class="col-1">{{ row.uom }}</td>
            <td class="col-1">{{ row.schedule_date }}</td>
            </tr>
        {%- endfor -%}
      </tbody>
    </table>
    <div class="row mt-4">
      <h6 style="font-style: italic;">Моля да потвърдите сроковете на доставка в с последващ EМail до 3 работни дни от датата на настоящата поръчка.</h6>
    </div>
  </div>

  <footer class="container-fluid mt-4">
    <div class="row">
      <div class="col">
        <h6>
          <div>С най-добри пожелания,</div>
          <div>**************</div>
        </h6>
      </div>
    </div>
  </footer>

What do you suggest, where should we put the CSS styling you suggested?

Thanks!

You can not load external css (Bootstrap) into wkhtmltopdf.

Either user flex as mentioned in my previous comment or stick to the original structure.

Hi,

thanks again. Sorry for the stupid question. but I don’t get it how to modify the custom format, so that the PDF gets the styles we need. Apparently somehow wkhtmltopdf processes the CSS for the table, but not for our custom HTML.
We tried to put the above CSS in section in the above code, but there was no effect.
Sorry, wkhtmltopdf in combination with erpnext/frappe is really new experience for us.

Thanks a lot!

You must have basic CSS/HTML knowledge to be able to make your own custom print formats. The “code” I shared above is basically some flex and flex properties that are prefixed and put into classes. These classes can be added to your divs.

However it seems you do not have enough knowledge in HTML/CSS so I would suggest checking out Print Designer