title: Converting HTML to PDF using iText
body: <p>I am posting this question because many developers ask more or less the same question in different forms. I will answer this question myself (I am the Founder/CTO of iText Group), so that it can be a "Wiki-answer." If the Stack Overflow "documentation" feature still existed, this would have been a good candidate for a documentation topic.</p>
  
  <h1>The source file:</h1>
  
  <p>I am trying to convert the following HTML file to PDF:</p>
  
  <pre><code>&lt;html&gt;
      &lt;head&gt;
          &lt;title&gt;Colossal (movie)&lt;/title&gt;
          &lt;style&gt;
              .poster { width: 120px;float: right; }
              .director { font-style: italic; }
              .description { font-family: serif; }
              .imdb { font-size: 0.8em; }
              a { color: red; }
          &lt;/style&gt;
      &lt;/head&gt;
      &lt;body&gt;
          &lt;img src="img/colossal.jpg" class="poster" /&gt;
          &lt;h1&gt;Colossal (2016)&lt;/h1&gt;
          &lt;div class="director"&gt;Directed by Nacho Vigalondo&lt;/div&gt;
          &lt;div class="description"&gt;Gloria is an out-of-work party girl
              forced to leave her life in New York City, and move back home.
              When reports surface that a giant creature is destroying Seoul,
              she gradually comes to the realization that she is somehow connected
              to this phenomenon.
          &lt;/div&gt;
          &lt;div class="imdb"&gt;Read more about this movie on
              &lt;a href="www.imdb.com/title/tt4680182"&gt;IMDB&lt;/a&gt;
          &lt;/div&gt;
      &lt;/body&gt;
  &lt;/html&gt;
  </code></pre>
  
  <p>In a browser, this HTML looks like this:</p>
  
  <p><a href="https://i.stack.imgur.com/IKOdC.jpg" rel="noreferrer"><img src="https://i.stack.imgur.com/IKOdC.jpg" alt="enter image description here"></a></p>
  
  <h1>The problems I encountered:</h1>
  
  <p><strong>HTMLWorker doesn't take CSS into account at all</strong></p>
  
  <p>When I used <code>HTMLWorker</code>, I need to create an <code>ImageProvider</code> to avoid an error that informs me that the image can't be found. I also need to create a <code>StyleSheet</code> instance to change some of the styles:</p>
  
  <pre><code>public static class MyImageFactory implements ImageProvider {
      public Image getImage(String src, Map&lt;String, String&gt; h,
              ChainedProperties cprops, DocListener doc) {
          try {
              return Image.getInstance(
                  String.format("resources/html/img/%s",
                      src.substring(src.lastIndexOf("/") + 1)));
          } catch (DocumentException e) {
              e.printStackTrace();
          } catch (IOException e) {
              e.printStackTrace();
          }
          return null;
      }    
  }
  
  public static void main(String[] args) throws IOException, DocumentException {
      Document document = new Document();
      PdfWriter.getInstance(document, new FileOutputStream("results/htmlworker.pdf"));
      document.open();
      StyleSheet styles = new StyleSheet();   
      styles.loadStyle("imdb", "size", "-3");
      HTMLWorker htmlWorker = new HTMLWorker(document, null, styles);
      HashMap&lt;String,Object&gt; providers = new HashMap&lt;String, Object&gt;();
      providers.put(HTMLWorker.IMG_PROVIDER, new MyImageFactory());
      htmlWorker.setProviders(providers);
      htmlWorker.parse(new FileReader("resources/html/sample.html"));
      document.close();   
  }
  </code></pre>
  
  <p>The result looks like this:</p>
  
  <p><a href="https://i.stack.imgur.com/ym0N0.jpg" rel="noreferrer"><img src="https://i.stack.imgur.com/ym0N0.jpg" alt="enter image description here"></a></p>
  
  <p>For some reason, <code>HTMLWorker</code> also shows the content of the <code>&lt;title&gt;</code> tag. I don't know how to avoid this. The CSS in the header isn't parsed at all, I have to define all the styles in my code, using the <code>StyleSheet</code> object.</p>
  
  <p>When I look at my code, I see that plenty of objects and methods I'm using are deprecated:</p>
  
  <p><a href="https://i.stack.imgur.com/5LX3y.jpg" rel="noreferrer"><img src="https://i.stack.imgur.com/5LX3y.jpg" alt="enter image description here"></a></p>
  
  <p>So I decided to upgrade to using XML Worker.</p>
  
  <hr>
  
  <p><strong>Images aren't found when using XML Worker</strong></p>
  
  <p>I tried the following code:</p>
  
  <pre><code>public static final String DEST = "results/xmlworker1.pdf";
  public static final String HTML = "resources/html/sample.html";
  public void createPdf(String file) throws IOException, DocumentException {
      Document document = new Document();
      PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(file));
      document.open();
      XMLWorkerHelper.getInstance().parseXHtml(writer, document,
              new FileInputStream(HTML));
      document.close();
  }
  </code></pre>
  
  <p>This resulted in the following PDF:</p>
  
  <p><a href="https://i.stack.imgur.com/fPpm1.jpg" rel="noreferrer"><img src="https://i.stack.imgur.com/fPpm1.jpg" alt="enter image description here"></a></p>
  
  <p>Instead of Times-Roman, the default font Helvetica is used; this is typical for iText (I should have defined a font explicitly in my HTML). Otherwise, the CSS seems to be respected, but the image is missing, and I didn't get an error message.</p>
  
  <p>With <code>HTMLWorker</code>, an exception was thrown, and I was able to fix the problem by introducing an <code>ImageProvider</code>. Let's see if this works for XML Worker.</p>
  
  <p><strong>Not all CSS styles are supported in XML Worker</strong></p>
  
  <p>I adapted my code like this:</p>
  
  <pre><code>public static final String DEST = "results/xmlworker2.pdf";
  public static final String HTML = "resources/html/sample.html";
  public static final String IMG_PATH = "resources/html/";
  public void createPdf(String file) throws IOException, DocumentException {
      Document document = new Document();
      PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(file));
      document.open();
  
      CSSResolver cssResolver =
              XMLWorkerHelper.getInstance().getDefaultCssResolver(true);
      HtmlPipelineContext htmlContext = new HtmlPipelineContext(null);
      htmlContext.setTagFactory(Tags.getHtmlTagProcessorFactory());
      htmlContext.setImageProvider(new AbstractImageProvider() {
          public String getImageRootPath() {
              return IMG_PATH;
          }
      });
  
      PdfWriterPipeline pdf = new PdfWriterPipeline(document, writer);
      HtmlPipeline html = new HtmlPipeline(htmlContext, pdf);
      CssResolverPipeline css = new CssResolverPipeline(cssResolver, html);
  
      XMLWorker worker = new XMLWorker(css, true);
      XMLParser p = new XMLParser(worker);
      p.parse(new FileInputStream(HTML));
  
      document.close();
  }
  </code></pre>
  
  <p>My code is much longer, but now the image is rendered:</p>
  
  <p><a href="https://i.stack.imgur.com/38bPb.jpg" rel="noreferrer"><img src="https://i.stack.imgur.com/38bPb.jpg" alt="enter image description here"></a></p>
  
  <p>The image is larger than when I rendered it using <code>HTMLWorker</code> which tells me that the CSS attribute <code>width</code> for the <code>poster</code> class is taken into account, but the <code>float</code> attribute is ignored. How do I fix this?</p>
  
  <h1>The remaining question:</h1>
  
  <p>So the question boils down to this: I have a <em>specific</em> HTML file that I try to convert to PDF. I have gone through a lot of work, fixing one problem after the other, but there is one <em>specific</em> problem that I can't solve: how do I make iText respect CSS that defines the position of an element, such as <code>float: right</code>?</p>
  
  <h1>Additional question:</h1>
  
  <p>When my HTML contains form elements (such as <code>&lt;input&gt;</code>), those form elements are ignored.</p>