Rendering to Html to string with images

Hello Everyone,

my goal:

  • To render a html page with images and send it to api to convert it to a pdf. The html contains image.

Current Situation:

  • I am using Phoenix.View.render_to_string , to render the template to a string and then send it for conversion to pdf.
  • Dont know how to render a image in render to string. Though img src tags have been mentioned.

issue

  • don’t know how to link an image in.Phoenix.View.render_to_string
  • how to refer to the image?
    Phoenix.View.render_to_string(PCCore.DocView, "stats.html",
      account: account
    )

More Information

  • My application is standalone api application, it does not use phoenix framework as whole , so no routers.
  • I am using Bamboo.mail for sending emails
  • I am attaching report pdf to email.

This will not be an easy task. It depends a lot on the tool you are using to convert the HTML to PDF. Normally this contains an engine that will render the HTML and as such try to load the images from the src attribute on the img tags, so these will need to be disk-based, otherwise it will try to source them from a webserver. You could probably convert your images to Base64 encoded data and if the renderer supports it, you are fine.

There are several Hex packages that wrap common tools, such puppeteer or wkhtmltopdf.
Or if your HTML is static you could also go for rendering the PDF using something like pdf | Hex

1 Like

I am using online tool api2pdf.Where i send html data and gets back pdf binary.

How do i render images from disk in html.heex template without router

How do i refer to images locally in elixir? instead via the router

In that case you can’t, the remote server is not able to acces your disk.
And only if you would run a “full” server that is internet-reachable could you just refer to the images. In this case your best bet is to convert them to their data-uri.

Just read the file, convert it with Base.url_encode64 and use the correct uri format as described in the page above and put this as your src attribute.

1 Like

this solution works <img src="data:image/png;base64,base64 data" />
But in general how we refer to images locally in elixir?

This has nothing to do with Elixir, it is just the way HTML works.
The src attribute can refer to different kinds of URI.
Normally this would be a relative path on the server the page is being served from, but it can also point to a resource on another server, or on a local disk using file://, but always remember that this depends on the consumer/browser’s point of view, not the server.
So if you reference a file on disk, every visitor to that page should have the file on disk at that location.

3 Likes

so i can just do in

<img src="file:///#{path_to_project,dynamically}/apps/core/priv/static/images/logo.png">

??

No you cannot.

file:// is the protocol used to access local files. But that access is done by the server running the API you’re using. That server doesn’t have your files stored locally.

As described you can either use data uri’s. That means the server rendering your html doesn’t need to access the files, as they’re embedded in the uri.

Or you can make the files available to that server by using a differrent protocol like http:// or better https://. However that means running a webserver, which actually serves those files at the supplied urls and it also means anyone having access to the url(s) also does have access to the files. Often those constraints makes this a non-option for your usecase, but that depends on what files you reference in your pdfs.

can we use file.read to locate image locally and then render via render to string.
will this work