Sending html to pdf converter

Looking for a way to convert HTML (which I build inside another workflow) into a PDF, preferably inside my own network. So I found Gotenberg, which looks very promising.

Their API expects a file named index.html: HTML API call and I don’t yet understand how to do that in n8n: should I write my HTML into a file like that? And call the API with a path to that file (but where would that path point to)?

hints welcome, thanks a lot

Gotenberg looks nice. I tested it out and it works well.
They have a docker which you can run locally. You need to call their API to get a PDF from a URL you pass
Then for n8n, I would assume you need to write the html to a local file and present it on a localip:port/document.html or pass it as a binary to the gotenberg endpoint.

You may also want to have a look at this Webhook | Gotenberg

Sure, I have their docker image running here already. The missing bit for me is how to get the HTML output of my other node(s) into the Webhook-Call or the HTTP-Request. I might ask the Gotenberg-people also.

If it is possible to “store” the generated HTML in some kind of temporary file usable by the workflow, this would be a possibility, right?

Save the file locally and then pass it as below
from Chromium | Gotenberg

curl \
--request POST 'http://localhost:3000/forms/chromium/convert/html' \
--form '[email protected]"/path/to/index.html"' \
-o my.pdf

Use Write Binary File node to write to local file system (on docker of course, mapped to the docker host - usually local_files)

You can use this as a starting point

Appreciate if you can share the final workflow for everyone

Seems like another useful node - havent used it so cant tell

Thank you, yes, I already had something similar. So far not yet successful, but I am a newbie so that has to be expected :wink:

“JSON to binary” requires JSON as input, sure, so I have to add a node to convert HTML to JSON first. That’s my next step.

(In the end I will have to write a HTML document containing data from multiple JSON objects, adding some css-formatting, and this should be converted into a PDF, then pushed into some API again. At least that’s my current plan)

I dont think you need to convert JSON to HTML at all.
That would NOT be a fun exercise - you can just write HTML using Write Binary node

Ah, OK, thanks.

Yes, I am able to write a test HTML file to “plaintext.html”.
Changing the field “File Name” in the “Write Binary File” node to “/tmp/index.html” doesn’t change the File Name on the output side.

The Gotenberg Webhook Module wants “index.html” according to: Webhook | Gotenberg

I have a HTTP request node already calling the Gotenberg container which is able to call a Webhook in n8n … (and receive the pdf file) :wink: so I get closer.

I think I have to send the body of the html document as well.
Unsure how to set that correctly.

“Body Content Type” ? etc

Tried various combinations, Gotenberg always complains with “not multipart-data”

But maybe because the node doesn’t read in the file from the previous node, I can’t tell 100%

I try:

Body Content Type: n8n Binary Data

Input Data Field Name: data

?

Let me show what I have.

The HTTP Request calls the Gotenberg-container with several parameters:

according to Webhook | Gotenberg I send headers for Webhook-URLs (that’s where the generated pdf should be delivered to) and most important: the path to the html-file that should be converted.

Is that a header at all?

The curl-example says (I skip the Webhook-headers here):

curl \
--request POST 'http://localhost:3000/forms/chromium/convert/html' \
--form '[email protected]"/path/to/index.html"' \
-o my.pdf

My try:

If someone wants to try, there is a Live Demo URL for Gotenberg, their docs give this example call:

curl \
--request POST 'https://demo.gotenberg.dev/forms/chromium/convert/url' \
--form 'url="https://sparksuite.github.io/simple-html-invoice-template/"' \
-o my.pdf

regards, Stefan

This works - now still trying to figure out the right way to send the html file in the form-data.
The obvious way hasnt worked so far !

After reading the docs, the [email protected]/path/to/file seems to indicate it needs a file on its local disk.
It cannot be passed in using the form-data from my testing.
You will need to write the file on the docker storage of the Gotenberg docker (or better yet, a shared folder between the host, n8n,gotenberg), then pass that relative path to the above node.
I have limited knowledge of share storage on docker so cant help.

You will NOT need write file etc.

@treyr thanks for trying and researching.

I will see if shared docker storage might do the trick. I have experience around that, will look into this tomorrow.

I am sure it will work.
At the very least adding a local xyz.html to the gotenberg docker and calling the sample node I pasted above should work.
If that works, shared storage will work too

You will obviously have to change the url parameter to files and then see how that @ sign works for syntax

Found a ticket at PDF from POST Body · Discussion #558 · gotenberg/gotenberg · GitHub

This points to convert html to pdf where an example is given for using a html stream.

I don’t yet fully understand how to integrate that.
And I wonder if this would work with larger chunks of HTML as well.

I asked there now also …

The Gotenberg-dev suggests putting the source html file to a webserver and using the URL route

Playing with this now: Docker Hub :wink:

Trying to set up a HTTP-request to put the file into that.

In-memory stream wont work - because you have no memory shared between n8n and gotenberg dockers.
Go the HTML->URL route

Yes. Do you have a recommendation how to host that “temporary” file? I didn’t yet manage to make the mentioned container work, but I was busy with other things. It would be great to have a Node in n8n to do that, right?

Unsure if my request is OK … or: it is not OK :wink:

Tried with header authentication as well.

The working curl command is:

curl [email protected] 'http://192.168.97.161:25478/upload?token=f9403fc5f537b4ab332d'

thanks in advance

Forget it: @MutedJam told me how to do that in:

So the helper container with nginx seems not to be necessary anymore: great