programing

루비로 XLS 및 XLSX(MS Excel) 파일을 해석하시겠습니까?

lovejava 2023. 4. 24. 21:04

루비로 XLS 및 XLSX(MS Excel) 파일을 해석하시겠습니까?

XLS 및 XLSX 파일을 해석할 수 있는 보석이 있습니까?스프레드시트와 ParseExcel은 찾았는데 둘 다 XLSX 포맷을 이해하지 못합니다.

저는 최근에 루비와 함께 엑셀 파일을 해석해야 했습니다.도서관과 옵션이 풍부해서 혼란스러워서 블로그에 글을 올렸습니다.

다음은 다양한 Ruby 라이브러리와 지원되는 기능의 표입니다.

여기에 이미지 설명 입력

하는 이 있습니다.xlsx라이브러리 비교:

지원되는 각 라이브러리에서 xlsx 파일을 읽기 위한 샘플 코드가 여기에 있습니다.

읽기의 예가 .xlsx다음과 같이 합니다.

루비XL

require 'rubyXL'

workbook = RubyXL::Parser.parse './sample_excel_files/xlsx_500_rows.xlsx'
worksheets = workbook.worksheets
puts "Found #{worksheets.count} worksheets"

worksheets.each do |worksheet|
  puts "Reading: #{worksheet.sheet_name}"
  num_rows = 0
  worksheet.each do |row|
    row_cells = row.cells.map{ |cell| cell.value }
    num_rows += 1
  end
  puts "Read #{num_rows} rows"
end

루우

require 'roo'

workbook = Roo::Spreadsheet.open './sample_excel_files/xlsx_500_rows.xlsx'
worksheets = workbook.sheets
puts "Found #{worksheets.count} worksheets"

worksheets.each do |worksheet|
  puts "Reading: #{worksheet}"
  num_rows = 0
  workbook.sheet(worksheet).each_row_streaming do |row|
    row_cells = row.map { |cell| cell.value }
    num_rows += 1
  end
  puts "Read #{num_rows} rows" 
end

시냇물

require 'creek'

workbook = Creek::Book.new './sample_excel_files/xlsx_500_rows.xlsx'
worksheets = workbook.sheets
puts "Found #{worksheets.count} worksheets"

worksheets.each do |worksheet|
  puts "Reading: #{worksheet.name}"
  num_rows = 0
  worksheet.rows.each do |row|
    row_cells = row.values
    num_rows += 1
  end
  puts "Read #{num_rows} rows"
end

simple_xlsx_simple

require 'simple_xlsx_reader'

workbook = SimpleXlsxReader.open './sample_excel_files/xlsx_500000_rows.xlsx'
worksheets = workbook.sheets
puts "Found #{worksheets.count} worksheets"

worksheets.each do |worksheet|
  puts "Reading: #{worksheet.name}"
  num_rows = 0
  worksheet.rows.each do |row|
    row_cells = row
    num_rows += 1
  end
  puts "Read #{num_rows} rows"
end

.xls 하여 파일을 작성하다spreadsheet★★★★★★★★★★★★★★★★★★:

스프레드시트

require 'spreadsheet'

# Note: spreadsheet only supports .xls files (not .xlsx)
workbook = Spreadsheet.open './sample_excel_files/xls_500_rows.xls'
worksheets = workbook.worksheets
puts "Found #{worksheets.count} worksheets"

worksheets.each do |worksheet|
  puts "Reading: #{worksheet.name}"
  num_rows = 0
  worksheet.rows.each do |row|
    row_cells = row.to_a.map{ |v| v.methods.include?(:value) ? v.value : v }
    num_rows += 1
  end
  puts "Read #{num_rows} rows"
end

이제 막 roo를 찾았습니다.그건 제 요구 사항에 부합합니다.기본 스프레드시트를 읽습니다.

roo gem은 Excel (.xls 및 .xlsx)에 매우 적합하며 현재 활발히 개발 중입니다.

구문이 훌륭하지도 않고 루비같지도 않다는 것에 동의합니다.그러나 다음과 같은 방법으로 이를 쉽게 달성할 수 있습니다.

class Spreadsheet
  def initialize(file_path)
    @xls = Roo::Spreadsheet.open(file_path)
  end

  def each_sheet
    @xls.sheets.each do |sheet|
      @xls.default_sheet = sheet
      yield sheet
    end
  end

  def each_row
    0.upto(@xls.last_row) do |index|
      yield @xls.row(index)
    end
  end

  def each_column
    0.upto(@xls.last_column) do |index|
      yield @xls.column(index)
    end
  end
end

노코기리를 사용한 개울을 이용하고 있습니다.빠르다.Macbook Air의 21x11250 xlsx 테이블에서 8.3초 사용.루비 1.9.3+로 작동.각 행의 출력 형식은 행 및 열 이름을 셀 컨텐츠에 해시하는 것입니다. {"A1"=> "cell", "B1"=> "another cell"} 해시는 키가 원래 열 순서에 있음을 보장하지 않습니다.https://github.com/pythonicrubyist/creek

둔갑은 노코기리를 사용하는 또 다른 훌륭한 것입니다.엄청 빨라요.Macbook Air의 21x11250 xlsx 테이블에서 6.7초 사용.루비 2.0.0+로 동작.각 행의 출력 형식은 배열입니다.[ " cell " , " another cell " ] https://github.com/thirtyseven/dullard

앞서 말한 simple_xlsx_simple은 훌륭하고 조금 느립니다.Macbook Air의 21x11250 xlsx 테이블에서 91초를 사용했습니다.루비 1.9.3+로 작동.각 행의 출력 형식은 배열입니다.[ " cell " , " another cell " ] https://github.com/woahdae/simple_xlsx_reader

또 다른 흥미로운 것은 황소자리이다.nokogiri의 DOM이나 SAX 파서보다 빠를 것으로 생각되는 ox의 SAX 파서를 사용하고 있습니다.매트릭스를 출력한 것으로 추정됩니다.나는 그것을 작동시킬 수 없었다.또, 루비집과의 의존 관계도 몇 가지 있었습니다.추천하지 않겠습니다.

결론적으로, 크리크는 좋은 선택인 것 같다.다른 게시물에서는 simple_xlsx_parser의 퍼포먼스가 비슷하기 때문에 권장하고 있습니다.

더러움이 오래되어 오류가 발생하거나 문제가 있기 때문에 권장하는 대로 제거.

최신 라이브러리를 찾는 경우 스프레드시트(http://spreadsheet.rubyforge.org/GUIDE_txt.html를 참조하십시오.XLSX 파일 지원 여부는 알 수 없지만, 현재 개발 중인 것으로 보아 XLSX 파일 지원인 것 같습니다(Windows 또는 Office가 아니기 때문에 테스트할 수 없습니다.

현시점에서는 roo가 다시 좋은 선택인 것 같습니다.XLSX를 지원하며, 사용 방법만으로 (일부) 반복이 가능합니다.times핸드폰에 접속할 수 있습니다.★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★

은, 「RubyXL」의 「RubyXL」의 「RubyXL」을 할 수 .extract_data쉽게 반복할 수 있는 2D 데이터 어레이를 제공합니다.

또는 Windows에서 XLSX 파일을 사용하려는 경우 Word 및 Excel에서 제공하는 OLE 개체와 인터페이스할 수 있는 Ruby의 Win32OLE 라이브러리를 사용할 수 있습니다.그러나 @PanagiotisKanavos가 코멘트에서 언급했듯이 여기에는 몇 가지 큰 단점이 있습니다.

  • Excel을 설치해야 합니다.
  • 각 문서에 대해 새로운 Excel 인스턴스가 시작됩니다.
  • 메모리와 기타 자원 소비량은 단순한 XLSX 문서 조작에 필요한 양보다 훨씬 많습니다.

단, Excel을 사용하지 않고 XLSX 파일을 로드한 후 이를 통해 액세스할 수 있습니다.반복을 지원하는지 모르겠지만, 엑셀용 Microsoft OLE API 풀이기 때문에 제공된 메서드를 중심으로 구축하는 것은 그리 어렵지 않다고 생각합니다.여기 매뉴얼이 있습니다.http://support.microsoft.com/kb/222101 여기 장식이 있습니다.http://www.ruby-doc.org/stdlib-1.9.3/libdoc/win32ole/rdoc/WIN32OLE.html

다시 말씀드리지만, 선택지는 별로 좋아 보이지 않지만, 유감스럽게도 그 밖에는 별로 없습니다.블랙박스 형식의 파일을 해석하는 것은 어렵습니다.그리고 그것을 깨는 데 성공한 소수의 사람들은 눈에 잘 띄지 않았다.Google Docs는 비공개 소스이며 LibreOffice는 수천 개의 harry C++ 행입니다.

지난 몇 주 동안 스프레드시트와 루비XL 둘 다 열심히 작업했는데 둘 다 훌륭한 도구입니다.그러나 둘 다 겪는 한 가지 문제는 실제로 유용한 것을 구현하기 위한 예가 부족하다는 것입니다.현재 크롤러를 만들고 있으며 xlsx 파일 및 스프레드시트를 사용하여 xls를 해석하고 있습니다.아래의 코드가 도움이 되어 이러한 툴이 얼마나 효과적인지 알 수 있기를 바랍니다.

require 'find'
require 'rubyXL'

count = 0

Find.find('/Users/Anconia/crawler/') do |file|             # begin iteration of each file of a specified directory
  if file =~ /\b.xlsx$\b/                                  # check if file is xlsx format
    workbook = RubyXL::Parser.parse(file).worksheets       # creates an object containing all worksheets of an excel workbook
    workbook.each do |worksheet|                           # begin iteration over each worksheet
      data = worksheet.extract_data.to_s                   # extract data of a given worksheet - must be converted to a string in order to match a regex
      if data =~ /regex/
        puts file
        count += 1
      end      
    end
  end
end

puts "#{count} files were found"

require 'find'
require 'spreadsheet'
Spreadsheet.client_encoding = 'UTF-8'

count = 0

Find.find('/Users/Anconia/crawler/') do |file|             # begin iteration of each file of a specified directory
  if file =~ /\b.xls$\b/                                   # check if a given file is xls format
    workbook =  Spreadsheet.open(file).worksheets          # creates an object containing all worksheets of an excel workbook
    workbook.each do |worksheet|                           # begin iteration over each worksheet
      worksheet.each do |row|                              # begin iteration over each row of a worksheet
        if row.to_s =~ /regex/                             # rows must be converted to strings in order to match the regex
          puts file
          count += 1
        end
      end
    end
  end
end

puts "#{count} files were found"

Ruby XL 젬은 XLSX 파일을 아름답게 해석합니다.

만족스러운 xlsx 파서를 찾을 수 없었습니다.Ruby XL은 날짜 타입 캐스팅을 하지 않습니다.Roo는 날짜로 숫자를 타이핑하려고 했습니다.API와 코드 모두 엉망입니다.

그래서 simple_xlsx_reader라고 썼어요.그러나 xls에는 다른 것을 사용해야 하기 때문에 원하는 완전한 답은 아닐 수 있습니다.

스프레드시트 보석의 작성자 웹사이트를 포함한 대부분의 온라인 예에서는 Excel 파일의 전체 내용을 RAM으로 읽는 방법을 시연하고 있습니다.스프레드시트가 작더라도 괜찮습니다.

xls = Spreadsheet.open(file_path)

대용량 파일을 사용하는 사용자라면 파일 내용을 스트리밍하여 읽는 것이 좋습니다.현재(2015년경) 문서화가 잘 되어 있지는 않지만 스프레드시트 보석은 이를 지원합니다.

Spreadsheet.open(file_path).worksheets.first.rows do |row|
  # do something with the array of CSV data
end

인용: https://github.com/zdavatz/spreadsheet

RemoteTable 라이브러리는 내부적으로 roo를 사용합니다.다양한 형식의 스프레드시트(XLS, XLSX, CSV 등)를 쉽게 읽을 수 있으며 zip, gz 등에 저장되어 있을 수 있습니다.

require 'remote_table'
r = RemoteTable.new 'http://www.fueleconomy.gov/FEG/epadata/02data.zip', :filename => 'guide_jan28.xls'
r.each do |row|
  puts row.inspect
end

출력:

{"Class"=>"TWO SEATERS", "Manufacturer"=>"ACURA", "carline name"=>"NSX", "displ"=>"3.0", "cyl"=>"6.0", "trans"=>"Auto(S4)", "drv"=>"R", "bidx"=>"60.0", "cty"=>"17.0", "hwy"=>"24.0", "cmb"=>"20.0", "ucty"=>"19.1342", "uhwy"=>"30.2", "ucmb"=>"22.9121", "fl"=>"P", "G"=>"", "T"=>"", "S"=>"", "2pv"=>"", "2lv"=>"", "4pv"=>"", "4lv"=>"", "hpv"=>"", "hlv"=>"", "fcost"=>"1238.0", "eng dscr"=>"DOHC-VTEC", "trans dscr"=>"2MODE", "vpc"=>"4.0", "cls"=>"1.0"}
{"Class"=>"TWO SEATERS", "Manufacturer"=>"ACURA", "carline name"=>"NSX", "displ"=>"3.2", "cyl"=>"6.0", "trans"=>"Manual(M6)", "drv"=>"R", "bidx"=>"65.0", "cty"=>"17.0", "hwy"=>"24.0", "cmb"=>"19.0", "ucty"=>"18.7", "uhwy"=>"30.4", "ucmb"=>"22.6171", "fl"=>"P", "G"=>"", "T"=>"", "S"=>"", "2pv"=>"", "2lv"=>"", "4pv"=>"", "4lv"=>"", "hpv"=>"", "hlv"=>"", "fcost"=>"1302.0", "eng dscr"=>"DOHC-VTEC", "trans dscr"=>"", "vpc"=>"4.0", "cls"=>"1.0"}
{"Class"=>"TWO SEATERS", "Manufacturer"=>"ASTON MARTIN", "carline name"=>"ASTON MARTIN VANQUISH", "displ"=>"5.9", "cyl"=>"12.0", "trans"=>"Auto(S6)", "drv"=>"R", "bidx"=>"1.0", "cty"=>"12.0", "hwy"=>"19.0", "cmb"=>"14.0", "ucty"=>"13.55", "uhwy"=>"24.7", "ucmb"=>"17.015", "fl"=>"P", "G"=>"G", "T"=>"", "S"=>"", "2pv"=>"", "2lv"=>"", "4pv"=>"", "4lv"=>"", "hpv"=>"", "hlv"=>"", "fcost"=>"1651.0", "eng dscr"=>"GUZZLER", "trans dscr"=>"CLKUP", "vpc"=>"4.0", "cls"=>"1.0"}

언급URL : https://stackoverflow.com/questions/3321011/parsing-xls-and-xlsx-ms-excel-files-with-ruby