10 March 2015

前言

恢复工作驱动后,接了个需求,要execl中读取数据并保存到数据库中。以下是关于roo的学习。

备注: Roo 仅仅只是一个 读取 并解析 Excel 文档的工具,而不是可直接创建相应文档的工具。 要创建 excel 文件,需要使用 speadsheet 这个 gem 包。

解析 excel 文件,理论上其基础模型就是一个二维表。 关系模型方面,自己也不是很熟,需要加强。

正文

不想深入研究Roo,照着github官方提供的Readme,写出如下的测试代码:

require 'roo'                                   # 解析xlsx格式的文件
require 'spreadsheet'                           # 解析xls格式的文件
file = "/home/xiajian/Downloads/keyword.xlsx"
file1 = "/home/xiajian/Downloads/search.xls"    # 文件名不能包含中文
s = Roo::Excelx.new(file)
w = Roo::Spreadsheet.open file1

arr = []

3.step(s.last_column, 6).each do |x|
  arr << 4.upto(s.last_row).map{|row| s.cell(row, x) }.compact
end

5.step(s.last_column, 6).each do |x|
  arr << 4.upto(s.last_row).map{|row| s.cell(row, x) }.compact
end

arr << 2.upto(w.last_row).map { |row| w.cell("A", row ) }

arr.join(",").split(",").compact.select { |x| x != ""}  # 去掉为空子元素

# 备注,以下两条语句的功能相同,不知为何
4.upto(s.last_row).map{|row| s.cell('C',row) }.compact
4.upto(s.last_row).map{|row| s.cell(row, 'C') }.compact

解析CSV

Roo gem中解析CSV似乎有些不同(使用了不同的类 - Roo::CSV),但使用方式,与读写xls类似。以下,是一个简单的使用示例,用来统计csv文件中邮件发送的数据:

require 'roo'

readfile = "test.csv"
outfile  = "test_email.csv"
s = Roo::CSV.new readfile
o = File.new(outfile, "w+")

total_count , success_count = 0 , 0 

o.puts "状态, email地址"
2.upto(s.last_row).each do |row|
  if s.cell(row, 'C') == "tphd_all_user"
    unless s.cell(row, 'D') =~ /@example.com/
      status = s.cell(row, 'B')
      total_count += 1
      if status =~ /invalid/ 
        o.puts "#{status},#{s.cell(row, 'D')} #{s.cell(row,'E')}"
      else
        success_count += 1 if status =~ /deliver/
        o.puts "#{status},#{s.cell(row, 'D')}"
      end
    end
    # o.puts "#{s.cell(row, 'B')},#{s.cell(row, 'D')}"  unless s.cell(row, 'D') =~ /@example.com/
  end
end

o.close

注意: Roo解析的csv文件时,文件hong不能包含",否则会出现CSV::MalformedCSVError: Illegal quoting in line 11493.的错误。

备注: 网上看到,也有使用csv类库处理csv文件的解析的,以下是简单使用示例:

def get_data_from_csv
  input = "/home/xiajian/works/test/ruby/unsend.txt"
  arr = []
  CSV.foreach(input) do |row|
    p row[0]
    arr << row[0]
  end
  arr
end

后记

然后,就把关键字的事情搞定了,然后接下去搞邮件的部分。当时的我,哪知道邮件是我人生中的痛。

参考文献

  1. Roo的Readme文档
  2. CSV文档



傲娇的使用Disqus