Lets assume you want to use this LibreOffice/OpenOffice document as your template.
Send your data via http POST request. The url: http://template2pdf.com/jobs.json Make sure that you send the following header information: Accept: application/json POST fields-payload: {'api_key'=>'<API_KEY>', 'ootemplate[attachment]'=>'@file', 'data'=> hash_with_key_values_to_search_and_replace} Example: # # api_key: # {'api_key' => '<API_KEY>', # # your template to upload: 'ootemplate[attachment]'=>'@file', # # # the key values in the 'data' section will be used for the substitution inside the template # for example: if your template contains [[example]], it will be replaced with 'test123' # 'data'=>{'key'=>'value', 'example'=>'test123', ...}, # # 'list_keys' are used to define lists that need to get into the template. # Think of invoice items as an example. # Here you see 'list_key_item' pointing to an array of key-value-hashes # Inside your template you can use '[[list_key_item]]' to indicate that you want to build a list. # Once the program sees a list key inside a table-row, it knows that this row is subject to be expanded to a list. # Please see the example invoice and how [[list_key_item]] is used in there. # Be aware that there is no limitation on 'list_key_name'. You can generate as many lists as you want. # 'data'=> {'key'=>'value', 'example'=>'test123', 'list_key_item'=>[{"item_quantity"=>"2","item_amount"=>"90,00 USD",...}, {"item_quantity"=>"1","item_amount"=>"49,99 USD",...}, {"item_quantity"=>"1","item_amount"=>"8,98 USD",...}] } On success, the server will return with HTTP STATUS CODE 201 (create). On error, the server will return an error description in the body. If you receive a 201 response to your request, parse the returned headers for the 'Location'. Wait a few seconds, to give the pdf-generator a bit time to run. Then issue a normal HTTP GET request to that location. If it returns with HTTP STATUS CODE 200, save to body as pdf file. If the pdf is not yet ready, the system will return with a HTTP STATUS CODE 503 and ask you to refresh the resource. If there was an error during pdf creation, you will get an HTTP STATUS CODE 4XX/5XX (except 503) with an explanation of the error inside the body.
# this does the following: # submit the data and template for the job # get the location where the pdf file will be from the 'Location' part of the returned header # wait some seconds to be sure that the file is generated # (if not you need to follow redirects until it appears) # and then download the pdf url=$(curl -i -F "ootemplate[attachment]=@example_invoice_template.odt;type=application/vnd.oasis.opendocument.text" \ -H "Accept: application/json" \ -X POST \ -F 'api_key=<API_KEY>'\ -F 'data[invoice_id]=12345'\ -F 'data[invoice_date]=31.02.2050'\ -F 'data[user_company_name]=Taco-Tools'\ -F 'data[user_salut]=Mr'\ -F 'data[user_first]=Larry'\ -F 'data[user_last]=Hickup'\ -F 'data[user_street]=Examplestreet'\ -F 'data[user_city]=Crazytown'\ -F 'data[user_zip]=54321'\ -F 'data[user_country]=Flatland'\ -F 'data[sales_name]=Sven'\ -F 'data[sales_email]=sven@test.com'\ -F 'data[amount_total]=$64.00'\ -F 'data[amount_tax]=$0.00'\ -F 'data[tax]=0%'\ -F 'data[freetext]=no comment'\ -F 'data[list_key_item][][item_no]=482'\ -F 'data[list_key_item][][item_quantity]=2'\ -F 'data[list_key_item][][item_amount]=$30.00'\ -F 'data[list_key_item][][item_amount_total]=$60.00'\ -F 'data[list_key_item][][item_title]=Tacos'\ -F 'data[list_key_item][][item_no]=692'\ -F 'data[list_key_item][][item_quantity]=1'\ -F 'data[list_key_item][][item_amount]=$4.00'\ -F 'data[list_key_item][][item_amount_total]=$4.00'\ -F 'data[list_key_item][][item_title]=Taco-Adapter'\ "http://template2pdf.com/jobs.json" |grep Location|sed 's/Location://g'|sed 's/\r//g'); \ sleep 3; \ curl -L --retry 10 $url > example_output.pdf;
array( array("no"=>'482',"quantity"=>"2","amount"=>"$30,00","amount_total"=>"$60.00","title"=>"Tacos"), array("no"=>'692',"quantity"=>"1","amount"=>"$4.00","amount_total"=>"4.00","title"=>"Taco-Adapter"))); # 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.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'); $lists = array('item'=>array( array("no"=>'482',"quantity"=>"2","amount"=>"$30,00","amount_total"=>"$60.00","title"=>"Tacos"), array("no"=>'692',"quantity"=>"1","amount"=>"$4.00","amount_total"=>"4.00","title"=>"Taco-Adapter"))); $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.odt" # output_filename = './example_output.pdf' # normal_key_values = { 'name'=>'Sven', # 'email'=>'sven@beastiebytes.com', # 'amount_total'=>'234.23 USD', # 'amount_tax'=>'0%', # 'pay_day'=>'today', # 'freetext'=>'no comment', # 'invoice_id'=>'2342', # 'invoice_date'=>'xmas', # 'user_name'=>'Jane Doe', # 'user_street'=>'Mainstreet', # 'user_city'=>'Berlin'} # lists = { 'item'=>[ {'no'=>'482','title'=>'Tacos','amount'=>'$30.00','quantity'=>'2','amount_total'=>'$60.00'}, # {'no'=>'692','title'=>'Taco-Adapter','amount'=>'$4.00','quantity'=>'1','amount_total'=>'$4.00'}], # '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 api_location = "http://template2pdf.com/" api_key = "<API_KEY>" input_filename = "example_invoice_template.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'} lists = { 'item'=>[ {'no'=>'482','title'=>'Tacos','amount'=>'$30.00','quantity'=>'2','amount_total'=>'$60.00'}, {'no'=>'692','title'=>'Taco-Adapter','amount'=>'$4.00','quantity'=>'1','amount_total'=>'$4.00'}]} 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 # 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.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[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][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') ]) 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