You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用rubyzip读取压缩包中.xlsx文件数据,无需临时解压?

解决Ruby中从Zip包内读取XLSX数据(无需临时解压)

针对Creek的解决方案

Creek支持直接传入二进制IO对象,无需提前保存文件。只需过滤出.xlsx后缀的entry,将其输入流以二进制模式传入即可:

require 'creek'
require 'zip'

Zip::File.open(file_path) do |zip_file|
  zip_file.each do |entry|
    next unless entry.name.end_with?('.xlsx')

    # 获取二进制输入流,避免编码乱码
    stream = entry.get_input_stream
    stream.set_encoding(Encoding::BINARY)

    # 用Creek解析流中的XLSX内容
    creek = Creek::Book.new stream
    creek.sheets.each do |sheet|
      sheet.rows.each do |row|
        # 按需处理每行数据
        puts row.inspect
      end
    end
  end
end

针对Roo的解决方案

Roo的Excelx类可接收IO对象,但需要用StringIO包装二进制内容来规避编码问题:

require 'roo'
require 'zip'
require 'stringio'

Zip::File.open(file_path) do |zip_file|
  zip_file.each do |entry|
    next unless entry.name.end_with?('.xlsx')

    # 读取二进制内容并包装成StringIO
    xlsx_content = entry.get_input_stream.read.force_encoding(Encoding::BINARY)
    xlsx_io = StringIO.new(xlsx_content)

    # 用Roo解析IO中的XLSX,大文件推荐用streaming模式
    xlsx = Roo::Excelx.new(xlsx_io)
    xlsx.sheets.each do |sheet_name|
      xlsx.sheet(sheet_name).each_row_streaming do |row|
        # 按需处理行数据
        puts row.map(&:value).inspect
      end
    end
  end
end

核心注意事项

  • 必须确保流以二进制编码处理,这是解决乱码问题的关键。
  • 处理大文件时,优先使用Roo的each_row_streaming或Creek的rows方法,避免一次性加载全量数据到内存。
  • 如果你的file_path本身就是XLSX文件(而非包含XLSX的Zip包),无需手动用rubyzip处理——Roo和Creek内部已经实现了XLSX的Zip结构解析,直接调用Roo::Excelx.new(file_path)或Creek::Book.new(file_path)即可。

内容的提问来源于stack exchange,提问作者sombersushi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.07 20:05:48