Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?
#!/usr/bin/env ruby
# merge_highrise_contacts.rb
# 2009 Robert Jones, Craic Computing LLC (
# Distributed under the terms of the MIT Open Source license
# This is a utility to convert a CSV dump of People and Companies from
# Highrise ( into a mailing list suitable for a Mail Merge
# with Excel/Word or Numbers/Pages (09 version)
# I create Company records with full addresses and Person records with no address
# This script performs the 'join' between the two types of record in the CSV dump file
# Highrise ought to do this for us... but until then, this script fills the gap
# 1: To create the input file, go to your Highrise account
# then -> Contacts -> Export -> Export to Excel
# 2: Then run this script:
# ./merge_highrise_contacts.rb highrise_dump.csv > mail_merge.csv
# 3: Load the file into Excel or Numbers, save as Worksheet
# and follow the Mail Merge instructions in Word or Pages
# In Numbers, you will need to designate the first line as a Header line
# The script requires that you install the 'fastercsv' gem with:
# 'sudo gem install fastercsv'
require 'rubygems'
require 'fastercsv'
# Clean up extraneous spaces and newlines in a string
def clean_up_string(string_in)
return '' if string_in.nil?
string_out =
string_out.sub!(/^\s+/, '')
string_out.sub!(/\s+$/, '')
string_out.sub!(/[\r\n]+/, ' ')
# Specify the columns to be extracted
company_cols = ['Name', 'Address - Work Street', 'Address - Work City',
'Address - Work State', 'Address - Work Zip', 'Address - Work Country' ]
person_cols = ['First name', 'Last name', 'Company']
abort "Usage: #{$0} <highrise.csv file>" unless ARGV.length == 1
companies =
people =
columns =
i = 0
FasterCSV.foreach(ARGV[0]) do |row|
# Parse out the header row to build the column map
if i == 0
j = 0
row.each do |label|
columns[label] = j
j += 1
i += 1
# Parse out Person and Company rows
if row[0] =~ /^Person/
# Build a unique key for each person
name = row[columns['Company']] + ' ' + row[columns['Last name']] + ' ' + row[columns['First name']]
people[name] =
person_cols.each do |label|
people[name] << clean_up_string(row[columns[label]])
elsif row[0] =~ /^Company/
name = row[columns['Company']]
companies[name] =
company_cols.each do |label|
field = clean_up_string(row[columns[label]])
companies[name] << "\"#{field}\""
# Link People to Company Addresses and output in CSV format
output = ['First name','Last name','Company','Street','City','State','Zip','Country']
puts output.join(",")
people.keys.sort.each do |name|
output =
output << "\"#{people[name][0]}\""
output << "\"#{people[name][1]}\""
company = people[name][2]
output.concat(companies[company]) unless companies[company].nil?
puts output.join(",")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment