向Ruby Excel文档生成器传入数组触发write_row()错误如何解决
错误原因及修复方案
报错根因
你遇到的RuntimeError: Not an array ref in call to write_row()错误,是因为writeexcel库的write_row方法要求第二个参数必须是一维数组,而你现有代码传入的是无效的字符串,同时存在多处逻辑错误。
现有代码的核心问题
- 变量引用错误:类作用域下定义的
@array属于类实例变量,普通实例方法无法访问,且你初始化传入的data参数完全没有被使用 - 字符串插值失效:
'#{array}'使用了单引号,Ruby中单引号字符串不会解析插值语法,实际传入write_row的是纯文本字符串"#{array}",完全不符合参数要求 - 数据格式不匹配:
write_row要求传入当前行所有单元格值组成的一维数组,你传入的原始数据是哈希数组,需要先提取表头、再逐行转换为值数组 - 路径参数未生效:
create_new_workbook方法里写死了输出文件名,没有使用初始化传入的path参数
修复后代码
module Accounting module Datev module Utils class ExcelGenerator require 'writeexcel' # 该类用于生成Excel文档并保存到指定路径 # 示例用法: # d = [ # { name: 'Dima', dob: '27/02', city: 'Berlin' }, # { name: 'Conor', dob: '23/04', city: 'Berlin' }, # ] # Accounting::Datev::Utils::ExcelGenerator.new(data: d, path: '~/text.xls').call # 执行后将在home目录生成text.xls文件,内容如下 # | name | dob | city | # | Dima | 27/02 | Berlin | # | Conor | 23/04 | Berlin | # attr_reader :data, :path, :workbook, :worksheet def initialize(data:, path:) @data = data @path = path end def call return if data.empty? # 空数据直接返回避免报错 create_new_workbook add_worksheet write_new_worksheet save_file end def create_new_workbook # 处理~开头的用户目录路径,使用传入的path参数 @workbook = WriteExcel.new(File.expand_path(path)) end def add_worksheet @worksheet = workbook.add_worksheet end def write_new_worksheet # 第一行写入表头:取第一个哈希的键作为表头 headers = data.first.keys.map(&:to_s) worksheet.write_row('A1', headers) # 逐行写入数据 data.each_with_index do |row_hash, index| # 行号从2开始,因为第一行是表头 row_num = index + 1 row_values = row_hash.values worksheet.write_row(row_num, 0, row_values) end end def save_file workbook.close end end end end end
正确调用方式
和你注释里的示例用法完全一致:
d = [ { name: 'Dima', dob: '27/02', city: 'Berlin' }, { name: 'Conor', dob: '23/04', city: 'Berlin' }, ] Accounting::Datev::Utils::ExcelGenerator.new(data: d, path: '~/text.xls').call
注意:writeexcel库只支持生成xls格式的文件,不要传xlsx后缀的路径,否则生成的文件可能无法正常打开
内容的提问来源于stack exchange,提问作者cbln
相关产品推荐
相关产品推荐

