Class: Anvil::PDF

Inherits:
Resources::Base show all
Defined in:
lib/anvil/resources/pdf.rb

Instance Attribute Summary collapse

Attributes inherited from Resources::Base

#attributes, #client

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Resources::Base

#==, build_from_response, create, find, #inspect, list, #method_missing, #respond_to_missing?, #to_h, #to_json, with_client

Constructor Details

#initialize(raw_data, attributes = {}, client: nil) ⇒ PDF

Returns a new instance of PDF.



7
8
9
10
# File 'lib/anvil/resources/pdf.rb', line 7

def initialize(raw_data, attributes = {}, client: nil)
  super(attributes, client: client)
  @raw_data = raw_data
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method in the class Anvil::Resources::Base

Instance Attribute Details

#raw_dataObject (readonly)

Returns the value of attribute raw_data.



5
6
7
# File 'lib/anvil/resources/pdf.rb', line 5

def raw_data
  @raw_data
end

Class Method Details

.fill(template_id:, data:, **options) ⇒ PDF

Fill a PDF template with data

Parameters:

  • template_id (String)

    The PDF template ID

  • data (Hash)

    The data to fill the PDF with

  • options (Hash)

    Additional options

Options Hash (**options):

  • :title (String)

    Optional document title

  • :font_family (String)

    Font family (default: “Noto Sans”)

  • :font_size (Integer)

    Font size (default: 10)

  • :text_color (String)

    Text color (default: “#333333”)

  • :use_interactive_fields (Boolean)

    Use interactive form fields

  • :api_key (String)

    Optional API key override

Returns:

  • (PDF)

    The filled PDF

Raises:



65
66
67
68
69
70
71
72
73
74
75
76
77
# File 'lib/anvil/resources/pdf.rb', line 65

def fill(template_id:, data:, **options)
  api_key = options.delete(:api_key)
  client = api_key ? Client.new(api_key: api_key) : self.client

  payload = build_fill_payload(data, options)
  path = "/fill/#{template_id}.pdf"

  response = client.post(path, payload)

  raise APIError, "Expected PDF response but got: #{response.content_type}" unless response.binary?

  new(response.raw_body, { template_id: template_id }, client: client)
end

.generate(data:, type: :markdown, **options) ⇒ PDF

Generate a PDF from HTML or Markdown

Parameters:

  • type (Symbol, String) (defaults to: :markdown)

    :html or :markdown

  • data (Hash, Array)

    Content data

  • options (Hash)

    Additional options

Options Hash (**options):

  • :title (String)

    Document title

  • :page (Hash)

    Page configuration

  • :api_key (String)

    Optional API key override

Returns:

  • (PDF)

    The generated PDF

Raises:



88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
# File 'lib/anvil/resources/pdf.rb', line 88

def generate(data:, type: :markdown, **options)
  api_key = options.delete(:api_key)
  client = api_key ? Client.new(api_key: api_key) : self.client

  type = type.to_s.downcase
  unless %w[html markdown].include?(type)
    raise ArgumentError, "Type must be :html or :markdown, got #{type.inspect}"
  end

  payload = build_generate_payload(type, data, options)
  path = '/generate-pdf'

  response = client.post(path, payload)

  raise APIError, "Expected PDF response but got: #{response.content_type}" unless response.binary?

  new(response.raw_body, { type: type }, client: client)
end

.generate_from_html(html:, css: nil, **options) ⇒ Object

Convenience methods for specific generation types



108
109
110
111
112
# File 'lib/anvil/resources/pdf.rb', line 108

def generate_from_html(html:, css: nil, **options)
  data = { html: html }
  data[:css] = css if css
  generate(type: :html, data: data, **options)
end

.generate_from_markdown(content, **options) ⇒ Object



114
115
116
117
118
119
120
121
122
123
124
# File 'lib/anvil/resources/pdf.rb', line 114

def generate_from_markdown(content, **options)
  data = if content.is_a?(String)
           [{ content: content }]
         elsif content.is_a?(Array)
           content
         else
           raise ArgumentError, 'Markdown content must be a string or array'
         end

  generate(type: :markdown, data: data, **options)
end

Instance Method Details

#save_as(filename, mode = 'wb') ⇒ Object

Save the PDF to a file

Raises:



13
14
15
16
17
18
19
20
# File 'lib/anvil/resources/pdf.rb', line 13

def save_as(filename, mode = 'wb')
  raise FileError, 'No PDF data to save' unless raw_data

  File.open(filename, mode) do |file|
    file.write(raw_data)
  end
  filename
end

#save_as!(filename, mode = 'wb') ⇒ Object

Save and raise on error



23
24
25
26
27
# File 'lib/anvil/resources/pdf.rb', line 23

def save_as!(filename, mode = 'wb')
  save_as(filename, mode)
rescue StandardError => e
  raise FileError, "Failed to save PDF: #{e.message}"
end

#sizeObject

Get the size in bytes



37
38
39
# File 'lib/anvil/resources/pdf.rb', line 37

def size
  raw_data&.bytesize || 0
end

#size_humanObject



41
42
43
44
45
46
47
48
49
50
# File 'lib/anvil/resources/pdf.rb', line 41

def size_human
  size_in_bytes = size
  return '0 B' if size_in_bytes.zero?

  units = %w[B KB MB GB]
  exp = (Math.log(size_in_bytes) / Math.log(1024)).to_i
  exp = units.size - 1 if exp >= units.size

  format('%.2f %s', size_in_bytes.to_f / (1024**exp), units[exp])
end

#to_base64Object

Get the PDF as a base64 encoded string



30
31
32
33
34
# File 'lib/anvil/resources/pdf.rb', line 30

def to_base64
  return nil unless raw_data

  Base64.strict_encode64(raw_data)
end