Trouble with displaying label in PDF post HTML conversion using iText html2pdf

Software Versions:

  • html2pdf v2.0.1
  • iText 7.1.1

The HTML label that spans the width of the page is as follows:

<label class="test">Patient</label>

CSS Styling:

.test {
    display: block;
    font-weight: bold;
    color: #009fd1;
    font-size: .6em;
    text-align: left;
    padding: 0.5rem;
    background: #085a9f;
    border-radius: 3px;
} 

https://i.sstatic.net/OCT8y.png

However, when converting this HTML to PDF using iText, the label appears differently:

https://i.sstatic.net/wgWDv.png

It seems like the issue lies with the display: block and border-radius: 3px properties.

Could this be a problem with iText?

Here is the code snippet for the conversion process:

    
public ByteArrayOutputStream createPdf(String html) throws IOException {
    ByteArrayOutputStream baos = null;
    html = replaceStylesheet(html);
    try {
        baos = new ByteArrayOutputStream();
        WriterProperties writerProperties = new WriterProperties();
        
        PdfWriter pdfWriter = new PdfWriter(baos, writerProperties);

        PdfDocument pdfDoc = new PdfDocument(pdfWriter);
        PageSize pageSize = PageSize.A4;
        pdfDoc.setDefaultPageSize(pageSize);
        pdfDoc.getCatalog().setLang(new PdfString("en-US"));
       
        pdfDoc.setTagged();
        PdfViewerPreferences pdfViewerPreferences = new PdfViewerPreferences();
        pdfViewerPreferences.setDisplayDocTitle(true);
        pdfDoc.getCatalog().setViewerPreferences(pdfViewerPreferences);

        String header = "© 2018 Generated by OpenNCP Portal";
        Header headerHandler = new Header(header);
        PageXofY footerHandler = new PageXofY(pdfDoc);
        
        pdfDoc.addEventHandler(PdfDocumentEvent.START_PAGE,headerHandler);
        pdfDoc.addEventHandler(PdfDocumentEvent.END_PAGE,footerHandler);

        ConverterProperties props = new ConverterProperties();
        FontProvider dfp = new DefaultFontProvider(true, false, false);

        props.setFontProvider(dfp);

        HtmlConverter.convertToDocument(html, pdfDoc, props);
        footerHandler.writeTotal(pdfDoc);
        pdfDoc.close();
    } catch (Exception e) {
        LOGGER.error("Error occurred when converting HTML to PDF", e);
    }
    return baos;
}

Answer №1

Undoubtedly, the issue lies within the current version of iText and your assumptions are indeed correct.

There are two main issues at play here. The first one being that in pdfHTML, the display:block attribute for the label element is not supported as it defaults to inline. It appears that enabling display:block for label can be achieved easily by extending the DefaultTagWorkerFactory and DefaultCssApplierFactory as shown below:

private static class LabelBlockTagWorkerFactory extends DefaultTagWorkerFactory {
    @Override
    public ITagWorker getCustomTagWorker(IElementNode tag, ProcessorContext context) {
        // code implementation here
    }

}

private static class LabelBlockCssApplierFactory extends DefaultCssApplierFactory {
    @Override
    public ICssApplier getCustomCssApplier(IElementNode tag) {
        // code implementation here
    }
}

These custom factories can then be set in the ConverterProperties:

props.setTagWorkerFactory(new LabelBlockTagWorkerFactory());
props.setCssApplierFactory(new LabelBlockCssApplierFactory());

The second issue pertains to the lack of support for the border-radius property on inline elements' backgrounds. This is currently a known bug in iText, but it should not pose an obstacle once you have resolved the display:block problem.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

How about connecting functions in JavaScript?

I'm looking to create a custom function that will add an item to my localStorage object. For example: alert(localStorage.getItem('names').addItem('Bill').getItem('names')); The initial method is getItem, which retrieves ...

Why is thread sleep ineffective in Safari with Selenium?

While I've successfully slowed down selenium in FireFox using Thread.sleep(xx), the same technique doesn't work in Safari. Please refrain from suggesting waiting until the element is found. A fellow user experienced a similar issue and shared th ...

changing the vertical position of an element using JavaScript

I'm currently working on a project where I have a canvas that animates upwards when a button is clicked. However, I'm facing an issue with making it go back down after the animation completes. It seems to be getting stuck and not returning to its ...

Broken links preventing page navigation

As embarrassing as it is, I seem to have forgotten the basics of linking pages in HTML. I've been focusing so much on CSS that now, when it's time to create a website with multiple pages, I'm stumped. The links in my navbar aren't worki ...

The utilization of bootstrap can lead to CSS interruptions

I am trying to create a navigation button that transforms from 3 horizontal lines to an X shape when clicked. var anchor = document.querySelectorAll('button'); [].forEach.call(anchor, function(anchor) { var open = false; an ...

Creating a StreamSupplier for IntStream: A step-by-step guide

This is my first experience working with Streams in Java. I started by creating an IntStream with 1000 numbers. However, when I attempted to perform multiple operations, I encountered an error. After investigating further, I discovered that Streams are c ...

Having trouble applying CSS styles to the root element despite using a CSS file

My reactjs entry component setup looks like this: import React from "react" import ReactDOM from 'react-dom'; import App from "./js/components/App.js" import './index.css'; ReactDOM.render(<App />, document.getElementById(' ...

Learn how to use AJAX to automatically retrieve the contents of a file

I'm currently exploring AJAX to retrieve the contents of a file upon clicking a button, as I am fairly new to AJAX. Below is the HTML code snippet: <!DOCTYPE html> <html> <head> <script> function loadXMLDoc() { ...

Using Java and regular expressions to split a string by a period (.) unless it is part of a fraction

Is there a way to split a string in Java using regex, specifically based on dots but only if the dot is between alphabetic characters? For example, given the string: System.out.println(5.55); I want the output to be: System out println(5.55); ...

Changing the value of a user object's variable in Django

I have been working on implementing a feature that allows users to edit their personal information in a Django project using Django forms. However, after entering new values in the form and hitting enter, the user is redirected back to the main profile pag ...

Customize the drawer background in Vue Material

Recently, I developed a vuejs application incorporating Google's material design components. I've been exploring options to customize the background color. <template> <div class="page-container"> <md-app> ...

Is there a way for me to set distinct values for the input box using my color picker?

I have two different input boxes with unique ids and two different color picker palettes. My goal is to allow the user to select a color from each palette and have that color display in the corresponding input box. Currently, this functionality is partiall ...

Why is it that the bootstrap text color class isn't applying for my project?

After some experience with bootstrap, I have encountered an issue with the text-white class. Despite trying to change the text color using this class, it doesn't seem to work. Below is the code that I've been working on. Can anyone spot what migh ...

When Components in Vue are called in a Single File, certain elements may not be displaying as expected

I have just finished creating my components using Vue 2, Vuetify, and Vue cli - 4.5.15. I attempted to combine them into a Single Vue file but encountered issues with the components not displaying <v-icons>, <v-textfield>, and some other elemen ...

Dynamic Data Drive Multi-Series Line Graph

I am currently working on creating a D3 line chart. I have taken the code from the block builder and adjusted it with my own data. While the code is functional, I'm facing an issue where the labels are not showing up when I hover over the line. My ma ...

Generate an HTML table dynamically from a PostgreSQL query

I am facing a challenge that may be simple for experienced individuals but is proving to be difficult for me as a newbie. The task at hand involves retrieving JSON data from a database query and displaying it in an HTML table using Node.js, Express, and Po ...

Transform the image background on mouse hover using CSS

On my php page, I am dynamically visualizing thumbnails. To ensure that they are all the same size, I use the following method: <a class="zoom" href="..."> <img src="thumb/default.png" width="130" style="background-image:url(thumb/<?php echo $ ...

Infinite scrolling made effortless with jQuery and Ajax

I am attempting to create a basic infinite scroll feature that monitors when the user scrolls to the bottom in an HTML file. Once the bottom is reached, it should then load additional content from another HTML file which contains more text. The second HTM ...

Enhance the appearance of text fields in Android app by implementing a double border design

Just started learning about Android development and I'm curious if there's a way to include two borders in a text field - one inside the other. Is it possible for the inner border to change color to blue or any specified color when the user input ...

Pictures are not appearing correctly when utilizing the img-fluid class

Issues occur when I apply the "img-fluid" bootstrap class to my images, as they fail to appear on the page and are set at 0x0 pixels in size upon inspection. This is the HTML code: <div class="col"> <div class="row no-gutters"> &l ...