XLS- und XLSX-Dateien (MS Excel) mit Ruby analysieren?
76
Gibt es Edelsteine, die XLS- und XLSX-Dateien analysieren können? Ich habe Spreadsheet und ParseExcel gefunden, aber beide verstehen das XLSX-Format nicht.
roo funktioniert sicherlich, aber es ist frustrierend un-Ruby-artig und (für mich jedenfalls) sehr überraschend: nicht in der Lage zu sein, mit jedem über Zeilen zu iterieren? nicht in der Lage sein, über Blätter zu iterieren? eine Vorstellung von einem "Standardblatt", gefolgt vom Zugriff auf Zellen über das Arbeitsmappenobjekt?
M. Anthony Aiello
7
Es hat eine Weile gedauert , bis ich sie gefunden habe, aber diese jetzt offizielle Roo-Gabel , die Sie explizit anheften müssen, behebt meine Beschwerden über Roo. Es verfügt über #each, #to_a, einen angemessenen Blattzugriff und verschmutzt den globalen Namespace nicht, Spreadsheetindem es eine Ruby-Tabelle benötigt.
Woahdae
@woahdae Super! Es wäre toll, ein Beispiel mit diesen neuen Funktionen zu sehen. Gibt es Unterlagen? Ich bin speziell daran interessiert, jede Zeile jedes Arbeitsblatts einer Arbeitsmappe durchlaufen zu können.
Anconia
Die README dieser Gabel enthält einen zusätzlichen Abschnitt darüber, was in der Gabel neu ist. Nach der Implementierung eines xlsx-Uploads, der eine gute Typumwandlung erfordert, stellte ich jedoch fest, dass die Roo-Typumwandlung sehr zu wünschen übrig ließ. Es wurde erstickt, als versucht wurde, "2" (als Zahl formatiert) als Datum zu analysieren. Ich habe meinen eigenen Parser geschrieben, den ich viel besser mag. Ich werde ihn heute Abend auf github hochladen und mich bei Ihnen melden.
Woahdae
@woahdae Gutes Zeug. Ich freue mich auf Ihre Arbeit. Bitte senden Sie den Link, wenn Sie können.
Anconia
118
Ich musste kürzlich einige Excel-Dateien mit Ruby analysieren. Die Fülle an Bibliotheken und Optionen erwies sich als verwirrend, deshalb schrieb ich einen Blog-Beitrag darüber.
Hier ist eine Tabelle mit verschiedenen Ruby-Bibliotheken und deren Unterstützung:
Wenn Sie Wert auf Leistung xlsxlegen, vergleichen die Bibliotheken Folgendes:
Ich habe Beispielcode zum Lesen von XLSX-Dateien mit jeder unterstützten Bibliothek hier
Hier einige Beispiele zum Lesen von xlsxDateien mit verschiedenen Bibliotheken:
Dies war ein großartiger Beitrag, den ich positiv bewertet habe, aber leider stellte ich fest, dass weder Roo noch Tabellenkalkulation mit meinen XLS-Daten funktionierten.
Guero64
2
Thnks @ guero64 Die xls-Funktionalität für roo wird tatsächlich in einem anderen Projekt namens roo-xls github.com/roo-rb/roo-xls gespeichert . Hast du diese Bibliothek ausprobiert?
Mattnedrich
4
Ich habe das Problem gefunden. Die Quelle, die die Dateien generierte, speicherte sie als XLS, aber der Inhalt war HTML. Vielen Dank für Ihre Eingabe.
Guero64
Haben Sie jemanden gefunden, der einen vernünftigen Job mit definierten Namen als Bereiche gemacht hat? ZB mit openpyxl: gist.github.com/empiricalthought/…
Steven
Großartige Vergleichsarbeit! Ich versuche, roo zu verwenden, und ich bin gewandert, ob Sie es geschafft haben, Kommentare aus einer Zelle zu extrahieren, und wie dies mit der bereitgestellten Funktion erreicht werden kann.
user1185081
43
Das Roo- Juwel eignet sich hervorragend für Excel (.xls und .xlsx) und wird aktiv weiterentwickelt.
Ich bin damit einverstanden, dass die Syntax weder großartig noch rubinartig ist. Aber das kann leicht erreicht werden mit so etwas wie:
Vorsicht bei dieser Namenskonvention - Spreadsheet ist eine vorhandene Konstante, die sich auf ein Modul bezieht: Das Spreadsheet.class # => ModuleUmbenennen der Klasse in "Roobook" löst dieses Problem. Tolle Arbeit!
Anconia
2
Das neueste Roo (auf der Empact-Gabel, auf die Sie zeigen) verschmutzt den Namespace nicht und wird mit #each und dergleichen geliefert. Schließlich! yay empact.
Woahdae
1
Roo Gem ist schrecklich mit großen Dateien. Das Öffnen einer 5 MB XLSx-Datei kann 30-60 Sekunden dauern, was einfach keinen Sinn ergibt.
Yura Omelchuk
1
Roo dauert lange, weil es alles in den Speicher laden muss. Es scheint auch die Tabelle in eine verwendbare Datenstruktur zu analysieren, die langsam sein kann.
Carlosfocker
Bitte wo in einem Rails-Projekt kann eine solche Datei @Bruno Buccolo aufbewahrt werden.
Wokoro Douye Samuel
26
Ich benutze Creek, der Nokiaogiri verwendet. Es ist schnell. Verwendet 8,3 Sekunden auf einem 21x11250 xlsx-Tisch auf meinem Macbook Air. Ich habe es für Ruby 1.9.3+ zum Laufen gebracht. Das Ausgabeformat für jede Zeile ist ein Hash aus Zeilen- und Spaltennamen zum Zelleninhalt: {"A1" => "eine Zelle", "B1" => "eine andere Zelle"} Der Hash übernimmt keine Garantie dafür, dass die Schlüssel vorhanden sind die ursprüngliche Spaltenreihenfolge.
https://github.com/pythonicrubyist/creek
Dullard ist ein weiterer großartiger, der Nokogiri verwendet. Es ist super schnell. Verwendet 6,7 Sekunden auf einem 21x11250 xlsx-Tisch auf meinem Macbook Air. Ich habe es für Ruby 2.0.0+ zum Laufen gebracht. Das Ausgabeformat für jede Zeile ist ein Array: ["eine Zelle", "eine andere Zelle"]
https://github.com/thirtyseven/dullard
Der erwähnte simple_xlsx_reader ist großartig, ein bisschen langsam. Verwendet 91 Sekunden auf einem 21x11250 xlsx-Tisch auf meinem Macbook Air. Ich habe es für Ruby 1.9.3+ zum Laufen gebracht. Das Ausgabeformat für jede Zeile ist ein Array: ["eine Zelle", "eine andere Zelle"]
https://github.com/woahdae/simple_xlsx_reader
Ein weiteres interessantes ist Oxcelix. Es verwendet den SAX-Parser von ox, der angeblich schneller ist als der DOM- und SAX-Parser von Nokiaogiri. Es wird angeblich eine Matrix ausgegeben. Ich konnte es nicht zum Laufen bringen. Außerdem gab es einige Abhängigkeitsprobleme mit Rubyzip. Würde es nicht empfehlen.
Zusammenfassend scheint Creek eine gute Wahl zu sein. Andere Beiträge empfehlen simple_xlsx_parser, da es eine ähnliche Leistung hat.
Dummkopf wie empfohlen entfernt, da er veraltet ist und Leute Fehler bekommen / Probleme damit haben.
Ich danke Ihnen für das Teilen. Ich fand, dass das Streamen von mehr als 100.000 Zeilen aus einer XLSX-Datei mit dem Dullard-Juwel schnell und speichereffizient ist.
scarver2
1
dullardwar voller Fehler für mich (mit nicht lateinischen Daten). creekgab, was ich brauche
okliv
okliv, es wäre fantastisch, wenn Sie angeben könnten, welche Schriftsätze hier nicht mit Dullard funktionieren. Schießen Sie auch einen Beitrag zum Dullard Issue Tracker auf Github! :)
the_minted
1
In dieser Antwort wird erwähnt, dass nur 'xlsx'-Dateien gelesen werden. Was ist mit' xls'-Dateien?
anshul410
7
Wenn Sie nach moderneren Bibliotheken suchen, werfen Sie einen Blick auf die Tabelle: http://spreadsheet.rubyforge.org/GUIDE_txt.html . Ich kann nicht sagen, ob es XLSX-Dateien unterstützt, aber wenn man bedenkt, dass es aktiv entwickelt wird, schätze ich, dass dies der Fall ist (ich bin nicht unter Windows oder mit Office, daher kann ich nicht testen).
An diesem Punkt sieht es so aus, als wäre Roo wieder eine gute Option. Es unterstützt XLSX und ermöglicht (einige) Iterationen, indem es nur timesmit Zellenzugriff verwendet wird. Ich gebe zu, es ist aber nicht schön.
Außerdem kann RubyXL Ihnen jetzt mithilfe seiner extract_dataMethode eine Art Iteration geben , die Ihnen ein 2D- Datenarray liefert, über das Sie leicht iterieren können.
Wenn Sie versuchen, mit XLSX-Dateien unter Windows zu arbeiten, können Sie alternativ die Win32OLE-Bibliothek von Ruby verwenden, mit der Sie eine Schnittstelle zu OLE-Objekten herstellen können, wie sie von Word und Excel bereitgestellt werden. Wie @PanagiotisKanavos in den Kommentaren erwähnt hat, hat dies jedoch einige Hauptnachteile:
Excel muss installiert sein
Für jedes Dokument wird eine neue Excel-Instanz gestartet
Der Speicher- und andere Ressourcenverbrauch ist weit mehr als für eine einfache Bearbeitung von XLSX-Dokumenten erforderlich.
Wenn Sie es jedoch verwenden möchten, können Sie festlegen, dass Excel nicht angezeigt wird, dass Sie Ihre XLSX-Datei laden und über diese Datei darauf zugreifen. Ich bin mir nicht sicher, ob es Iteration unterstützt, aber ich denke nicht, dass es zu schwierig wäre, um die bereitgestellten Methoden herum aufzubauen, da es sich um die vollständige Microsoft OLE-API für Excel handelt. Hier ist die Dokumentation: http://support.microsoft.com/kb/222101
Hier ist das Juwel: http://www.ruby-doc.org/stdlib-1.9.3/libdoc/win32ole/rdoc/WIN32OLE.html
Auch hier sehen die Optionen nicht viel besser aus, aber ich fürchte, es gibt nicht viel anderes da draußen. Es ist schwierig, ein Dateiformat zu analysieren, das eine Black Box ist. Und die wenigen, die es geschafft haben, es zu brechen, haben es nicht so sichtbar gemacht. Google Text & Tabellen ist eine geschlossene Quelle, und LibreOffice besteht aus Tausenden von Zeilen von Harry C ++.
Sehr hilfreiche Infos! Ich baue gerade einen Excel-Crawler und habe Passungen dazu ( stackoverflow.com/questions/14044357/… ). Ich habe Roo aufgegeben, da die Iteration ziemlich schmerzhaft ist. Ich bin jedoch gespannt darauf, es extract_datamit RubyXL zu versuchen .
Anconia
2
Die Verwendung von OLE für XLSX ist eine schlechte Idee - XLSX ist nur komprimiertes XML mit einem bekannten Format. Es ist definitiv keine Black Box - das Open XML-Format ist sehr gut definiert, das Open XML SDK bietet alle Informationen, die zum Erstellen des XMLSX erforderlich sind XML von Hand und es gibt viele Bibliotheken, die die Arbeit mit XLSX erheblich vereinfachen.
Panagiotis Kanavos
@PanagiotisKanavos: Interessanter Punkt. Ich verstehe zwar, warum das besser wäre, aber gibt es einen Grund (wieder aus Neugier), warum die Verwendung von OLE so schlecht ist? Ich habe Windows seit einigen Jahren nicht mehr verwendet oder entwickelt, daher fehlt mir möglicherweise etwas Offensichtliches.
Linuxios
Was Sie als OLE bezeichnen, ist die Automatisierungsschnittstelle für Excel. Dazu muss Excel auf dem Server installiert sein und für jede Dateianforderung gestartet werden. Es ist langsam - jeder Anruf ist ein nicht in Bearbeitung befindlicher Anruf bei Excel. Dies ist auch gefährlich, da das Vergessen, eine Instanz zu schließen, bedeutet, dass eine Excel-Instanz im Speicher bleibt. Dies kann schnell Serverressourcen verschlingen. Tatsächlich wurde XLSX so erstellt, dass jede Anwendung eine gültige Excel-Datei erstellen kann, ohne dass Excel auf dem Server erforderlich ist. Der Overhead ist minimal - es ist nur XML-Verarbeitung
Panagiotis Kanavos
@ PanagiotisKanavos: Richtig. Ich habe vergessen, dass OLE mehr IPC als eine Bibliothek ist. Vielen Dank! Ich werde der Antwort eine Notiz hinzufügen.
Linuxios
6
Ich habe in den letzten Wochen intensiv mit Spreadsheet und rubyXL gearbeitet und ich muss sagen, dass beide großartige Tools sind. Ein Bereich, unter dem beide leiden, ist das Fehlen von Beispielen für die tatsächliche Implementierung von nützlichen Dingen. Derzeit baue ich einen Crawler und verwende rubyXL, um xlsx-Dateien und Tabellenkalkulationen für alle xls zu analysieren. Ich hoffe, der folgende Code kann als hilfreiches Beispiel dienen und zeigen, wie effektiv diese Tools sein können.
require'find'require'rubyXL'
count = 0
Find.find('/Users/Anconia/crawler/') do|file|# begin iteration of each file of a specified directoryif 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 regexif data =~ /regex/
puts file
count += 1endendendend
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 directoryif 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 worksheetif row.to_s =~ /regex/# rows must be converted to strings in order to match the regex
puts file
count += 1endendendendend
puts "#{count} files were found"
rubyXL (wie oben roo) wird auch seltsam, wenn Sie tatsächlich auf die Daten in einem Arbeitsblatt zugreifen. Hat das Datenmodell für eine Tabelle etwas Grundlegendes, das nicht einfach über Zeilen und Spalten iteriert werden kann?
M. Anthony Aiello
4
RubyXL ist ein Chaos. Ich empfehle es nicht.
Benzado
3
Ich konnte keinen zufriedenstellenden xlsx-Parser finden. RubyXL führt keine Datums-Typumwandlung durch, Roo hat versucht, eine Zahl als Datum zu typisieren, und beide sind sowohl in der API als auch im Code ein Chaos.
Also habe ich simple_xlsx_reader geschrieben . Sie müssten jedoch etwas anderes für xls verwenden, sodass es möglicherweise nicht die vollständige Antwort ist, nach der Sie suchen.
Ich freue mich darauf, es zu versuchen. Wir hoffen, später weitere Funktionen zu sehen. Toller Start!
Anconia
3
Die meisten Online-Beispiele, einschließlich der Website des Autors für das Spreadsheet-Juwel, zeigen das Lesen des gesamten Inhalts einer Excel-Datei in den Arbeitsspeicher. Das ist in Ordnung, wenn Ihre Tabelle klein ist.
xls = Spreadsheet.open(file_path)
Für alle, die mit sehr großen Dateien arbeiten, ist es besser, den Inhalt der Datei per Stream zu lesen . Das Spreadsheet-Juwel unterstützt dies - wenn auch derzeit nicht gut dokumentiert (ca. 3/2015).
Spreadsheet.open(file_path).worksheets.first.rows do|row|# do something with the array of CSV dataend
Sie müssen .each hinzufügen, wenn etwas passieren soll
Peter
2
Die RemoteTable-Bibliothek verwendet Roo intern. Es erleichtert das Lesen von Tabellenkalkulationen in verschiedenen Formaten (XLS, XLSX, CSV usw., möglicherweise entfernt, möglicherweise in einem Zip, GZ usw. gespeichert):
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
Spreadsheet
indem es eine Ruby-Tabelle benötigt.Ich musste kürzlich einige Excel-Dateien mit Ruby analysieren. Die Fülle an Bibliotheken und Optionen erwies sich als verwirrend, deshalb schrieb ich einen Blog-Beitrag darüber.
Hier ist eine Tabelle mit verschiedenen Ruby-Bibliotheken und deren Unterstützung:
Wenn Sie Wert auf Leistung
xlsx
legen, vergleichen die Bibliotheken Folgendes:Ich habe Beispielcode zum Lesen von XLSX-Dateien mit jeder unterstützten Bibliothek hier
Hier einige Beispiele zum Lesen von
xlsx
Dateien mit verschiedenen Bibliotheken:rubyXL
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
roo
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
Bach
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_reader
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
Hier ist ein Beispiel für das Lesen einer Legacy-
xls
Datei mithilfe derspreadsheet
Bibliothek:Kalkulationstabelle
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
quelle
Das Roo- Juwel eignet sich hervorragend für Excel (.xls und .xlsx) und wird aktiv weiterentwickelt.
Ich bin damit einverstanden, dass die Syntax weder großartig noch rubinartig ist. Aber das kann leicht erreicht werden mit so etwas wie:
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
quelle
Spreadsheet.class # => Module
Umbenennen der Klasse in "Roobook" löst dieses Problem. Tolle Arbeit!Ich benutze Creek, der Nokiaogiri verwendet. Es ist schnell. Verwendet 8,3 Sekunden auf einem 21x11250 xlsx-Tisch auf meinem Macbook Air. Ich habe es für Ruby 1.9.3+ zum Laufen gebracht. Das Ausgabeformat für jede Zeile ist ein Hash aus Zeilen- und Spaltennamen zum Zelleninhalt: {"A1" => "eine Zelle", "B1" => "eine andere Zelle"} Der Hash übernimmt keine Garantie dafür, dass die Schlüssel vorhanden sind die ursprüngliche Spaltenreihenfolge. https://github.com/pythonicrubyist/creek
Dullard ist ein weiterer großartiger, der Nokogiri verwendet. Es ist super schnell. Verwendet 6,7 Sekunden auf einem 21x11250 xlsx-Tisch auf meinem Macbook Air. Ich habe es für Ruby 2.0.0+ zum Laufen gebracht. Das Ausgabeformat für jede Zeile ist ein Array: ["eine Zelle", "eine andere Zelle"] https://github.com/thirtyseven/dullard
Der erwähnte simple_xlsx_reader ist großartig, ein bisschen langsam. Verwendet 91 Sekunden auf einem 21x11250 xlsx-Tisch auf meinem Macbook Air. Ich habe es für Ruby 1.9.3+ zum Laufen gebracht. Das Ausgabeformat für jede Zeile ist ein Array: ["eine Zelle", "eine andere Zelle"] https://github.com/woahdae/simple_xlsx_reader
Ein weiteres interessantes ist Oxcelix. Es verwendet den SAX-Parser von ox, der angeblich schneller ist als der DOM- und SAX-Parser von Nokiaogiri. Es wird angeblich eine Matrix ausgegeben. Ich konnte es nicht zum Laufen bringen. Außerdem gab es einige Abhängigkeitsprobleme mit Rubyzip. Würde es nicht empfehlen.
Zusammenfassend scheint Creek eine gute Wahl zu sein. Andere Beiträge empfehlen simple_xlsx_parser, da es eine ähnliche Leistung hat.
Dummkopf wie empfohlen entfernt, da er veraltet ist und Leute Fehler bekommen / Probleme damit haben.
quelle
dullard
war voller Fehler für mich (mit nicht lateinischen Daten).creek
gab, was ich braucheWenn Sie nach moderneren Bibliotheken suchen, werfen Sie einen Blick auf die Tabelle: http://spreadsheet.rubyforge.org/GUIDE_txt.html . Ich kann nicht sagen, ob es XLSX-Dateien unterstützt, aber wenn man bedenkt, dass es aktiv entwickelt wird, schätze ich, dass dies der Fall ist (ich bin nicht unter Windows oder mit Office, daher kann ich nicht testen).
An diesem Punkt sieht es so aus, als wäre Roo wieder eine gute Option. Es unterstützt XLSX und ermöglicht (einige) Iterationen, indem es nur
times
mit Zellenzugriff verwendet wird. Ich gebe zu, es ist aber nicht schön.Außerdem kann RubyXL Ihnen jetzt mithilfe seiner
extract_data
Methode eine Art Iteration geben , die Ihnen ein 2D- Datenarray liefert, über das Sie leicht iterieren können.Wenn Sie versuchen, mit XLSX-Dateien unter Windows zu arbeiten, können Sie alternativ die Win32OLE-Bibliothek von Ruby verwenden, mit der Sie eine Schnittstelle zu OLE-Objekten herstellen können, wie sie von Word und Excel bereitgestellt werden. Wie @PanagiotisKanavos in den Kommentaren erwähnt hat, hat dies jedoch einige Hauptnachteile:
Wenn Sie es jedoch verwenden möchten, können Sie festlegen, dass Excel nicht angezeigt wird, dass Sie Ihre XLSX-Datei laden und über diese Datei darauf zugreifen. Ich bin mir nicht sicher, ob es Iteration unterstützt, aber ich denke nicht, dass es zu schwierig wäre, um die bereitgestellten Methoden herum aufzubauen, da es sich um die vollständige Microsoft OLE-API für Excel handelt. Hier ist die Dokumentation: http://support.microsoft.com/kb/222101 Hier ist das Juwel: http://www.ruby-doc.org/stdlib-1.9.3/libdoc/win32ole/rdoc/WIN32OLE.html
Auch hier sehen die Optionen nicht viel besser aus, aber ich fürchte, es gibt nicht viel anderes da draußen. Es ist schwierig, ein Dateiformat zu analysieren, das eine Black Box ist. Und die wenigen, die es geschafft haben, es zu brechen, haben es nicht so sichtbar gemacht. Google Text & Tabellen ist eine geschlossene Quelle, und LibreOffice besteht aus Tausenden von Zeilen von Harry C ++.
quelle
extract_data
mit RubyXL zu versuchen .Ich habe in den letzten Wochen intensiv mit Spreadsheet und rubyXL gearbeitet und ich muss sagen, dass beide großartige Tools sind. Ein Bereich, unter dem beide leiden, ist das Fehlen von Beispielen für die tatsächliche Implementierung von nützlichen Dingen. Derzeit baue ich einen Crawler und verwende rubyXL, um xlsx-Dateien und Tabellenkalkulationen für alle xls zu analysieren. Ich hoffe, der folgende Code kann als hilfreiches Beispiel dienen und zeigen, wie effektiv diese Tools sein können.
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"
quelle
Das rubyXL- Juwel analysiert XLSX-Dateien auf wundervolle Weise.
quelle
Ich konnte keinen zufriedenstellenden xlsx-Parser finden. RubyXL führt keine Datums-Typumwandlung durch, Roo hat versucht, eine Zahl als Datum zu typisieren, und beide sind sowohl in der API als auch im Code ein Chaos.
Also habe ich simple_xlsx_reader geschrieben . Sie müssten jedoch etwas anderes für xls verwenden, sodass es möglicherweise nicht die vollständige Antwort ist, nach der Sie suchen.
quelle
Die meisten Online-Beispiele, einschließlich der Website des Autors für das Spreadsheet-Juwel, zeigen das Lesen des gesamten Inhalts einer Excel-Datei in den Arbeitsspeicher. Das ist in Ordnung, wenn Ihre Tabelle klein ist.
Für alle, die mit sehr großen Dateien arbeiten, ist es besser, den Inhalt der Datei per Stream zu lesen . Das Spreadsheet-Juwel unterstützt dies - wenn auch derzeit nicht gut dokumentiert (ca. 3/2015).
Spreadsheet.open(file_path).worksheets.first.rows do |row| # do something with the array of CSV data end
Zitieren: https://github.com/zdavatz/spreadsheet
quelle
Die RemoteTable-Bibliothek verwendet Roo intern. Es erleichtert das Lesen von Tabellenkalkulationen in verschiedenen Formaten (XLS, XLSX, CSV usw., möglicherweise entfernt, möglicherweise in einem Zip, GZ usw. gespeichert):
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
Ausgabe:
{"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"}
quelle