使用rubyzip解压后提取excel数据



我正试图从压缩的。xlsx文件中获得电子表格数据。我使用rubyzip来访问zip文件

的内容
Zip::File.open(file_path) do |zip_file|
zip_file.each do |entry|
*process entry*
end
end

我的问题是rubyzip给出了一个Zip::Entry对象,其中,我不能得到像roocreek宝石的工作。

我做过类似的事情,但使用的是。csv文件。这就像CSV.parse(entry.get_input_stream.read)一样简单。但是,当在.xlsx文件上使用它时,它只是给了我一个编码的乱码字符串。

我已经环顾四周,我得到的最接近的答案是暂时提取文件,但我想避免这样做,因为文件可以变得相当大。

有人有什么建议吗?提前谢谢。

所以你需要做的是将流转换成Roo可以理解的IO对象。

判断传递给Roo::Spreadsheet.open的对象是否为"流";Roo使用如下方法:

def is_stream?(filename_or_stream)
filename_or_stream.respond_to?(:seek)
end

因为Zip::InputStream不响应seek,所以你不能直接使用这个对象。为了解决这个问题,我们只需要一个响应seek的对象(如StringIO)

我们可以直接将read输入流放入StringIO:

stream = StringIO.new(entry.get_input_stream.read)

或者Zip库还提供了通过IOExtras模块将Zip::InputStream复制到另一个IO对象的方法,我认为这也读得相当好。

知道了以上的一切,我们可以实现如下:

Zip::File.open(file_path) do |zip_file|
zip_file.each do |entry|
# make sure Roo can handle the file (at least based on the extension)
ext = File.extname(entry.name)&.to_sym 
next unless Roo::CLASS_FOR_EXTENSION[ext]
# stream = StringIO.new(entry.get_input_stream.read)
::Zip::IOExtras.copy_stream(stream = StringIO.new, entry.get_input_stream)
spreadsheet = Roo::Spreadsheet.open(stream, extension: ext)
# process file
end
end

相关内容

  • 没有找到相关文章

最新更新