Weasyprint: Examples of strictly designed and complex generated pdfs?

Created on 7 Feb 2017  路  2Comments  路  Source: Kozea/WeasyPrint

Dear WeasyPrinters,

this is perhaps a "documentation" type question:

For a project, we would like to generate some fairly fancy .pdf reports. Weasyprint works well for us. The question we have now: Does is also have the capacity to generated .pdfs when the design requirements are pretty strict?

It would be great to know what the WeasyPrint community thinks about this, and also if somewhere there are some convincing .pdf examples (perhaps even with the .css) which I simply missed when I searched?

I've created this stackoverflow q on the topic - so if you had an answer on stackoverflow perhaps, this would be helpful:

http://stackoverflow.com/questions/42091524/python-create-automated-strictly-designed-multi-page-pdf-report-from-html

for reference, this is our example of a "Strictly designed pdf" - of course just one of many possible:
screen shot 2017-02-07 at 2 07 00 pm

Thanks a lot and thanks of course also for this great library!

documentation

Most helpful comment

Thanks a lot and thanks of course also for this great library!

You're welcome!

The link given in StackOverflow is amazing.

We (Kozea) use WeasyPrint to generate various documents, including long reports with lots of stats just like your example. We also use Jinja to generate HTML, and we use Pygal for charts.

Generating documents with small manual adjustments is pretty easy when you have HTML, CSS, design and typography skills. Carefully reading the supported CSS features of WeasyPrint can help to discover what can be done.

If your generation must be fully automated, it'll be much harder but not impossible. You'll have to learn the CSS specs related to paged media and be really, really patient to understand the CSS logic about documents and endlessly tweak your CSS stylesheets.

Here's a quick and dirty example:
test

<html>
  <head>
    <link rel="stylesheet" type="text/css" href="file:///tmp/test.css">
  </head>

  <body>
    <h1>A Headline</h1>

    <aside>
      <article>
        <h2>Orci varius natoque</h2>
        <embed src="file:///tmp/pie.svg" />
      </article>

      <article>
        <h2>Orci varius natoque</h2>
        <embed src="file:///tmp/pie.svg" />
      </article>

      <article>
        <h2>Orci varius natoque</h2>
        <embed src="file:///tmp/pie.svg" />
      </article>
    </aside>

    <meter min="0" max="100" value="70">-3.9%</meter>

    <section id="main">
      <article>
        <h2>Lorem ipsum dolor sit amet</h2>
        <p>
          Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse eu
          neque vel mi consequat porttitor. Pellentesque sit amet nulla cursus
          elit venenatis efficitur. Suspendisse tempor, nisi vel suscipit
          ultrices, velit nulla volutpat dolor, ut aliquam purus nibh et
          dolor. Quisque metus nibh, egestas in sapien eu, ullamcorper faucibus
          ipsum. Nunc mollis magna ac quam laoreet sodales. Fusce ut ipsum non
          nulla molestie volutpat id id leo. Maecenas in rutrum mauris.
        </p>
      </article>

      <article>
        <h2>Orci varius natoque penatibus et magnis</h2>
        <embed src="file:///tmp/chart.svg" />
      </article>

      <article>
        <h2>Orci varius natoque penatibus et magnis</h2>
        <embed src="file:///tmp/chart.svg" />
      </article>
    </section>

    <section id="secondary">
      <article>
        <h2>Orci varius natoque penatibus et magnis</h2>
        <p>Lorem ipsum</p>
      </article>

      <article>
        <h2>Orci varius natoque penatibus et magnis</h2>
        <p>Lorem ipsum</p>
      </article>
    </section>
  </body>
</html>
@page {
  margin: 4em 2em;

  @top-left {
    content: "Here is the header copy";
    font-size: 0.8em;
  }

  @bottom-left {
    border-top: 1px solid #aaa;
    content: "Here is the footer copy";
    font-size: 0.8em;
    padding: 0.5em 0;
    vertical-align: top;
    width: 100%;
  }

  @bottom-right {
    border-top: 1px solid #aaa;
    content: "Page " counter(page) " of " counter(pages);
    font-size: 0.8em;
    padding: 0.5em 0;
    vertical-align: top;
    width: 100%;
  }
}

html {
  color: #666;
  font-family: sans;
  font-size: 10pt;
  line-height: 1.4;
}


h1 {
  font-weight: 400;
}

h2 {
  color: #27b;
  font-size: 1em;
  margin: 2em 0 0 0;
  text-transform: uppercase;
}

p {
  margin: 0.5em 0;
  text-align: justify;
}


aside {
  background: #eee;
  float: right;
  margin-left: 1em;
  width: 30%;
}

aside embed {
  margin-bottom: 1em;
  width: 100%;
}

aside article {
  margin: 1em;
}

aside article:not(article:last-child) {
  border-bottom: 1px solid #aaa;
}


#secondary {
  width: 65%;
}

#secondary article {
  display: table-cell;
  padding-right: 1em;
}

#secondary p {
  background: #eee;
  padding: 1em;
  text-align: center;
}


meter {
  color: #d44;
  font-size: 1.5em;
  font-weight: bold;
  position: relative;
}

meter:before,
meter:after {
  border: 1px solid #888;
  border-radius: 0.3em;
  content: '';
  display: inline-block;
  height: 1.2em;
  margin-right: 1em;
  vertical-align: top;
  width: 50%;
}

meter:after {
  background: #d44;
  border-color: transparent;
  border-radius: 0.3em 0 0 0.3em;
  left: 0;
  position: absolute;
  top: 0;
  width: 60%;
}

embed {
  width: 60%;
}

All 2 comments

Thanks a lot and thanks of course also for this great library!

You're welcome!

The link given in StackOverflow is amazing.

We (Kozea) use WeasyPrint to generate various documents, including long reports with lots of stats just like your example. We also use Jinja to generate HTML, and we use Pygal for charts.

Generating documents with small manual adjustments is pretty easy when you have HTML, CSS, design and typography skills. Carefully reading the supported CSS features of WeasyPrint can help to discover what can be done.

If your generation must be fully automated, it'll be much harder but not impossible. You'll have to learn the CSS specs related to paged media and be really, really patient to understand the CSS logic about documents and endlessly tweak your CSS stylesheets.

Here's a quick and dirty example:
test

<html>
  <head>
    <link rel="stylesheet" type="text/css" href="file:///tmp/test.css">
  </head>

  <body>
    <h1>A Headline</h1>

    <aside>
      <article>
        <h2>Orci varius natoque</h2>
        <embed src="file:///tmp/pie.svg" />
      </article>

      <article>
        <h2>Orci varius natoque</h2>
        <embed src="file:///tmp/pie.svg" />
      </article>

      <article>
        <h2>Orci varius natoque</h2>
        <embed src="file:///tmp/pie.svg" />
      </article>
    </aside>

    <meter min="0" max="100" value="70">-3.9%</meter>

    <section id="main">
      <article>
        <h2>Lorem ipsum dolor sit amet</h2>
        <p>
          Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse eu
          neque vel mi consequat porttitor. Pellentesque sit amet nulla cursus
          elit venenatis efficitur. Suspendisse tempor, nisi vel suscipit
          ultrices, velit nulla volutpat dolor, ut aliquam purus nibh et
          dolor. Quisque metus nibh, egestas in sapien eu, ullamcorper faucibus
          ipsum. Nunc mollis magna ac quam laoreet sodales. Fusce ut ipsum non
          nulla molestie volutpat id id leo. Maecenas in rutrum mauris.
        </p>
      </article>

      <article>
        <h2>Orci varius natoque penatibus et magnis</h2>
        <embed src="file:///tmp/chart.svg" />
      </article>

      <article>
        <h2>Orci varius natoque penatibus et magnis</h2>
        <embed src="file:///tmp/chart.svg" />
      </article>
    </section>

    <section id="secondary">
      <article>
        <h2>Orci varius natoque penatibus et magnis</h2>
        <p>Lorem ipsum</p>
      </article>

      <article>
        <h2>Orci varius natoque penatibus et magnis</h2>
        <p>Lorem ipsum</p>
      </article>
    </section>
  </body>
</html>
@page {
  margin: 4em 2em;

  @top-left {
    content: "Here is the header copy";
    font-size: 0.8em;
  }

  @bottom-left {
    border-top: 1px solid #aaa;
    content: "Here is the footer copy";
    font-size: 0.8em;
    padding: 0.5em 0;
    vertical-align: top;
    width: 100%;
  }

  @bottom-right {
    border-top: 1px solid #aaa;
    content: "Page " counter(page) " of " counter(pages);
    font-size: 0.8em;
    padding: 0.5em 0;
    vertical-align: top;
    width: 100%;
  }
}

html {
  color: #666;
  font-family: sans;
  font-size: 10pt;
  line-height: 1.4;
}


h1 {
  font-weight: 400;
}

h2 {
  color: #27b;
  font-size: 1em;
  margin: 2em 0 0 0;
  text-transform: uppercase;
}

p {
  margin: 0.5em 0;
  text-align: justify;
}


aside {
  background: #eee;
  float: right;
  margin-left: 1em;
  width: 30%;
}

aside embed {
  margin-bottom: 1em;
  width: 100%;
}

aside article {
  margin: 1em;
}

aside article:not(article:last-child) {
  border-bottom: 1px solid #aaa;
}


#secondary {
  width: 65%;
}

#secondary article {
  display: table-cell;
  padding-right: 1em;
}

#secondary p {
  background: #eee;
  padding: 1em;
  text-align: center;
}


meter {
  color: #d44;
  font-size: 1.5em;
  font-weight: bold;
  position: relative;
}

meter:before,
meter:after {
  border: 1px solid #888;
  border-radius: 0.3em;
  content: '';
  display: inline-block;
  height: 1.2em;
  margin-right: 1em;
  vertical-align: top;
  width: 50%;
}

meter:after {
  background: #d44;
  border-color: transparent;
  border-radius: 0.3em 0 0 0.3em;
  left: 0;
  position: absolute;
  top: 0;
  width: 60%;
}

embed {
  width: 60%;
}

We've now added a samples page on our website, with more and more examples coming soon!

Was this page helpful?
0 / 5 - 0 ratings

Related issues

ivanprice picture ivanprice  路  3Comments

whitelynx picture whitelynx  路  5Comments

jeffgabhart picture jeffgabhart  路  3Comments

Daniyal-Javani picture Daniyal-Javani  路  3Comments

Tontyna picture Tontyna  路  4Comments