htmlToPdf 0.1.0 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Gemfile.lock +9 -5
- data/README.md +47 -2
- data/htmlToPdf.gemspec +6 -5
- data/lib/htmlToPdf/configuration.rb +28 -0
- data/lib/htmlToPdf/version.rb +1 -1
- data/lib/htmlToPdf.rb +61 -17
- metadata +17 -14
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: eb26af6ab6e2d50a8836366601bfd8fc14c7c4d374a3483c34e2b511d2645634
|
|
4
|
+
data.tar.gz: 901949e8b9b71ddf2eca72d7c702718710524af5b45744135267e187102fb712
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 1a8010ab65b9d32b0361b57442c0b095324eaf2222ccb98b2844723830880e60def0c5aaa32516e6d072dff911cd9a6434b33e997938c4f132820f4a47da4339
|
|
7
|
+
data.tar.gz: 5fd86086620cd34a5d1b20c1fa4e9f309d1931d04147f8ac43cb23e47020ce68dbcd0a154e06cd90a1331f309a742a342a575d5b9f9e263b3c97b3e1576609a3
|
data/Gemfile.lock
CHANGED
|
@@ -1,20 +1,24 @@
|
|
|
1
1
|
PATH
|
|
2
2
|
remote: .
|
|
3
3
|
specs:
|
|
4
|
-
htmlToPdf (0.
|
|
4
|
+
htmlToPdf (2.0.0)
|
|
5
5
|
|
|
6
6
|
GEM
|
|
7
7
|
remote: https://rubygems.org/
|
|
8
8
|
specs:
|
|
9
|
-
rake (
|
|
9
|
+
rake (13.4.2)
|
|
10
10
|
|
|
11
11
|
PLATFORMS
|
|
12
12
|
ruby
|
|
13
13
|
|
|
14
14
|
DEPENDENCIES
|
|
15
|
-
bundler
|
|
15
|
+
bundler (>= 2.4)
|
|
16
16
|
htmlToPdf!
|
|
17
|
-
rake
|
|
17
|
+
rake (>= 13.0)
|
|
18
|
+
|
|
19
|
+
CHECKSUMS
|
|
20
|
+
htmlToPdf (2.0.0)
|
|
21
|
+
rake (13.4.2) sha256=cb825b2bd5f1f8e91ca37bddb4b9aaf345551b4731da62949be002fa89283701
|
|
18
22
|
|
|
19
23
|
BUNDLED WITH
|
|
20
|
-
|
|
24
|
+
4.0.6
|
data/README.md
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
# HtmlToPdf
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
This gem will generate pdf of the action's html requested as pdf.
|
|
4
|
+
|
|
5
|
+
Supports Rails 7.x and Rails 8.x (latest).
|
|
4
6
|
|
|
5
7
|
## Installation
|
|
6
8
|
#### Install and setup `wkhtmltopdf`. Please refer https://wkhtmltopdf.org for more details.
|
|
@@ -33,6 +35,49 @@ you can customize pdf like you can give the name and layout for the pdf.to custo
|
|
|
33
35
|
|
|
34
36
|
<%= link_to 'download', your_action_path(:format => 'pdf',:pdf_options => {title: 'pdf_name', layout: 'layout_name'}) %>
|
|
35
37
|
|
|
36
|
-
this will generate the pdf of your_action named
|
|
38
|
+
this will generate the pdf of your_action named `pdf_name.pdf` with layout `layout_name`.
|
|
37
39
|
|
|
38
40
|
one can call any action as pdf and he get the pdf file of that action's html.
|
|
41
|
+
|
|
42
|
+
customizing page padding and wkhtmltopdf options:
|
|
43
|
+
|
|
44
|
+
<%= link_to 'download', your_action_path(:format => 'pdf', :pdf_options => {
|
|
45
|
+
title: 'pdf_name',
|
|
46
|
+
layout: 'layout_name',
|
|
47
|
+
padding: '10mm',
|
|
48
|
+
wkhtmltopdf_options: {
|
|
49
|
+
orientation: 'Landscape',
|
|
50
|
+
page_size: 'A4',
|
|
51
|
+
margin_top: '15mm',
|
|
52
|
+
grayscale: true
|
|
53
|
+
}
|
|
54
|
+
}) %>
|
|
55
|
+
|
|
56
|
+
`padding` is a shorthand that sets all four margins at once. `wkhtmltopdf_options` accepts **any** option the `wkhtmltopdf` CLI supports (underscores or dashes both work, e.g. `margin_top`, `page_size`, `orientation`, `dpi`, `zoom`, `encoding`, `javascript_delay`, `disable_smart_shrinking`, ...) — see https://wkhtmltopdf.org for the full list. Boolean-style flags (e.g. `grayscale: true`) are passed as bare flags; anything else is passed as `--flag value`.
|
|
57
|
+
|
|
58
|
+
##### Security note: `pdf_options` is read from the request's query params and forwarded verbatim as CLI flags to `wkhtmltopdf`. If `your_action_path` is publicly reachable, anyone can pass arbitrary `wkhtmltopdf` flags to it. Only expose the pdf format on actions where that's acceptable, or filter `pdf_options` yourself before it reaches `html_to_pdf` (e.g. in a `before_action` that runs earlier).
|
|
59
|
+
|
|
60
|
+
## Configuration
|
|
61
|
+
|
|
62
|
+
Set gem-wide defaults in an initializer (e.g. `config/initializers/html_to_pdf.rb`):
|
|
63
|
+
|
|
64
|
+
HtmlToPdf.configure do |config|
|
|
65
|
+
# Path to the wkhtmltopdf binary. Defaults to "wkhtmltopdf" (resolved via $PATH).
|
|
66
|
+
# Useful when it's installed via the wkhtmltopdf-binary gem or a custom location.
|
|
67
|
+
config.wkhtmltopdf_path = Wkhtmltopdf.path # or an absolute path string
|
|
68
|
+
|
|
69
|
+
# Layout used when pdf_options[:layout] isn't given. Defaults to "application".
|
|
70
|
+
config.default_layout = "pdf"
|
|
71
|
+
|
|
72
|
+
# wkhtmltopdf options applied to every PDF, merged under any per-request
|
|
73
|
+
# padding/wkhtmltopdf_options. Defaults to {}.
|
|
74
|
+
config.default_options = { dpi: 300, margin_top: "10mm" }
|
|
75
|
+
|
|
76
|
+
# Directory temporary .html/.pdf files are written to. Defaults to Rails.root/tmp.
|
|
77
|
+
config.tmp_dir = Rails.root.join("tmp", "pdfs")
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
##### Make sure you have configured your `asset_host` in application's Rails environment, otherwise assets might not be loaded properly.
|
|
81
|
+
|
|
82
|
+
`config.action_controller.asset_host = "YOUR_ASSETS_HOST"`
|
|
83
|
+
|
data/htmlToPdf.gemspec
CHANGED
|
@@ -8,14 +8,15 @@ Gem::Specification.new do |spec|
|
|
|
8
8
|
spec.version = HtmlToPdf::VERSION
|
|
9
9
|
spec.authors = ["Ram Laxman Yadav"]
|
|
10
10
|
spec.email = ["yadavramlaxman@gmail.com"]
|
|
11
|
-
spec.summary = %q{
|
|
12
|
-
spec.description = %q{
|
|
13
|
-
spec.homepage = ""
|
|
11
|
+
spec.summary = %q{Render Rails controller actions to PDF using wkhtmltopdf}
|
|
12
|
+
spec.description = %q{HtmlToPdf lets any Rails controller action be downloaded as a PDF. Request the action with a PDF format and the gem renders the view exactly as the browser would, then converts it to PDF via wkhtmltopdf. Supports Rails 7.x and 8.x.}
|
|
13
|
+
spec.homepage = "https://github.com/ramlaxmanyadav/htmlToPdf"
|
|
14
14
|
spec.license = "MIT"
|
|
15
|
+
spec.required_ruby_version = ">= 3.1"
|
|
15
16
|
|
|
16
17
|
spec.files = `git ls-files -z`.split("\x0")
|
|
17
18
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
|
18
19
|
|
|
19
|
-
spec.add_development_dependency "bundler"
|
|
20
|
-
spec.add_development_dependency "rake"
|
|
20
|
+
spec.add_development_dependency "bundler", ">= 2.4"
|
|
21
|
+
spec.add_development_dependency "rake", ">= 13.0"
|
|
21
22
|
end
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
module HtmlToPdf
|
|
2
|
+
class Configuration
|
|
3
|
+
attr_accessor :wkhtmltopdf_path, :default_layout, :default_options, :tmp_dir
|
|
4
|
+
|
|
5
|
+
def initialize
|
|
6
|
+
@wkhtmltopdf_path = 'wkhtmltopdf'
|
|
7
|
+
@default_layout = 'application'
|
|
8
|
+
@default_options = {}
|
|
9
|
+
@tmp_dir = nil
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
class << self
|
|
14
|
+
attr_writer :configuration
|
|
15
|
+
|
|
16
|
+
def configuration
|
|
17
|
+
@configuration ||= Configuration.new
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def configure
|
|
21
|
+
yield(configuration)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def reset_configuration!
|
|
25
|
+
@configuration = Configuration.new
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
data/lib/htmlToPdf/version.rb
CHANGED
data/lib/htmlToPdf.rb
CHANGED
|
@@ -1,43 +1,87 @@
|
|
|
1
|
+
require "securerandom"
|
|
1
2
|
require "htmlToPdf/version"
|
|
3
|
+
require "htmlToPdf/configuration"
|
|
2
4
|
|
|
3
5
|
module HtmlToPdf
|
|
4
6
|
|
|
5
7
|
def html_to_pdf()
|
|
6
|
-
pdf_options = params[:pdf_options] ? params[:pdf_options] : {}
|
|
8
|
+
pdf_options = params[:pdf_options] ? params[:pdf_options] : {}
|
|
7
9
|
if request.format == 'application/pdf'
|
|
8
10
|
initialize_downloads(pdf_options)
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
11
|
+
_tmp_dir = HtmlToPdf.configuration.tmp_dir || File.join(Rails.root, 'tmp')
|
|
12
|
+
FileUtils.mkdir_p(_tmp_dir)
|
|
13
|
+
_unique_id = "#{Time.now.to_i}_#{SecureRandom.hex(8)}"
|
|
14
|
+
_source_file = File.join(_tmp_dir, "#{_unique_id}.html")
|
|
15
|
+
_destination_file = File.join(_tmp_dir, "#{_unique_id}.pdf")
|
|
12
16
|
_controller = ("#{controller_name}Controller").camelize.constantize.new
|
|
17
|
+
_controller.request = request
|
|
18
|
+
_controller.response = response
|
|
19
|
+
_controller.params = params
|
|
13
20
|
_controller.method(action_name).call
|
|
14
|
-
|
|
21
|
+
|
|
15
22
|
_controller.instance_variables.each do |var|
|
|
16
|
-
|
|
23
|
+
instance_variable_set(var, _controller.instance_variable_get(var))
|
|
17
24
|
end
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
_html = render_to_string(template: "#{controller_name}/#{action_name}", :layout => @layout, locals: _assigns)
|
|
25
|
+
|
|
26
|
+
_html = render_to_string(template: "#{controller_name}/#{action_name}", :layout => @layout, locals: { url: Rails.application.routes.url_helpers })
|
|
21
27
|
file_content = _html.gsub(/\\"/, "")
|
|
22
28
|
|
|
23
29
|
|
|
24
30
|
File.open(_source_file, "w+") do |f|
|
|
25
31
|
f.write(file_content)
|
|
26
32
|
end
|
|
27
|
-
system(
|
|
33
|
+
system(HtmlToPdf.configuration.wkhtmltopdf_path, *wkhtmltopdf_args, _source_file, _destination_file)
|
|
28
34
|
File.delete(_source_file) if File.exist?(_source_file)
|
|
29
|
-
send_data File.open(_destination_file, "rb") { |f| f.read }, :disposition => 'attachment'
|
|
35
|
+
send_data File.open(_destination_file, "rb") { |f| f.read }, :disposition => 'attachment', :filename => "#{sanitized_pdf_name}.pdf"
|
|
30
36
|
File.delete(_destination_file)
|
|
31
37
|
end
|
|
32
38
|
end
|
|
33
39
|
|
|
34
40
|
def initialize_downloads(pdf_options = {})
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
+
pdf_options ||= {}
|
|
42
|
+
@name = pdf_options[:title].nil? ? "#{Time.now.to_i.to_s}" : pdf_options[:title]
|
|
43
|
+
@layout = pdf_options[:layout].nil? ? HtmlToPdf.configuration.default_layout : pdf_options[:layout]
|
|
44
|
+
@wkhtmltopdf_options = build_wkhtmltopdf_options(pdf_options)
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def sanitized_pdf_name
|
|
48
|
+
@name.to_s.gsub(/[^a-zA-Z0-9_\- ]/, '').strip.presence || Time.now.to_i.to_s
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
# Merges, in increasing precedence: HtmlToPdf.configuration.default_options,
|
|
52
|
+
# pdf_options[:padding] (shorthand applied to all four margins), then
|
|
53
|
+
# pdf_options[:wkhtmltopdf_options] (any wkhtmltopdf flag, e.g. orientation:
|
|
54
|
+
# 'Landscape', page_size: 'A4', grayscale: true). Keys are dasherized so
|
|
55
|
+
# either underscore or dash form works.
|
|
56
|
+
def build_wkhtmltopdf_options(pdf_options)
|
|
57
|
+
options = dasherize_keys(HtmlToPdf.configuration.default_options)
|
|
58
|
+
|
|
59
|
+
if pdf_options[:padding].present?
|
|
60
|
+
padding = pdf_options[:padding].to_s
|
|
61
|
+
%w[margin-top margin-bottom margin-left margin-right].each { |flag| options[flag] = padding }
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
options.merge!(dasherize_keys(pdf_options[:wkhtmltopdf_options] || {}))
|
|
65
|
+
options
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def dasherize_keys(hash)
|
|
69
|
+
hash.each_with_object({}) { |(key, value), acc| acc[key.to_s.tr('_', '-')] = value }
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
# Query-string values arrive as strings (e.g. grayscale: true serializes to
|
|
73
|
+
# "true" in a link_to href and comes back as that literal string), so plain
|
|
74
|
+
# booleans aren't enough to detect a falsy/truthy flag.
|
|
75
|
+
FALSEY_VALUES = [nil, false, '', '0', 'false', 'off'].freeze
|
|
76
|
+
TRUTHY_FLAG_VALUES = [true, 'true'].freeze
|
|
77
|
+
|
|
78
|
+
def wkhtmltopdf_args
|
|
79
|
+
(@wkhtmltopdf_options || {}).each_with_object([]) do |(flag, value), args|
|
|
80
|
+
normalized = value.is_a?(String) ? value.downcase : value
|
|
81
|
+
next if FALSEY_VALUES.include?(normalized)
|
|
82
|
+
|
|
83
|
+
args << "--#{flag}"
|
|
84
|
+
args << value.to_s unless TRUTHY_FLAG_VALUES.include?(normalized)
|
|
41
85
|
end
|
|
42
86
|
end
|
|
43
87
|
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: htmlToPdf
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 2.0.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Ram Laxman Yadav
|
|
8
|
-
autorequire:
|
|
8
|
+
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date:
|
|
11
|
+
date: 2026-07-11 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: bundler
|
|
@@ -16,29 +16,31 @@ dependencies:
|
|
|
16
16
|
requirements:
|
|
17
17
|
- - ">="
|
|
18
18
|
- !ruby/object:Gem::Version
|
|
19
|
-
version: '
|
|
19
|
+
version: '2.4'
|
|
20
20
|
type: :development
|
|
21
21
|
prerelease: false
|
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
|
23
23
|
requirements:
|
|
24
24
|
- - ">="
|
|
25
25
|
- !ruby/object:Gem::Version
|
|
26
|
-
version: '
|
|
26
|
+
version: '2.4'
|
|
27
27
|
- !ruby/object:Gem::Dependency
|
|
28
28
|
name: rake
|
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
|
30
30
|
requirements:
|
|
31
31
|
- - ">="
|
|
32
32
|
- !ruby/object:Gem::Version
|
|
33
|
-
version: '0'
|
|
33
|
+
version: '13.0'
|
|
34
34
|
type: :development
|
|
35
35
|
prerelease: false
|
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
|
37
37
|
requirements:
|
|
38
38
|
- - ">="
|
|
39
39
|
- !ruby/object:Gem::Version
|
|
40
|
-
version: '0'
|
|
41
|
-
description:
|
|
40
|
+
version: '13.0'
|
|
41
|
+
description: HtmlToPdf lets any Rails controller action be downloaded as a PDF. Request
|
|
42
|
+
the action with a PDF format and the gem renders the view exactly as the browser
|
|
43
|
+
would, then converts it to PDF via wkhtmltopdf. Supports Rails 7.x and 8.x.
|
|
42
44
|
email:
|
|
43
45
|
- yadavramlaxman@gmail.com
|
|
44
46
|
executables: []
|
|
@@ -52,12 +54,13 @@ files:
|
|
|
52
54
|
- Rakefile
|
|
53
55
|
- htmlToPdf.gemspec
|
|
54
56
|
- lib/htmlToPdf.rb
|
|
57
|
+
- lib/htmlToPdf/configuration.rb
|
|
55
58
|
- lib/htmlToPdf/version.rb
|
|
56
|
-
homepage:
|
|
59
|
+
homepage: https://github.com/ramlaxmanyadav/htmlToPdf
|
|
57
60
|
licenses:
|
|
58
61
|
- MIT
|
|
59
62
|
metadata: {}
|
|
60
|
-
post_install_message:
|
|
63
|
+
post_install_message:
|
|
61
64
|
rdoc_options: []
|
|
62
65
|
require_paths:
|
|
63
66
|
- lib
|
|
@@ -65,15 +68,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
65
68
|
requirements:
|
|
66
69
|
- - ">="
|
|
67
70
|
- !ruby/object:Gem::Version
|
|
68
|
-
version: '
|
|
71
|
+
version: '3.1'
|
|
69
72
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
70
73
|
requirements:
|
|
71
74
|
- - ">="
|
|
72
75
|
- !ruby/object:Gem::Version
|
|
73
76
|
version: '0'
|
|
74
77
|
requirements: []
|
|
75
|
-
rubygems_version: 3.
|
|
76
|
-
signing_key:
|
|
78
|
+
rubygems_version: 3.4.10
|
|
79
|
+
signing_key:
|
|
77
80
|
specification_version: 4
|
|
78
|
-
summary:
|
|
81
|
+
summary: Render Rails controller actions to PDF using wkhtmltopdf
|
|
79
82
|
test_files: []
|