Module: Tabular::Tables::FileReading

Included in:
Tabular::Table
Defined in:
lib/tabular/tables/file_reading.rb

Instance Method Summary collapse

Instance Method Details

#format_from(as_option, file_path) ⇒ Object



28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
# File 'lib/tabular/tables/file_reading.rb', line 28

def format_from(as_option, file_path)
  if as_option
    as_option
  else
    case File.extname(file_path)
    when ".xls"
      :xls
    when ".xlsx"
      :xlsx
    when ".txt"
      :txt
    when ".csv"
      :csv
    end
  end
end

#read(file, format = nil, sheet = nil) ⇒ Object

file : file path as String or File Assumes .txt = tab-delimited, .csv = CSV, .xls = Excel. Assumes first row is the header. Normalizes column names to lower-case with underscores. format : :csv, :txt, or :xls sheet: integer, specifies the desired worksheet of an .xls/xlsx file, 0 by default. Returns Array of Arrays



10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# File 'lib/tabular/tables/file_reading.rb', line 10

def read(file, format = nil, sheet = nil)
  file_path = to_file_path(file)
  format ||= format_from(format, file_path)

  self.rows = case format
  when :xls, :xlsx
    # Set to first sheet if undefined.
    sheet ||= 0
    read_spreadsheet file_path, format, sheet
  when :txt
    read_txt file_path
  when :csv
    read_csv file_path
  else
    raise "Cannot read '#{format}' format. Expected :xls, :xlsx, :txt, or :csv"
  end
end

#read_csv(file_path) ⇒ Object



85
86
87
88
89
90
91
92
93
# File 'lib/tabular/tables/file_reading.rb', line 85

def read_csv(file_path)
  if RUBY_VERSION < "1.9"
    require "fastercsv"
    FasterCSV.read file_path
  else
    require "csv"
    CSV.read file_path
  end
end

#read_spreadsheet(file_path, format, sheet) ⇒ Object



58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
# File 'lib/tabular/tables/file_reading.rb', line 58

def read_spreadsheet(file_path, format, sheet)
  require "roo"

  if format == :xls
    require "roo-xls"
    excel = ::Roo::Excel.new(file_path)
  else
    excel = ::Roo::Excelx.new(file_path)
  end

  # Row#to_a coerces Excel data to Strings, but we want Dates and Numbers
  data = []
  excel.sheet(sheet).each do |excel_row|
    data << excel_row.inject([]) { |row, cell| row << cell; row }
  end
  data
end

#read_txt(file_path) ⇒ Object



76
77
78
79
80
81
82
83
# File 'lib/tabular/tables/file_reading.rb', line 76

def read_txt(file_path)
  require "csv"
  if RUBY_VERSION < "1.9"
    ::CSV.open file_path, "r", "\t"
  else
    CSV.read file_path, col_sep: "\t"
  end
end

#to_file_path(file) ⇒ Object



45
46
47
48
49
50
51
52
53
54
55
56
# File 'lib/tabular/tables/file_reading.rb', line 45

def to_file_path(file)
  file_path = case file
  when File
     file.path
  else
    file
  end

  raise "Could not find '#{file_path}'" unless File.exist?(file_path)

  file_path
end