Nice and easy PDF-generating

August 10th, 2008

Problem

My client (logistics) has that old form handed out to every driver which needs have the address and values of collected items on it. Since this was done by the clients' client by hand and submittet via fax before, re-implementing the business logic included the output of that form in print quality with data from the database. Also, the form should be printable out of the web application besides normal handling of the business logic in RHTML-templates. Since all PDF-libraries available are currently not capable (please correct me if I'm wrong) of working with existing documents (forms or docs with blanks to fill out), I didn't really want to re-create the form vector-by-vector and pixel-by-pixel.

Solution

I decided to make a high-resolution image of the original form, blank all the space in which dynamic content was to be inserted and use that image as the background for the new form. Inserting values is done by simply specifiying coordinates. This turned out to be quite productive...

Prerequisites

I came across many libraries but decided to stick with PDF-Writer by Austin Ziegler. You'll need to install it as a gem by issuing a

sudo gem install pdf-writer

or any other way.

Generating the picture

Fortunately the client was able to provide me with a fairly high-res PSD-version of the original form (which was used at the printing facility) and I only had to figure out the correct dimensions and resolutions. Since I use DIN-A4 format in Europe, I needed to cut out a 210 × 297 millimeter chunk out of the PSD to fit into the PDF. That didn't work that well as it resulted in various ugly resizing errors.

Then I went with points, which are actually used as measurement units with PDF-Writer and cut out 595 x 837 pts which blended in successfully. You might just want to try different combinations of resolution and DPI values for your picture as it naturally hits on the outputs filesize.

I went on fine with 1785 x 2511 pts with 300 DPI to be scaled down to a width of 595 pts.

Creating the PDF in the model class

Implementing output is done by simply defining a method in the model class. The following example includes the output of three attributes in different styles and with charset conversion from oracle-something to utf8:

require 'pdf/writer'

class Mymodel < ActiveRecord::Base
  ... # your methods

  def to_pdf
    pdf = PDF::Writer.new(:paper => "A4")
    pdf.select_font("Helvetica", { :encoding => "WinAnsiEncoding" })
    pdf.add_image_from_file(
      "#{RAILS_ROOT}/lib/your_background_picture.png", 0, 0, width=595.28)

    pdf.add_text(62,777, "<i>#{Iconv.conv('ISO-8859-1', 'utf-8', self.attribute1)}</i>", size = 8)
    pdf.add_text(62,767, "<b>#{Iconv.conv('ISO-8859-1', 'utf-8', self.attribute2)}</b>", size = 8)
    pdf.add_text(62,757, Iconv.conv('ISO-8859-1', 'utf-8', self.attribute3), size = 8)

    return pdf
  end
end

Outputting the PDF in the controller

You'll just need to define a PDF-filetype in /config/initializers/mime-types.rb like

Mime::Type.register "application/pdf", :pdf

To output a pdf on-the-fly, use the following example as a starting point:

class Mycontroller < ApplicationController
  ... your methods

  def show        
    respond_to do |f|
      f.html { render :action => 'show' }
      f.pdf { send_data @model_instance.to_pdf, :filename => "#{@model_instance.id}.pdf", :type => 'application/pdf' }
    end
  end

  ... your methods
end

Result

Scan in an empty form you'd like to automate, resize and manipulate the image, use as background, fill in values, render to user, done

So I upgraded my ruby version from 1.8.5 to 1.8.6 (I don't feel like going into why I upgraded so late).

And my gems broke. So I followed my own advice in my former post on the subject and purged rubygems and reinstalled them from source.

Then sqlite wouldn't work.

So I deleted /home/user/.gem/source_cache and the source_cache that was listed under GEM_PATH when I ran: gem env

Sqlite still wasn't recognized.

So I ensured I had the following libraries via apt-get: libyaml-ruby libzlib-ruby libdrb-ruby liberb-ruby rdoc

I also got nothing but errors when I ran: sudo gem install sqlite-ruby

So I ran: sudo dpkg --purge sqlite3

And then I could finally install sqlite-ruby gem with: sudo gem install sqlite-ruby

And the opening page of rails identifies all my systems in my environment.

And which sqlite3 is currently returning /usr/local/bin/sqlite3

Note: I installed sqlite originally with the following commands:
tar zxvf sqlite-3.5.4.tar.gz
cd sqlite-3.5.4
./configure --prefix=/usr/local
make
sudo make install

So let's see what happens when I reboot.

/me crosses fingers

So reboot is successful. And at this point all seems right in my environment. So far.

After an interesting conversation with a friend, we came upon the idea of a gem that updates ruby. That would be too sweet. If anybody finds/writes it, let me know when you need a beta-tester.

:)
Anita.

Post-Conf Twilight Zone

June 8th, 2008

I have been talking with my friends old and new from RailsConf and it isn't just me lost in the Twilight Zone. Quite a few people are having difficulty returning to their normal energy levels after the conference.

So I thought I would share some info that I find helpful on the topic of re-couping energy.

The two dietary supplements I find most helpful to get energy back quickly are B vitamins and essential fatty acids (EFA's).

B Vitamins (also known as B Vitamin Complex)

They are water soluble; means you excrete what you don't need. Your body doesn't store B Vitamins so you need to have a constant supply in your diet. B Vitamins are used up more quickly when the body is stressed; like lack of sleep, changes in atmospheric pressure (like flying), changes in routine.

When you lack B Vitamins, sleep doesn't leave you refreshed. You still feel tired after sleep. Adding B Vitamins to your diet shows a noticeable improvement in energy levels, if low B Vitamin levels were a contributing factor to low energy levels.

Sources of B Vitamins

From:http://en.wikipedia.org/wiki/Vitamin_B

Different B vitamins come from different natural sources, such as potatoes, bananas, lentils, chilli peppers, tempeh, liver oil, liver, turkey, tuna, Nutritional yeast (or brewer's yeast) and molasses. Marmite and Vegemite bill themselves as "one of the world's richest known sources of vitamin B". As might be expected, due to its high content of brewer's yeast, beer is a source of B vitamins[7], although this may be less true for filtered beers[8]and the alcohol in beer impairs the body's ability to activate vitamins.

Essential Fatty Acids

These are fats that your body needs and can't produce itself.

They again get used up in situations when you body experiences stress because they are the building blocks of neurotransmitters which are the conduit for system regulation. In situations when the body works hard to regulate itself (like changing time zones or acclimatizing to a different environment) the body uses a lot of neurotransmitters so the essential fatty acids get used up quickly and the body needs more raw material.

Sources of Essential Fatty Acids

From:http://goodfats.pamrotella.com/

Omega-3

Flaxseed oil (flaxseed oil has the highest linolenic content of any food), flaxseeds, flaxseed meal, hempseed oil, hempseeds, walnuts, pumpkin seeds, Brazil nuts, sesame seeds, avocados, some dark leafy green vegetables (kale, spinach, purslane, mustard greens, collards, etc.), canola oil (cold-pressed and unrefined), soybean oil, wheat germ oil, salmon, mackerel, sardines, anchovies, albacore tuna, and others.

Omega-6

Flaxseed oil, flaxseeds, flaxseed meal, hempseed oil, hempseeds, grapeseed oil, pumpkin seeds, pine nuts, pistachio nuts, sunflower seeds (raw), olive oil, olives, borage oil, evening primrose oil, black currant seed oil, chestnut oil, chicken, among many others.

Omega-9

Olive oil (extra virgin or virgin), olives, avocados, almonds, peanuts, sesame oil, pecans, pistachio nuts, cashews, hazelnuts, macadamia nuts, etc.

There are other factors as well but I thought I would keep it simple. As with any other nutritional suggestions... consult your doctor, pharmacist, health practitioner, etc. before making any changes to your health routine.

Cheers,
Anita.

Gems & Ubuntu

June 7th, 2008

The Instructions

sudo dpkg --purge rubygems
sudo dpkg --purge libgems-ruby1.8

Clean out GEM_HOME and GEM_PATH edits in .bashrc

Log out.

Log in.

Confirm installation of wget with Synaptic

cd /tmp
wget http://rubyforge.org/frs/download.php/35283/rubygems-1.1.1.tgz
tar -zxf rubygems-1.1.1.tgz
cd rubygems-1.1.1/
sudo ruby setup.rb
sudo ln -s /usr/bin/gem1.8 /usr/bin/gem

The Motivation

I'm using Ubuntu and gems were behaving in a manner that I could not tolerate.
It seems that Ubuntu's rubygems package is a tad behind the times and creates some problems, so it is better to remove the Ubuntu package and any gems you have installed using it and install the official package from rubyforge.org.
So after weeks of horrible hacks and gems working sometimes, a kind soul in irc shared the benefit of his experience.
And so I am sharing it with you. With his permission. Thank you, Scott Bronson.

Cheers,
Anita.