Skip to content

Commit

Permalink
by default use npm module
Browse files Browse the repository at this point in the history
  • Loading branch information
gutschilla committed Apr 16, 2019
1 parent a08ddc2 commit bca08e7
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 31 deletions.
11 changes: 10 additions & 1 deletion CHANGES.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,14 @@
# Changes
- 0.5.0
- **Got rid of Porcelain** dependency as it interferes with many builds using
plain `System.cmd/3`. Please note, that as of the documentation
(https://hexdocs.pm/elixir/System.html#cmd/3) ports will be closed but in
case wkhtmltopdf somehow hangs, nobody takes care of terminating it.
- Refactored some sections
- **Support URLs** instead of just plain HTML
- **Support for chrome-headless** for (at least for me) faster and nicer renderings.
- Since this is hopefully helpful, I rose the version to 0.5.0 even tough
the API stays consistent
- 0.4.0
- Got rid of misc_random dependency. This was here to manage between
depreciated random functions in Erlang. We go ahead using plain
Expand Down Expand Up @@ -63,7 +73,6 @@
- make paths configurable in `config/ENV.exs` as well
- add some tests (Yay!)
- better README- 0.3.0

- 0.2.0
- adding support for PDFTK to create encrypted PDFs
- **API-CHANGE** PdfGenerator.generate now returns tuple `{:ok, file_name}`
Expand Down
50 changes: 23 additions & 27 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ A wrapper for wkhtmltopdf (HTML to PDF) and PDFTK (adds in encryption) for use
in Elixir projects. If available, it will use xvfb-run (x virtual frame buffer)
to use wkhtmltopdf on systems that have no X installed, e.g. a server.

# New in 0.5.0 - farewell Porcelain, hello chrome-headless
# New in 0.5.0 - farewell Porcelain, hello chrome-headless (puppeteer)

- 0.5.0
- **Got rid of Porcelain** dependency as it interferes with many builds using
Expand All @@ -19,30 +19,29 @@ to use wkhtmltopdf on systems that have no X installed, e.g. a server.

For a proper changelog, see [CHANGES](CHANGES.md)

# System prerequisites (either wkhtmltopdf or nodejs)
# System prerequisites (either wkhtmltopdf or nodejs and maybe pdftk)

Download wkhtmltopdf and place it in your $PATH. Current binaries can be found
here: http://wkhtmltopdf.org/downloads.html
1. Run `npm install`. This requires [nodejs](https://nodejs.org), of course.
This will install a recent chromium and chromedriver to run Chrome in
headless mode and use this browser and its API to print PDFs.

**OR***

Run `npm install`. This requires [nodejs](https://nodejs.org), of course. This
will install a recent chromium and chromedriver to run Chrome in headless mode
and use this browser and its API to print PDFs.
2. Download wkhtmltopdf and place it in your $PATH. Current binaries can be
found here: http://wkhtmltopdf.org/downloads.html

* _(optional)_ To use wkhtmltopdf on systems without an X window server
installed, please install `xvfb-run` from your repository (on
Debian/Ubuntu: `sudo apt-get install xvfb`).

_(optional)_ To use wkhtmltopdf on systems without an X window server installed,
please install `xvfb-run` from your repository (on Debian/Ubuntu: `sudo apt-get
install xvfb`).
* On current (2018) Macintosh computers `/usr/X11/bin/xvfb` should be
available and is reported to do the same thing. _warning:** This is untested.
PLS report to me if you ran this successfully on a Mac.

On current (2018) Macintosh computers `/usr/X11/bin/xvfb` should be available
and is reported to do the same thing. _warning:_ This is untested. PLS report to
me if you ran this successfully on a Mac.
**AND MAYBE**

_(optional)_ For best results, download goon and place it in your $PATH. Current
binaries can be found here: https://github.com/alco/goon/releases

_(optional)_ Install pdftk via your package manager or homebrew. The
project page also contains a Windows installer
3. _(optional)_ Install pdftk via your package manager or homebrew. The project
page also contains a Windows installer

# Usage

Expand All @@ -69,27 +68,24 @@ $ iex -S mix
html = "<html><body><p>Hi there!</p></body></html>"
# be aware, this may take a while...
{ :ok, filename } = PdfGenerator.generate html, page_size: "A5"
{ :ok, pdf_content } = File.read filename
{:ok, filename} = PdfGenerator.generate(html, page_size: "A5")
{:ok, pdf_content} = File.read(filename)
# or, if you prefer methods that raise on error:
filename = PdfGenerator.generate! html
filename = PdfGenerator.generate!(html, generator: :chrome)
```

Or, pass some URL

```
url = "http://google.com"
{ :ok, filename } = PdfGenerator.generate {:url, url}, page_size: "A5"
...
PdfGenerator.generate {:url, "http://google.com"}, page_size: "A5"
```

Or, use chrome-headless

```
url = "http://google.com"
{ :ok, filename } = PdfGenerator.generate {:url, url}, page_size: "A5", renderer: :chrome
...
html_works_too = "<html><body><h1>Minimalism!"
{:ok, filename} = PdfGenerator.generate html_works_too, generator: :chrome
```

Or use the bang-methods:
Expand Down
16 changes: 13 additions & 3 deletions lib/pdf_generator.ex
Original file line number Diff line number Diff line change
Expand Up @@ -169,21 +169,31 @@ defmodule PdfGenerator do

@spec make_command(generator, opts, content, {html_path, pdf_path}) :: {path, list()}
def make_command(:chrome, options, content, {html_path, pdf_path}) do
executable = System.find_executable("chrome-headless-render-pdf")
executable_on_path = System.find_executable("chrome-headless-render-pdf")
nodejs_on_path = System.find_executable("nodejs")
js_file = Application.app_dir(:pdf_generator) <> "/../../../../node_modules/chrome-headless-render-pdf/dist/cli/chrome-headless-render-pdf.js"

{executable, executable_args} =
if options[:prefer_system_executable] && is_binary(executable_on_path) do
{executable_on_path, []}
else
{nodejs_on_path, [js_file]}
end

{width, height} = make_dimensions(options)
more_params = options[:shell_params] || []
source =
case content do
{:url, url} -> url
_html -> "file://" <> html_path
end
arguments = [
arguments = executable_args ++ [
"--url", source,
"--pdf", pdf_path,
"--paper-width", width,
"--paper-height", height,
] ++ more_params
{executable, arguments}
{executable, arguments} # |> IO.inspect()
end

def make_command(:wkhtmltopdf, options, content, {html_path, pdf_path}) do
Expand Down
12 changes: 12 additions & 0 deletions test/pdf_generator_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,18 @@ defmodule PdfGeneratorTest do
assert {:ok, "%PDF-1" <> _pdf} = @html |> PdfGenerator.generate_binary
end

test "chrome-headless" do
{:ok, temp_filename } = PdfGenerator.generate(@html, generator: :chrome, page_size: "A5")

# File should exist and has some size
file_info = File.stat! temp_filename
assert file_info.size > 0
pdf = File.read! temp_filename

# PDF header should be present
assert String.slice( pdf, 0, 6) == "%PDF-1"
end

test "generate! returns a filename" do
@html
|> PdfGenerator.generate!
Expand Down

0 comments on commit bca08e7

Please sign in to comment.