openhtmltopdf icon indicating copy to clipboard operation
openhtmltopdf copied to clipboard

Javascript is not executed in HTML before rendering PDF

Open kiranduba opened this issue 1 year ago • 1 comments

Hi, I have created HTML template with placeholders for passing dynamic content and script renders ul-li. Im able to generate PDF but JS code is not getting executed before PDF rendering and causing blank ul-li.

`import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.nio.file.FileSystems; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths;

import org.apache.commons.io.FileUtils; import org.jsoup.Jsoup; import org.jsoup.helper.W3CDom; import org.jsoup.nodes.Document;

import com.openhtmltopdf.pdfboxout.PdfRendererBuilder;

public class Html2PdfUsingOpenHtml {

private static final String C_CODEBASE_SPRING_PDF_TEMPORARY_HTML = "C:\\Codebase\\spring\\pdf\\temporary.html";
private static final String PDF_OUTPUT = "C:\\Codebase\\spring\\pdf\\final.pdf";

private Document createWellFormedHtml(final File inputHTML) throws Exception {

    final Document document = Jsoup.parse(inputHTML, "UTF-8");
    document.outputSettings().syntax(Document.OutputSettings.Syntax.xml);
    return document;
}

private void generateHtmlToPdf() throws Exception {

    // final String htmlTemplate = "<html><body>Hello, ${name}!</body></html>";

    final String fileContent = readFileToString("C:\\Codebase\\spring\\pdf\\test.html");

    String dynamicContent = fileContent.replace("${name}", "John Doe");
    dynamicContent = dynamicContent.replace("${customer}",
            "[{'name': 'John', 'age': '30', 'city': 'New York'},{'name': 'Rambo', 'age': '50', 'city': 'Arizona'}]");

    final File tempHTML = new File(C_CODEBASE_SPRING_PDF_TEMPORARY_HTML);
    FileUtils.writeStringToFile(tempHTML, dynamicContent);

    final Document doc = createWellFormedHtml(tempHTML);
    renderPDF(doc, PDF_OUTPUT);
}

private void renderPDF(final Document doc, final String outputPdf) throws Exception {

    try (ByteArrayOutputStream os = new ByteArrayOutputStream()) {
        final String baseUri = FileSystems.getDefault().getPath("src/main/resources/").toUri().toString();
        final PdfRendererBuilder builder = new PdfRendererBuilder();
        // builder.withUri(outputPdf);
        builder.toStream(os);
        builder.withW3cDocument(new W3CDom().fromJsoup(doc), baseUri);
        builder.run();
        os.writeTo(new FileOutputStream(outputPdf));
    }
}

public static void main(final String[] args) {

    try {
        final Html2PdfUsingOpenHtml htmlToPdf = new Html2PdfUsingOpenHtml();
        htmlToPdf.generateHtmlToPdf();
    } catch (final Exception e) {
        e.printStackTrace();
    }
}

public static String readFileToString(final String filePath) throws IOException {

    // Create a Path object from the file path
    final Path path = Paths.get(filePath);

    // Read the file content into a byte array
    final byte[] bytes = Files.readAllBytes(path);

    // Convert the byte array to a string using the default character encoding
    return new String(bytes);
}

}`

Dependencies are :

<dependency> <groupId>com.openhtmltopdf</groupId> <artifactId>openhtmltopdf-core</artifactId> <version>1.0.6</version> </dependency> <dependency> <groupId>com.openhtmltopdf</groupId> <artifactId>openhtmltopdf-pdfbox</artifactId> <version>1.0.6</version> </dependency> <dependency> <groupId>com.openhtmltopdf</groupId> <artifactId>openhtmltopdf-svg-support</artifactId> <version>1.0.5</version> </dependency> <dependency> <groupId>org.jsoup</groupId> <artifactId>jsoup</artifactId> <version>1.13.1</version> </dependency>

kiranduba avatar Sep 18 '23 11:09 kiranduba

Is running JS even supported? Why don't you just replace your JS logic (which is not visible in the code you shared) with replacements/manipulations through your Java code? If you need to do complex things like loops, conditions etc. you could use a Java-based templating approach (via say Freemarker) to create your final HTML rather than rely on JS in the template.

costas80 avatar Sep 19 '23 07:09 costas80