Advanced Features:



Your final template can be stored on the server for easy and quick access. If changes are made to the template, you simply upload the new version.
You can do that either with your browser or via API call:

API-Example: Uploading a template

  • Send an LibreOffice/OpenOffice (application/vnd.oasis.opendocument.text) document as payload to the server via http POST request.
    
    The url:
    
    http://template2pdf.com/templates.json?api_key=<API_KEY>
                
    (Your api-key is attached as parameter.)
    
    Make sure:
    * The field name for the Office document is: 'ootemplate[attachment]'
    * The content type for that multipart attachment is set to 'application/vnd.oasis.opendocument.text'
    
    On success you will receive something like this:
    Status-Code: 201 (created)
    Content-Type: application/json; charset=utf-8
    {"key":"fc1110fd9fe2fdfe87e019e9fb2ba59d"}
    
    On error you would get something like this:
    Status-Code: 422
    Content-Type: application/json; charset=utf-8
    {"attachment_content_type":["file must be of filetype .odt (application/vnd.oasis.opendocument.text)"]}
          
                    
  • download upload.bash

    curl -F "ootemplate[attachment]=@example_invoice_template.odt;type=application/vnd.oasis.opendocument.text" \
         -X POST "http://template2pdf.com/templates.json?api_key=<API_KEY>"  
    
    
    
    On success you will receive something like this:
    Status-Code: 201 (created)
    Content-Type: application/json; charset=utf-8
    {"key":"fc1110fd9fe2fdfe87e019e9fb2ba59d"}
    
    On error you would get something like this:
    Status-Code: 422
    Content-Type: application/json; charset=utf-8
    {"attachment_content_type":["file must be of filetype .odt (application/vnd.oasis.opendocument.text)"]}
    
                    
  • download upload.php

    '@'.$file_name_with_full_path.';type=application/vnd.oasis.opendocument.text');
      $ch = curl_init();
      curl_setopt($ch, CURLOPT_URL,$target_url);
      curl_setopt($ch, CURLOPT_POST,1);
      curl_setopt($ch, CURLOPT_POSTFIELDS, $post);
      curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
      //curl_setopt($ch, CURLOPT_VERBOSE, 1);
      $result=curl_exec ($ch);
      $httpCode = (int) curl_getinfo($ch, CURLINFO_HTTP_CODE); 
      curl_close ($ch);
      if ($httpCode == 201) {
        $hash = json_decode($result,true);
        print "\nSuccess\nThis is your template key:\n".$hash['key']."\n\n";
      } else {
        print "\nAn error occured.\nCode: ".$httpCode."\n";
        print_r($result."\n\n");
      }
    ?>
    
                    
  • download upload.rb

    #! /usr/bin/ruby
    require 'rubygems'
    require 'curb'
    require 'json'
    url = 'http://template2pdf.com/templates.json?api_key=<API_KEY>'
    c = Curl::Easy.new(url)
    c.multipart_form_post = true   
    field = Curl::PostField.file('ootemplate[attachment]', "example_invoice_template.odt")
    field.content_type= "application/vnd.oasis.opendocument.text"
    c.http_post(field)
    if c.response_code.to_i == 201
      hash = JSON.parse(c.body_str.to_s)
      puts "\nSuccess\nThis is your template key:\n"+hash['key'].to_s+"\n\n";
    else
      puts "\nAn error occured.\nCode: "+c.response_code.to_s+"\n";
      puts c.body_str.to_s+"\n\n"
    end
    
    
                    
  • download upload.py

    #! /usr/bin/env python
    import pycurl
    import StringIO
    import simplejson
    c = pycurl.Curl()
    b = StringIO.StringIO()
    pf = [('ootemplate[attachment]', (pycurl.FORM_FILE, 'example_invoice_template.odt', pycurl.FORM_CONTENTTYPE, "application/vnd.oasis.opendocument.text"))]
    c.setopt(c.URL, 'http://template2pdf.com/templates.json?api_key=<API_KEY>')
    c.setopt(c.HTTPPOST, pf)
    #c.setopt(c.VERBOSE, 1)
    c.setopt(pycurl.WRITEFUNCTION, b.write)
    c.perform()
    result = b.getvalue()
    if c.getinfo(pycurl.HTTP_CODE)==201:
      xhash = simplejson.loads(result);
      print "\nSuccess\nThis is your template key:\n"+xhash['key']+"\n\n";
    else:
      print "\nAn error occured.\nCode: "+str(c.getinfo(pycurl.HTTP_CODE))+"\n";
      print result+"\n\n"
    b.close()
    c.close() 
    
    
    
                    

Lets say the API returns "example-secret-template-key" as key for your uploaded template.

Now you can generate pdf-documents with your existing template:

API-Example: Generating a pdf from an existing template

  • Send the json encoded payload to the server via http POST request.
    
    The url:
    
    http://template2pdf.com/jobs.json?api_key=<API_KEY>"
    
    (Your api-key is attached as parameter.)
    
    Make sure that you send the following header information:
    
    Accept: application/json
    Content-Type: application/json
    
    JSON-payload:
    
    {'key'=>'reference to your template',
     'data'=> hash_with_key_values_to_search_and_replace}
    
    Example:
    #
    # key references the desired template:          
    #
     {'key' => 'example-secret-template-key',   
    #
    # 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.
                      
                    
  • download templatejob.bash

    # this does the following:
    # submit the data 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 -H "Content-Type: application/json" \
            -H "Accept: application/json" \
            -X POST \
            -d '{"key":"example-secret-template-key","data":{"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","list_key_item":[{"item_no":"482","item_quantity":"2","item_amount":"$30.00","item_amount_total":"$60.00","item_title":"Tacos"},{"item_no":"692","item_quantity":"1","item_amount":"$4.00","item_amount_total":"$4.00","item_title":"Taco-Adapter"}]}}'\
            "http://template2pdf.com/jobs.json?api_key=<API_KEY>" |grep Location|sed 's/Location://g'|sed 's/\r//g'); \
            sleep 3; \
            curl -L --retry 10 $url > example_output.pdf;
    
    
                    
  • download templatejob.php

     'example-secret-template-key',
                'data'=>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',
                           'list_key_item'=>array(
                                        
                                          array("item_no"=>'482',"item_quantity"=>"2","item_amount"=>"$30,00","item_amount_total"=>"$60.00","item_title"=>"Tacos"),
                                          array("item_no"=>'692',"item_quantity"=>"1","item_amount"=>"$4.00","item_amount_total"=>"4.00","item_title"=>"Taco-Adapter")
    
                                                  )
                          )
                );
                
    $target_url = "http://template2pdf.com/jobs.json?api_key=<API_KEY>";
    $json_string = json_encode($big_hash);
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_HTTPHEADER, array(
        'Accept: application/json',
        'Content-Type: application/json'
        ));
    curl_setopt($ch, CURLOPT_HEADER, 1);
    curl_setopt($ch, CURLOPT_URL,$target_url);
    curl_setopt($ch, CURLOPT_POST,1);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $json_string);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    //curl_setopt($ch, CURLOPT_VERBOSE, 1);
    $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 != ''){
        print "found location\n";
        for($i=0;$i<10;$i++){
          print "try fetch #".$i."\n";
          $return_code = fetch_pdf($location);
          if($return_code == 200){
            break;
          }
          sleep(1+($i*$i*$i));
        }
        if($return_code == 200){
          print "example_output.pdf created\n";
        
        } else if($return_code == 503){
          print "\n";
          print "Document is not yet ready. Please try to reload in a few minutes:\n";
          print $location;
          print "\n";
        } else {
          print "\nAn error occured.\nCode: ".$return_code."\n";
        }
      }
    } else {
      print "\nAn error occured.\nCode: ".$httpCode."\n";
      print_r($response."\n\n");
    }
                
    ?>
    
                    
  • download templatejob.rb

    #! /usr/bin/ruby
    require 'rubygems'
    require 'curb'
    require 'json'
    
    
    def fetchit(new_location_url)
      puts new_location_url
      puts ""  
      c = Curl::Easy.http_get(new_location_url) do |curl|
        curl.follow_location=true
        curl.max_redirects = 20
      end
      if c.response_code.to_i == 200
        File.open('./example_output.pdf', "wb") do |file|
          file.write(c.body_str)
        end
      end
      return c.response_code.to_i
    end
    
    
    
    
    big_hash = {'key' => 'example-secret-template-key',
                'data'=>{'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',
                           'list_key_item'=>[{'item_no'=>'482','item_title'=>'Tacos','item_amount'=>'$30.00','item_quantity'=>'2','item_amount_total'=>'$60.00'},
                                             {'item_no'=>'692','item_title'=>'Taco-Adapter','item_amount'=>'$4.00','item_quantity'=>'1','item_amount_total'=>'$4.00'} ]
                          }
                } 
    
    json_string = big_hash.to_json()
    
    c = Curl::Easy.http_post("http://template2pdf.com/jobs.json?api_key=<API_KEY>", json_string) do |curl|
          curl.headers['Accept'] = 'application/json'
          curl.headers['Content-Type'] = 'application/json'
        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"]
      puts "job created"
      puts "sleeping 2 seconds to give converter enough time"
      sleep 2
      puts "trying to fetch pdf"
      res = 0
      10.times do |i|
        puts "try: #"+i.to_s
        res = fetchit(new_location_url)
        break if res == 200 # finish on success
        break unless res == 503 # continue on redirects
        sleep 1+(i*i*i);
      end
      
      
        if res == 200
          puts "example_output.pdf created"
        elsif res == 503
          puts ""
          puts "Document is not yet ready. Please try to reload in a few minutes:"
          puts new_location_url
          puts ""
        else
          puts "\nAn error occured.\nCode: "+res+"\n";
        end
    
      
      
    else
      puts "\nAn error occured.\nCode: "+c.response_code.to_s+"\n";
      puts c.body_str.to_s+"\n\n"
    end
    
    
    
    
                    
  • download templatejob.py

    #! /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.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
    
    
    data_hash =  {'key': 'example-secret-template-key',
                  'data':{        "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",
                           "list_key_item":[ {"item_no":"482","item_quantity":"2","item_amount":"$30.00","item_amount_total":"$60.00","item_title":"Tacos"},
                                             {"item_no":"692","item_quantity":"1","item_amount":"$4.00","item_amount_total":"$4.00","item_title":"Taco-Adapter"} ]
                        }
                }  
    
    
    
    
    
    jsondata = simplejson.dumps(data_hash)
    
    c = pycurl.Curl()
    b = StringIO.StringIO()
    retrieved_headers = Storage()
    c.setopt(pycurl.HTTPHEADER, ["Content-Type: application/json"])
    c.setopt(pycurl.POST, 1)
    c.setopt(pycurl.POSTFIELDS, jsondata)
    c.setopt(c.URL, 'http://template2pdf.com/jobs.json?api_key=<API_KEY>')
    c.setopt(c.HEADERFUNCTION, retrieved_headers.store)
    #c.setopt(c.VERBOSE, 1)
    c.setopt(pycurl.WRITEFUNCTION, b.write)
    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 our example, the API should return this pdf