Take this LibreOffice/OpenOffice document as your template.
And download the following images:
To use images in your template you need to give individual names to your placeholder images. In the example template, the images are called: 'logo' and 'item_picture' You can edit the image name in OpenOffice or LibreOffice like this: * right click on the picture -> select 'Picture' -> edit the 'name' field The API call itself is no different from the normal one, with the exception that you need to encode your supplied images into base64. 'data'=>{'key'=>'value', 'example'=>'test123', 'logo'=>'iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==', ...}, Same goes for the lists: 'data'=> {'key'=>'value', 'example'=>'test123', 'list_key_item'=>[{"item_quantity"=>"2","item_amount"=>"90,00 USD",'item_logo'=>base64('picA.png'),...}, {"item_quantity"=>"1","item_amount"=>"49,99 USD",'item_logo'=>base64('picB.png'),...}, {"item_quantity"=>"1","item_amount"=>"8,98 USD",'item_logo'=>base64('picC.png'),...}] }
'12345', 'invoice_date'=>'31.02.2050', 'user_company_name'=>'Taco-Tools', 'user_salut'=>'Mr', 'user_first'=>'Larry', 'user_last'=>'Hickup', 'user_street'=>'Examplestreet', 'user_city'=>'Crazytown', 'user_zip'=>'54321', 'user_country'=>'Flatland', 'sales_name'=>'Sven', 'sales_email'=>'sven@test.com', 'amount_total'=>'$64.00', 'amount_tax'=>'$0.00', 'tax'=>'0%', 'freetext'=>'no comment', 'logo'=>Template2PdfSimple::base64_image('./l0.png')); $lists = array('item'=>array( array("no"=>'482',"quantity"=>"2","amount"=>"$30,00","amount_total"=>"$60.00", "title"=>"Tacos","picture"=>Template2PdfSimple::base64_image('./p0.png')), array("no"=>'692',"quantity"=>"1","amount"=>"$4.00","amount_total"=>"4.00", "title"=>"Taco-Adapter","picture"=>Template2PdfSimple::base64_image('./p1.png')))); # Usage: $t2p = new Template2PdfSimple($api_location,$api_key); $t2p->enable_debug(); $t2p->convert($input_filename,$output_filename,$normal_key_values,$lists); */ class Template2PdfSimple{ public function Template2PdfSimple($api_location,$api_key) { $this->api_location = $api_location; $this->api_key = $api_key; $this->debug = false; } public function enable_debug(){ $this->debug = true; } private function dprint($x){ if($this->debug){ print($x); } } public function convert($input_filename,$output_filename,$normal_key_values,$lists){ $ch = curl_init(); curl_setopt($ch, CURLOPT_URL,$this->api_location.'jobs.json'); curl_setopt($ch, CURLOPT_POST, 1); curl_setopt($ch, CURLOPT_HEADER, 1); curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 0); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); //curl_setopt($ch, CURLOPT_SSL_VERIFYPEER,false); //curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); curl_setopt($ch, CURLOPT_HTTPHEADER, array('Accept: application/json',"Content-type: multipart/form-data")); $big_hash = $this->build_fields($input_filename,$normal_key_values,$lists); curl_setopt($ch, CURLOPT_POSTFIELDS, $big_hash); $response=curl_exec ($ch); $header_size = curl_getinfo($ch, CURLINFO_HEADER_SIZE); $header = substr($response, 0, $header_size); $body = substr($response, $header_size); $httpCode = (int) curl_getinfo($ch, CURLINFO_HTTP_CODE); if ($httpCode == 201) { $location = ''; $parts = explode("\r\n",$header); foreach($parts as $part){ if(preg_match('/Location\:/',$part)){ $location = trim(str_replace('Location: ','',$part)); } } if ($location != ''){ $this->dprint("found location\n"); for($i=0;$i<10;$i++){ $this->dprint("try fetch #".$i."\n"); $return_code = $this->fetch_pdf($location); if($return_code == 200){ break; } sleep(1+($i*$i*$i)); } if($return_code == 200){ $this->dprint("example_output.pdf created\n"); } else if($return_code == 503){ $this->dprint("\n"); $this->dprint("Document is not yet ready. Please try to reload in a few minutes:\n"); $this->dprint($location); $this->dprint("\n"); } else { $this->dprint("\nAn error occured.\nCode: ".$return_code."\n"); } } } else { $this->dprint("\nAn error occured.\nCode: ".$httpCode."\n"); $this->dprint(print_r($response."\n\n")); } } private function fetch_pdf($url){ $saveto = './example_output.pdf'; $ch = curl_init ($url); curl_setopt($ch, CURLOPT_HEADER, 1); curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); //curl_setopt($ch, CURLOPT_SSL_VERIFYPEER,false); //curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); curl_setopt($ch, CURLOPT_BINARYTRANSFER,1); $raw=curl_exec($ch); $httpCode = (int) curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close ($ch); if ($httpCode == 200){ if(file_exists($saveto)){ unlink($saveto); } $fp = fopen($saveto,'x'); fwrite($fp, $raw); fclose($fp); } return $httpCode; } private function build_fields($input_filename,$normal_key_values,$lists){ $big_hash = array('api_key'=> $this->api_key, "ootemplate[attachment]" => "@".realpath($input_filename).";type=application/vnd.oasis.opendocument.text"); foreach($normal_key_values as $key => $value){ $big_hash['data['.$key.']'] = $value; } foreach($lists as $list_key => $rows){ foreach($rows as $key => $value_rows){ foreach($value_rows as $lkey => $value){ $big_hash['data[list_key_'.$list_key.'['.$key.']]['.$list_key.'_'.$lkey.']'] = $value; } } } return $big_hash; } public static function base64_image($filename){ return base64_encode(file_get_contents($filename)); } } $api_location = "http://template2pdf.com/"; $api_key = "<API_KEY>"; $input_filename = "./example_invoice_template_images.odt"; $output_filename = './example_output.pdf'; $normal_key_values = array('invoice_id'=>'12345', 'invoice_date'=>'31.02.2050', 'user_company_name'=>'Taco-Tools', 'user_salut'=>'Mr', 'user_first'=>'Larry', 'user_last'=>'Hickup', 'user_street'=>'Examplestreet', 'user_city'=>'Crazytown', 'user_zip'=>'54321', 'user_country'=>'Flatland', 'sales_name'=>'Sven', 'sales_email'=>'sven@test.com', 'amount_total'=>'$64.00', 'amount_tax'=>'$0.00', 'tax'=>'0%', 'freetext'=>'no comment', 'logo'=>Template2PdfSimple::base64_image('./l0.png')); $lists = array('item'=>array( array("no"=>'482',"quantity"=>"2","amount"=>"$30,00","amount_total"=>"$60.00", "title"=>"Tacos","picture"=>Template2PdfSimple::base64_image('./p0.png')), array("no"=>'692',"quantity"=>"1","amount"=>"$4.00","amount_total"=>"4.00", "title"=>"Taco-Adapter","picture"=>Template2PdfSimple::base64_image('./p1.png')))); $t2p = new Template2PdfSimple($api_location,$api_key); $t2p->enable_debug(); $t2p->convert($input_filename,$output_filename,$normal_key_values,$lists); ?>
#! /usr/bin/ruby ## Example usage of template2pdf api: ## Basic configuration # api_location = "http://template2pdf.com/" # api_key = "your_api_key" # input_filename = "example_invoice_template_images.odt" # output_filename = './example_output.pdf' # normal_key_values = { 'invoice_id'=>'12345', # 'invoice_date'=>'31.02.2050', # 'user_company_name'=>'Taco-Tools', # 'user_salut'=>'Mr', # 'user_first'=>'Larry', # 'user_last'=>'Hickup', # 'user_street'=>'Examplestreet', # 'user_city'=>'Crazytown', # 'user_zip'=>'54321', # 'user_country'=>'Flatland', # 'sales_name'=>'Sven', # 'sales_email'=>'sven@test.com', # 'amount_total'=>'$64.00', # 'amount_tax'=>'$0.00', # 'tax'=>'0%', # 'freetext'=>'no comment', # 'logo'=>Template2PdfSimple.base64_image('l0.png')} # lists = { 'item'=>[ {'no'=>'482','title'=>'Tacos','amount'=>'$30.00','quantity'=>'2','amount_total'=>'$60.00','picture'=>Template2PdfSimple.base64_image('p0.png')}, # {'no'=>'692','title'=>'Taco-Adapter','amount'=>'$4.00','quantity'=>'1','amount_total'=>'$4.00','picture'=>Template2PdfSimple.base64_image('p1.png')}], # 'otherlist'=>[ {'whatever'=>'product1','amount'=>'2'}, # {'whatever'=>'product2','amount'=>'4'}]} # ## Usage: # t2p = Template2PdfSimple.new(api_location,api_key) # t2p.convert(input_filename,output_filename,normal_key_values,lists) require 'rubygems' require 'curb' require 'json' require "base64" class Template2PdfSimple def initialize(api_location,api_key) @api_location = api_location @api_key = api_key @debug = true end def enable_debug @debug = true end def dputs(*args) puts args if @debug end def convert(input_filename,output_filename,normal_key_values,lists) fields = build_fields(input_filename,normal_key_values,lists) c = Curl::Easy.http_post("#{@api_location}jobs.json",fields) do |curl| curl.headers['Accept'] = 'application/json' curl.multipart_form_post = true #curl.ssl_verify_peer = false #curl.ssl_verify_host = false end if c.response_code.to_i == 201 http_response, *http_headers = c.header_str.split(/[\r\n]+/).map(&:strip) http_headers = Hash[http_headers.flat_map{ |s| s.scan(/^(\S+): (.+)/) }] new_location_url = http_headers["Location"] dputs "job created" dputs "sleeping 2 seconds to give converter enough time" sleep 2 dputs "trying to fetch pdf" res = 0 10.times do |i| dputs "try: #"+i.to_s res = fetchit(new_location_url,output_filename) break if res == 200 # finish on success break unless res == 503 # continue on redirects sleep 1+(i*i*i); end if res == 200 dputs "example_output.pdf created" elsif res == 503 dputs "" dputs "Document is not yet ready. Please try to reload in a few minutes:" dputs new_location_url dputs "" else dputs "\nAn error occured.\nCode: "+res+"\n"; end elsif c.response_code.to_i == 401 dputs "Authentication error. Please check your API key.\n"; else dputs "\nAn error occured.\nCode: "+c.response_code.to_s+"\n"; dputs c.body_str.to_s+"\n\n" end end def fetchit(new_location_url,output_filename) dputs new_location_url dputs "" c = Curl::Easy.http_get(new_location_url) do |curl| curl.follow_location=true curl.max_redirects = 20 #curl.ssl_verify_peer = false #curl.ssl_verify_host = false end if c.response_code.to_i == 200 File.open(output_filename, "wb") do |file| file.write(c.body_str) end end return c.response_code.to_i end def build_fields(input_filename,normal_key_values,lists) attachment_field = Curl::PostField.file('ootemplate[attachment]', input_filename) attachment_field.content_type= "application/vnd.oasis.opendocument.text" fields = [attachment_field] fields << Curl::PostField.content('api_key',@api_key) normal_key_values.each do |k,v| fields << Curl::PostField.content('data['+k.to_s+']',v) end lists.each do |list_key,collection| collection.each do |row| row.each do |k,v| fields << Curl::PostField.content('data[list_key_'+list_key+'][]['+list_key+'_'+k+']',v) end end end fields end def self.base64_image(filename) Base64.strict_encode64(File.open(filename, "rb").read) end end # ATTENTION, YOU NEED THE FOLLOWING FILES (or edit the code): # example_invoice_template_images.odt # l0.png # p0.png # p1.png api_location = "http://template2pdf.com/" api_key = "<API_KEY>" input_filename = "example_invoice_template_images.odt" output_filename = './example_output.pdf' normal_key_values = { 'invoice_id'=>'12345', 'invoice_date'=>'31.02.2050', 'user_company_name'=>'Taco-Tools', 'user_salut'=>'Mr', 'user_first'=>'Larry', 'user_last'=>'Hickup', 'user_street'=>'Examplestreet', 'user_city'=>'Crazytown', 'user_zip'=>'54321', 'user_country'=>'Flatland', 'sales_name'=>'Sven', 'sales_email'=>'sven@test.com', 'amount_total'=>'$64.00', 'amount_tax'=>'$0.00', 'tax'=>'0%', 'freetext'=>'no comment', 'logo'=>Template2PdfSimple.base64_image('l0.png')} lists = { 'item'=>[ {'no'=>'482','title'=>'Tacos','amount'=>'$30.00','quantity'=>'2','amount_total'=>'$60.00','picture'=>Template2PdfSimple.base64_image('p0.png')}, {'no'=>'692','title'=>'Taco-Adapter','amount'=>'$4.00','quantity'=>'1','amount_total'=>'$4.00','picture'=>Template2PdfSimple.base64_image('p1.png')}]} t2p = Template2PdfSimple.new(api_location,api_key) t2p.enable_debug t2p.convert(input_filename,output_filename,normal_key_values,lists)
#! /usr/bin/env python import pycurl import StringIO import simplejson import time import sys import re import base64 def base64_image(filename): with open(filename, "rb") as image_file: return base64.b64encode(image_file.read()) # run this in a loop until pdf is ready def fetchit(new_location_url): print new_location_url print "" curl = pycurl.Curl() buff = StringIO.StringIO() curl.setopt(pycurl.URL, new_location_url) curl.setopt(pycurl.WRITEFUNCTION, buff.write) curl.setopt(pycurl.FOLLOWLOCATION, 1) #curl.setopt(pycurl.SSL_VERIFYHOST, 0) #curl.setopt(pycurl.SSL_VERIFYPEER, 0) curl.perform() if curl.getinfo(pycurl.HTTP_CODE)==200: pdffile = open("example_output.pdf", "wb") pdffile.write(buff.getvalue()) pdffile.close() return curl.getinfo(pycurl.HTTP_CODE) class Storage: def __init__(self): self.contents = '' def store(self, buf): self.contents += buf def __str__(self): return self.contents c = pycurl.Curl() b = StringIO.StringIO() retrieved_headers = Storage() c.setopt(pycurl.HTTPHEADER, ['Accept: application/json',"Content-Type: multipart/form-data"]) c.setopt(pycurl.POST, 1) c.setopt(c.HTTPPOST, [("ootemplate[attachment]", (c.FORM_FILE, "./example_invoice_template_images.odt",c.FORM_CONTENTTYPE, "application/vnd.oasis.opendocument.text")), ('api_key','<API_KEY>'), ('data[invoice_id]','12345'), ('data[invoice_date]','31.02.2050'), ('data[user_company_name]','Taco-Tools'), ('data[user_salut]','Mr'), ('data[user_first]','Larry'), ('data[user_last]','Hickup'), ('data[user_street]','Examplestreet'), ('data[user_city]','Crazytown'), ('data[user_zip]','54321'), ('data[user_country]','Flatland'), ('data[sales_name]','Sven'), ('data[sales_email]','sven@test.com'), ('data[amount_total]','$64.00'), ('data[amount_tax]','$0.00'), ('data[tax]','0%'), ('data[freetext]','no comment'), ('data[logo]',base64_image('./l0.png')), ('data[list_key_item][0][item_no]','482'), ('data[list_key_item][0][item_quantity]','2'), ('data[list_key_item][0][item_amount]','$30.00'), ('data[list_key_item][0][item_amount_total]','$60.00'), ('data[list_key_item][0][item_title]','Tacos'), ('data[list_key_item][0][item_picture]',base64_image('./p0.png')), ('data[list_key_item][1][item_no]','692'), ('data[list_key_item][1][item_quantity]','1'), ('data[list_key_item][1][item_amount]','$4.00'), ('data[list_key_item][1][item_amount_total]','$4.00'), ('data[list_key_item][1][item_title]','Taco-Adapter'), ('data[list_key_item][1][item_picture]',base64_image('./p1.png')) ]) c.setopt(c.URL, 'http://template2pdf.com/jobs.json') c.setopt(c.HEADERFUNCTION, retrieved_headers.store) c.setopt(pycurl.WRITEFUNCTION, b.write) #c.setopt(pycurl.SSL_VERIFYHOST, 0) #c.setopt(pycurl.SSL_VERIFYPEER, 0) c.perform() result = b.getvalue() listing = str(retrieved_headers).split("\r\n") location = '' # extract location out of header: for header_element in listing: if re.match('Location:',header_element): location = header_element.split('Location: ')[1].strip() # check if job started if c.getinfo(pycurl.HTTP_CODE)==201: print "job created" print "sleeping 2 seconds to give converter enough time" time.sleep(2) print "trying to fetch pdf" res = 0 # try 10 times to load the pdf for i in range(10): # or xrange if you are on 2.X print "try: #"+str(i) res = fetchit(location) if res == 200: # finish on success break if res != 503: break # continue on redirects time.sleep (1+(i*i*i)); # nice output to know what happened: if res == 200: print "example_output.pdf created" elif res == 503: print "" print "Document is not yet ready. Please try to reload in a few minutes:" print new_location_url print "" else: print "\nAn error occured.\nCode: "+str(res)+"\n"; else: print "\nAn error occured.\nCode: "+str(c.getinfo(pycurl.HTTP_CODE))+"\n"; print result+"\n\n" b.close() c.close()
If you followed the example, the API should return this pdf