Andreas: Excel-Dateien serverseitig lesen

Hallo!

Inzwischen schaffe ich es schon mit den beiden entsprechenden PERL-Modulten Excel-Dokumente zu verändern und zu erstellen. Gibt es darüber hinaus ein PERL Modul oder eine andere Möglichkeit um Excel-Dateien serverseitig zu lesen und auszuwerten, halt wie csv-Dateien? Es müssen die original Excel .xls-Dateien sein, keine aus Excel exportierten Dateien. Gibt es da eine frei verfügbare Lösung für Unix-Derivate? Oder welche Möglichkeiten gibt es sonst noch?

Viele Grüße
Andreas

  1. Hi Andreas,

    ich glaube nicht, dass es eine solche Lösung unter einem unix-ähnllichem System gibt - warum sollen es denn unbedingt die Original dateien aus Excel sein?
    Gibt es keinen anderen Weg?

    Gruss Sven

    1. Hallo!

      ich glaube nicht, dass es eine solche Lösung unter einem unix-ähnllichem System gibt -

      http://selfsuche.teamone.de/cgi-bin/such.pl?suchausdruck=perl+excel&feld=alle&index_4=on&hits=100
      http://search.cpan.org/search?mode=all&query=Excel

      warum sollen es denn unbedingt die Original dateien aus Excel sein?

      Das ist eine Vorgabe!

      Gibt es keinen anderen Weg?

      Es gibt viele Wege, aber mit Excel kann eben (in diesem Fall) jeder umgehen, und es funktioniert bereits so oder so ähnlich, nur halt manuell! Ich würde das auch leiber in html machen, aber das sei zu unflexibel, wobei der Flexibilität klare Grenzen gesetzt werden müssen, wenn der Server das noch parsen soll! Wie diese Grenzen genau aussehen sollen weiß ich auch noch nicht so genau, vielleicht habt Ihr ja Ideen dazu!

      Nochmal zu den Modulen, ich habe gerade nochmal im Archiv nachgelesen, die erste Frage hat sich wohl erledigt, mit Spreadsheet::ParseExcel lese ich die Datei ein, (in einen Hash?) und muß dann die Formulareinträge dem Hash hinzufügen, und dann den Hash wieder in eine neue Datei schreiben mit Spreadsheet::WriteExcel, oder wie würdet ihr das machen?

      Viele Grüße
      Andreas

      1. Hallo,

        Nochmal zu den Modulen, ich habe gerade nochmal im Archiv nachgelesen, die erste Frage hat sich wohl erledigt, mit Spreadsheet::ParseExcel lese ich die Datei ein, (in einen Hash?) und muß dann die Formulareinträge dem Hash hinzufügen, und dann den Hash wieder in eine neue Datei schreiben mit Spreadsheet::WriteExcel, oder wie würdet ihr das machen?

        Argh!

        Um drei Minuten zu spät! ;-)

        so short

        Christoph Zurnieden

        1. Hallo,

          Nochmal zu den Modulen, ich habe gerade nochmal im Archiv nachgelesen, die erste Frage hat sich wohl erledigt, mit Spreadsheet::ParseExcel lese ich die Datei ein, (in einen Hash?) und muß dann die Formulareinträge dem Hash hinzufügen, und dann den Hash wieder in eine neue Datei schreiben mit Spreadsheet::WriteExcel, oder wie würdet ihr das machen?

          Hier scheint eine Gebrauchsanleitung zu sein:
          http://www-106.ibm.com/developerworks/linux/library/l-pexcel/

          (Damit ich doch noch zu was gut bin ;-)

          so short

          Christoph Zurnieden

  2. Hallo!

    Inzwischen schaffe ich es schon mit den beiden entsprechenden PERL-Modulten Excel-Dokumente zu verändern und zu erstellen. Gibt es darüber hinaus ein PERL Modul oder eine andere Möglichkeit um Excel-Dateien serverseitig zu lesen und auszuwerten, halt wie csv-Dateien? Es müssen die original Excel .xls-Dateien sein, keine aus Excel exportierten Dateien. Gibt es da eine frei verfügbare Lösung für Unix-Derivate? Oder welche Möglichkeiten gibt es sonst noch?

    Vielleicht noch ein wenig zum Hintergrund:
    Ich möchte eine Extranet-Anwendung schreiben, um von bestimmten Personen Informationen zu bekommen. Das soll nach folgendem Schema ablaufen:
    Ich möchte z.B. von 10 Personen wissen, wieviel bei jedem von ihnen eine Luftmatratze und zwei Hängematten kosten.
    Dann erstelle ich eine Excel-Datei von einer Vorlage(wichtig damit das später geparst werden kann, aber wo da die Grenzen liegen weiß ich selbst noch nicht) eine Tabelle, 1. Spalte die Produktbeschreibung, dann eine Spalte pro Person(Anbieter), wo derjenige dann seinen Preis eintragen soll.
    Aber das soll er nicht selbst machen, das soll dann der Server übernehmen!

    Wenn ich dann also meine Ecxel-Datei fertig habe(noch ohne Preise) lade ich die mit HTTP über ein HTML-Formular hoch. Dann wird auf dem Server ein Script in gang gesetzt, welches die Excel-Datei auswertet. Und hier beginnen meine Probleme. Es gibt eine Menge Excel-Module von PERL, die sich mit Parsen von Excel beschäftigen und ich habe keinen Schimmer welches davon hier wohl geeignet sein könnte, vielleicht kennt sich ja hier einer aus, deshalb die genauere Beschreibung.

    Das Scipt soll folgendes machen:
    an jeden Anbieter (Zeile 1, Spalten 2-n der .xls-Datei) soll eine email geschickt werden, mit einem Link zu einem html-Formular und mit seinem Namen als Parameter.
    Wenn derjenige dann die email bekommt, klickt er auf den Link, kommt zu dem Formular. Das Formular wird dann wieder aus dem Excel-Sheet generiert, halt pro Artikel jeweils die Bezeichnung aus Spalte 1, Zeile 1-n und ein dazu gehöriges Formular-Feld um den Preis einzutragen. Das Eintragen dann ist kein Problem mehr, wenn er das Formular abschickt werden die Daten mittels entsprechendem Excel-Modul von Perl in die bestehende .xls Datei eingefügt, oder vielleicht auch in eine .txt und die .xls erst am Ende generiert, mal schauen. Aber mein größtes Problem, welche PERL-Module sollte ich dafür verwenden?

    Wenn bei den Modulen steht "verstehen Excel 2000", verstehen die dann auch XP(2002)?

    Außerdem habe ich noch nicht so recht eine Idee, wie man sicherstellen kann, dass eine Excel-Datei auch korrekt interpretiert wird, d.h. das keine Fehler dabei auftreten, z.B. durch fehlerhaftes Eintragen der Daten in die .xls-Datei!

    Weiteres Problem ist die Vielzahl der notwendigen Daten, z.B. email, oder weitere Produktspezifikation, Bild,..., es soll so einfach wie möglich sein, und ich weiß nicht so recht ob man eine DB dazu nehmen sollte, in der man derartige Daten ablegen kann, um in den Excel-Sheets nicht so viele Angaben machen zu müssen, auf der anderen Seite muß man dann die DB auch anlegen und pflegen...

    Was meint Ihr grundsäztlich dazu?

    Grüße
    Andreas

    1. Hallo!

      Noch ein prinzipielles Problem bei diesem Ablauf:

      Wie verhindere ich am besten, das derjenige Anbieter, der die Mail erhält, dass der tatsächlich nur seine eigenen Daten eingeben kann?

      Denn wenn ich wie geplant den Namen als Parameter übergebe, könnte er ja anfangen zu raten und mit Aussicht auf Erfolg, da er seine Konkurrenz wahrscheinlich gut kennt!
      Was hätte ich da für Möglichkeiten:

      Variante 1: Vorher Benutzer anlegen und ein Passwort festlegen, das wäre wohl das sicherste, aber das sollö vermieden werden.

      Variante 2: Man übegebe nicht den Namen _und_ eine uniqueID als Parameter, die ID müßte man dann temporär speichern.

      was haltet Ihr von Variante 2, ist das hinreichend sicher? Oder sollte ich lieber einen md5() kodierten string aus name.uniqueID übergeben? Das wäre wohl das einfachste, oder? Denn ein md5() String als Parameter-Wert stellt die wenigsten Email-Clients vor ein Problem!

      Was meint Ihr dazu?

      Grüße
      Andreas

      1. Halihallo Andreas

        Noch ein prinzipielles Problem bei diesem Ablauf:

        Wie verhindere ich am besten, das derjenige Anbieter, der die Mail erhält, dass der tatsächlich nur seine eigenen Daten eingeben kann?

        Indem du ihm die anderen vorenthältst!?

        Denn wenn ich wie geplant den Namen als Parameter übergebe, könnte er ja anfangen zu raten und mit Aussicht auf Erfolg, da er seine Konkurrenz wahrscheinlich gut kennt!

        Hm. OK...

        Was hätte ich da für Möglichkeiten:

        Variante 2: Man übegebe nicht den Namen _und_ eine uniqueID als Parameter, die ID müßte man dann temporär speichern.

        Temporär??? - Was, wenn er die Daten nach einer Woche nochmals ändern will? - Wie würdest du die Schranke festlegen?

        Variante 3: MD5(Name) => Anbieter sind wohl nicht so gescheit, zu merkten, wie dieses Teil entsteht...

        Variante 4: MD5(Name+time()) => diesen Wert einfach irgendwo speichern (musst nicht jedesmal die "Prüfsumme" neu berechnen).

        Variante 5: crypt (Unix-crypt => nicht reversible Verschlüsselung => einfach den Wert, den dieses Teil zurückgibt speichern)

        ich glaube, das mit einer uniqueID wäre sogar etwas zu arbeitsintensiv... Es geht auch noch schneller ;)

        was haltet Ihr von Variante 2, ist das hinreichend sicher?

        Im Prinzip glaube ich ja. Solange der Anbieter keinen menschenlesbaren String als URL enthält, ist meistens schon Ende :-)
        Aber wenn wir schon bei Sicherheit sind: eine ID lässt mich eine aufsteigende Reihe von 1 beginnend vermuten. Das wäre wohl auch genau das, was ein schlauer Anbieter im Hinterköpfchen hätte. Sicherer würd ich es finden, wenn du einfach MD5 über den Namen plus Timestamp laufen lässt (oder nur timestamp) und diesen Wert dann einfach speicherst und dem Anbieter zuordnest.

        Oder sollte ich lieber einen md5() kodierten string aus name.uniqueID übergeben? Das wäre wohl das einfachste, oder? Denn ein md5() String als Parameter-Wert stellt die wenigsten Email-Clients vor ein Problem!

        use Digest::MD5 qw(md5_hex);

        print md5_hex($name . time());

        => hex Werte sind bestimmt alle URL konform (dann brauchst du URI::Escape nicht). Eventuell würde auch MIME::Base64 oder gleich mit md5_base64 helfen; wobei der hex Wert "elegant" ist ;-)

        Viele Grüsse

        Philipp

        1. Hi!

          Danke Dir, ich denke so werd ichs machen! md5() kombiniert mit Name und timestamp. Mal gucken, in PHP gibts ja speziell urlencode(), damit sollte es keien Probleme geben.
          Das einzige Risiko ist wenn der Email-Client (z.B. Steinzeit T-Online 2.x) keine Links anklickbar macht. Nicht jeder kennt STRG + C !
          Wenn ich die ID evtl. in diesem Fall in ein Eingabefeld eingeben lasse, dann sollte die ja nicht unbedingt 48 byte haben ;-)
          Sollte ich dann vielleicht einen Teilstring, vielleicht die letzten 10 Zeichen, sowas wie

          substr(urlencode(md5($name.time())),-10)

          in PHP, dann kann man das zur Not auch abtippen.

          Grüße
          Andreas

          1. Halihallo Andreas

            Danke Dir, ich denke so werd ichs machen! md5() kombiniert mit Name und timestamp. Mal gucken, in PHP gibts ja speziell urlencode(), damit sollte es keien Probleme geben.

            use URI::Escape qw(uri_escape);

            print uri_escape('bla bla');

            -> bla%20bla ;-)

            Das einzige Risiko ist wenn der Email-Client (z.B. Steinzeit T-Online 2.x) keine Links anklickbar macht. Nicht jeder kennt STRG + C !

            Nun, dann sind die Anbieter aber auch unfähig, das kann ja nicht so schwer sein und ich glaube jeder hat schon mal ein Link in einer E-Mail angeklickt (sonst kannst du ja auch beschreiben, wie das geht ;-)). Oder du kannst, was ich zwar nicht befürworte, eine HTML-Mail schreiben mit <a href="">...</a>

            Wenn ich die ID evtl. in diesem Fall in ein Eingabefeld eingeben lasse, dann sollte die ja nicht unbedingt 48 byte haben ;-)
            Sollte ich dann vielleicht einen Teilstring, vielleicht die letzten 10 Zeichen, sowas wie

            substr(urlencode(md5($name.time())),-10)

            Oder du machst noch eine Art "md5" von dem MD5 kodierten String, der dir jedoch nur noch einen 10Byte Finterprint liefert => mit einigen Bitoperationen lässt sich dies einfach bewerkstelligen. Problem ist nur: je kleiner die Grösse des Fingerprints, desto schneller gibt's Überschneidungen (zwei Anbieter mit gleichem Fingerprint), ganz zu schweigen vom Sicherheitsrisiko... Aber solange du nicht 100'000 Anbieter "bearbeiten" willst, hast du selbst bei 7Byte Fingerprints wohl kaum Probleme...

            Viele Grüsse

            Philipp

            1. Hallo!

              Das einzige Risiko ist wenn der Email-Client (z.B. Steinzeit T-Online 2.x) keine Links anklickbar macht. Nicht jeder kennt STRG + C !

              Nun, dann sind die Anbieter aber auch unfähig, das kann ja nicht so schwer sein und ich glaube jeder hat schon mal ein Link in einer E-Mail angeklickt (sonst kannst du ja auch beschreiben, wie das geht ;-)). Oder du kannst, was ich zwar nicht befürworte, eine HTML-Mail schreiben mit <a href="">...</a>

              Nein, es gibt ja inzwischen T-Online 3,4,... aber die Leute haben einmal Ihr 2.0. drauf,  und dabei bleibts die nächsten Jahre! Ich habe dieses Jahr 2 Leute mühsam davon überzeugt das sie doch wenistens OutlookExpress mal probieren könnten ;-)

              Wenn ich die ID evtl. in diesem Fall in ein Eingabefeld eingeben lasse, dann sollte die ja nicht unbedingt 48 byte haben ;-)
              Sollte ich dann vielleicht einen Teilstring, vielleicht die letzten 10 Zeichen, sowas wie

              substr(urlencode(md5($name.time())),-10)

              Oder du machst noch eine Art "md5" von dem MD5 kodierten String, der dir jedoch nur noch einen 10Byte Finterprint liefert => mit einigen Bitoperationen lässt sich dies einfach bewerkstelligen. Problem ist nur: je kleiner die Grösse des Fingerprints, desto schneller gibt's Überschneidungen (zwei Anbieter mit gleichem Fingerprint), ganz zu schweigen vom Sicherheitsrisiko... Aber solange du nicht 100'000 Anbieter "bearbeiten" willst, hast du selbst bei 7Byte Fingerprints wohl kaum Probleme...

              Ich kenne ja die paar Leute die eine ID bekommen müssen, dann kann ich ja die IDs in einen Array schreiben und immer prüfen ob die ID schon im Array steht. Am Ende speichere ich die IDs dann in einer txt Datei oder ähnlichem.

              Grüße
              Andreas

    2. Halihallo Andreas

      Ich möchte eine Extranet-Anwendung schreiben, um von bestimmten Personen Informationen zu bekommen. Das soll nach folgendem Schema ablaufen:
      Ich möchte z.B. von 10 Personen wissen, wieviel bei jedem von ihnen eine Luftmatratze und zwei Hängematten kosten.
      Dann erstelle ich eine Excel-Datei von einer Vorlage(wichtig damit das später geparst werden kann, aber wo da die Grenzen liegen weiß ich selbst noch nicht) eine Tabelle, 1. Spalte die Produktbeschreibung, dann eine Spalte pro Person(Anbieter), wo derjenige dann seinen Preis eintragen soll.
      Aber das soll er nicht selbst machen, das soll dann der Server übernehmen!

      OK. Also etwa so:

      Artikel | Anbieter 1 | Anbieter 2 | Anbieter 3
      Lufti   | 125.3      | 100.3      | 97.5
      Hängi   | 56.3       | 23.5       | 97.5

      dies liegt in einer xls Datei vor, jedoch ohne Preise. Nachher soll jeder Anbieter über ein Formular den Preis eingeben können und dein Script soll dann den eingegebenen Preis in die xsl Datei schreiben und bei z. B. erneutem Laden (eg. Anbieter hat gemerkt, dass er seinen Preis falsch eingegeben hat) den Wert wieder aus der Excel Datei laden. Hab ich das soweit begriffen?

      Wozu eigentlich xls? - Ich meine, hast du bereits eine vorgefertigte Vorlage mit ca. 10000 Anbietern und willst diese nicht manuell extrahieren, oder erwarten die Anbieter am Schluss die gesamte Liste im xls-Format?

      Und wo sind eigentlich die E-Mail Adressen? - Wo sind die zusätzlichen Daten (eg. Produktbild, zweite Beschreibung etc.), welche du ansprichst? - Wo willst du die da unterbringen?

      Und hier beginnen meine Probleme. Es gibt eine Menge Excel-Module von PERL, die sich mit Parsen von Excel beschäftigen und ich habe keinen Schimmer welches davon hier wohl geeignet sein könnte, vielleicht kennt sich ja hier einer aus, deshalb die genauere Beschreibung.

      Nun, ich glaube, du kannst einige benutzen, die meisten dürfte das kein Problem darstellen (kann sein, dass einige mit Diagrammen nicht zurecht kommen, oder die Schriftformatierungen nicht mehr mitschreiben). Da hilft die wahrscheinlich nur testen.

      Wenn bei den Modulen steht "verstehen Excel 2000", verstehen die dann auch XP(2002)?

      Wenn nein, kannst du sie ja konvertieren und nachher wieder als Excel 2002 abspeichern.

      Außerdem habe ich noch nicht so recht eine Idee, wie man sicherstellen kann, dass eine Excel-Datei auch korrekt interpretiert wird, d.h. das keine Fehler dabei auftreten, z.B. durch fehlerhaftes Eintragen der Daten in die .xls-Datei!

      s. unten.

      Weiteres Problem ist die Vielzahl der notwendigen Daten, z.B. email, oder weitere Produktspezifikation, Bild,..., es soll so einfach wie möglich sein, und ich weiß nicht so recht ob man eine DB dazu nehmen sollte, in der man derartige Daten ablegen kann, um in den Excel-Sheets nicht so viele Angaben machen zu müssen, auf der anderen Seite muß man dann die DB auch anlegen und pflegen...

      Was meint Ihr grundsäztlich dazu?

      Hm. Also ich würde mich grundsätzlich möglichst weit von xls hinwegbewegen, sprich, das lesen/schreiben der xls Datei nur am Anfang/Ende durchzuführen und alles, was dazwischen ist, über sonstige Lösungen machen (z. B. CVS, Datenbank, XML, ...). Der Vorteil bestünde darin, dass man sich auf etwas "gängigere" Formate konzentrieren könnte, sprich, mit den Modulen bereits "Erfahrung" gesammelt hat und sich nicht mit Excel herumschlagen muss. Zudem wäre es möglich, dass du das "Dazwischen" mit php Programmieren könntest, wo du ja mehr Erfahrung hast. Des weiteren hast du das Problem der "Datensicherheit" angesprochen, ich habe etwas mehr vertrauen zu XML, CVS oder Datenbank, als zu XLS-Parsern.

      Also:
      XLS per HTML hochladen => parse.pl Script aufrufen, welches alle Daten aus der XLS in ein gängiges Format abbildet. Dann send.php aufrufen, was die Links an die extrahierten e-Mails aus der ExcelDatei versendet. Klickt der Kunde auf den Link, wird show-and-input.php aufgerufen, wo die Daten geändert werden können (und in der DB, XML, CVS gespeichert wird). Am Ende kannst du write.pl aufrufen, was die Daten wieder in eine XLS packt... Ich denke, wenn du von "Vorlage" sprichst, hast du Angst, dass die Vorlagedaten (eg. Formeln) verloren gehen. Ich bin mir hier leider nicht sicher, jedoch denke ich, dass wenn ein XLS-Parser die Vorlagedaten richtig schreibt, sollte man ihn auch dazu veranlassen können, diese Daten "nachher" einzugeben. Mit anderen Worten: Warum sollte ein Parser Daten schreiben, die er selber nicht versteht? - bzw. woher will der Parser wissen, wo die nicht verstandenen Daten hingehören?

      Zudem: Falls die Parser wirklich in der Lage sein sollten, diese Verluste zu unterlassen, auch wenn sie die Daten nicht verstehen, kannst du ja immer noch die Vorlage parsen und dann die Werte einsetzen (also mit write.pl genau das tun, was du sonst getan hättest, nur eben in einem Schritt).

      Viele Grüsse

      Philipp

  3. Hallo,

    Inzwischen schaffe ich es schon mit den beiden entsprechenden PERL-Modulten Excel-Dokumente zu verändern und zu erstellen.

    Welche meinst Du genau? Hast Du alle hier ausprobiert?
    http://search.cpan.org/search?mode=all&query=Spreadsheet%3A%3A

    Gibt es darüber hinaus ein PERL Modul oder eine andere Möglichkeit um Excel-Dateien serverseitig zu lesen und auszuwerten, halt wie csv-Dateien? Es müssen die original Excel .xls-Dateien sein, keine aus Excel exportierten Dateien. Gibt es da eine frei verfügbare Lösung für Unix-Derivate? Oder welche Möglichkeiten gibt es sonst noch?

    Frei verfügbar habe ich auf die Schnelle nur den hier gefunden:

    http://www.andykhan.com/jexcelapi/ (GPL)

    Ist allerdings leider nur in Java.

    Der rest scheint ziemlich teuer:
    http://www.extentech.com/estore/product_detail.jsp?product_group_id=1 US$ 995

    http://www.ais.com/linux_corner.html US$ 69.95 (Scheint aber mit GUI)

    http://www.greytrout.com/ Keinen Preis gefunden (allerdings auch nicht danach gesucht ;-)

    so short

    Christoph Zurnieden

    1. Hallo,

      Inzwischen schaffe ich es schon mit den beiden entsprechenden PERL-Modulten Excel-Dokumente zu verändern und zu erstellen.

      Welche meinst Du genau? Hast Du alle hier ausprobiert?
      http://search.cpan.org/search?mode=all&query=Spreadsheet%3A%3A

      Ich habe zunächst nur mit Spreadsheet::WriteExcel zu tun gehabt. Also Spreadsheet::ParseExcel scheint das zu sein was ich suche.
      Weißt Du ob Spreadsheet::WriteExcel auch bestehende Excel-Dateien ändern kann oder "nur" neue anlegen?

      Wenn ich das richtig verstehe erstellt Spreadsheet::ParseExcel ein Objekt aus der Excel-Datei, auf welches man dann zugreifen kann, oder?  Oder ist das ein Mehrdimensionaler Array? Jednefals wäre das besser denn da könnte ich einfach Daten anfügen und wieder mit Spreadsheet::WriteExcel in eine Excel-Datei schreiben.
      Müßte ich dann wohl in einer Schleife den Array auslesen und entsprechend eintragen, oder?

      Oder gibt es einen eleganteren Weg die Daten in PERL auszulesen, Daten hinzuzufügen und wieder in die Datei zu schreiben?

      Kannst Du mir sagen ob das ganze dann auch mit Excel 2002(XP) Dateien funktioniert? http://search.cpan.org/author/KWITKNR/Spreadsheet-ParseExcel-0.2602/ParseExcel.pm#DESCRIPTION

      Viele Grüße
      Andreas

      1. use Mosche;

        Weißt Du ob Spreadsheet::WriteExcel auch bestehende Excel-Dateien ändern kann oder "nur" neue anlegen?

        Spreadsheet::WriteExcel kann nur schreiben.

        Oder gibt es einen eleganteren Weg die Daten in PERL auszulesen, Daten hinzuzufügen und wieder in die Datei zu schreiben?

        Der meiner Ansciht nach eleganteste Weg ist DBD::Excel, welches vom Autor der beiden Spreadsheet::*Excel-Module ist und auf denen der DBD-Treiber aufbaut. Der Vorteil liegt bei der Verwendung darin, dass du ohne große Probleme danach noch auf andere Formate zugreifen kannst (wenn du schon bei Excel bist, könnte DBD::CSV interessant für dich sein). Das DBD-Modul sollte dir optimalen Zugriff auf die Inhalte der Excel-Tabellen bieten. Ich muß allerdings zugeben, dass DBD::Excel zu dem Zeitpunkt, als ich es ausprobierte, gerade mal Version 0.02 hatte, deswegen mein Tip : einfach mal probieren.

        use Tschoe qw(Matti);

        1. Hallo!

          Oder gibt es einen eleganteren Weg die Daten in PERL auszulesen, Daten hinzuzufügen und wieder in die Datei zu schreiben?

          Der meiner Ansciht nach eleganteste Weg ist DBD::Excel, welches vom Autor der beiden Spreadsheet::*Excel-Module ist und auf denen der DBD-Treiber aufbaut. Der Vorteil liegt bei der Verwendung darin, dass du ohne große Probleme danach noch auf andere Formate zugreifen kannst (wenn du schon bei Excel bist, könnte DBD::CSV interessant für dich sein). Das DBD-Modul sollte dir optimalen Zugriff auf die Inhalte der Excel-Tabellen bieten. Ich muß allerdings zugeben, dass DBD::Excel zu dem Zeitpunkt, als ich es ausprobierte, gerade mal Version 0.02 hatte, deswegen mein Tip : einfach mal probieren.

          Danke für den Tip, habs mir mal angesehen, das Problem dabei, das sind ja dann "Nur noch" reine Daten, oder? d.h. ich möchte in der Ausgabe auch Formeln, und evtl. auch Formatierungen verwenden. Der Schwerpunkt liegt hier weniger in der optimalen Datenhaltung/Datenverwaltung/Datenzugriff, eher in der Anwendung: Es soll ein bestehender Vorgang teilweise automatisiert werden, aber sonst möglichst so bleiben wie er ist und wie alle Mitarbeiter das kennen.
          Leider habe ich noch ein wenig Probleme mit der Syntax von PERL(php ist da schon etwas einfacher ;-O), vor allem da ich dann wohl alles in PERl machen sollte(Mailversand, Dynamisches HTML-Formular generieren...) also ist jetzt mal PERL programmieren(lernen) angesagt ;-) Leider habe ich gerade meine "Einführung in PERL" nicht griffbereit, abe das ein oder andere ist doch schon hängengeblieben, udn viele Sachen funktionierenn in PHP zumindest ähnlich(der Mailverrsand zählt nicht dazu, das habe ich aber schon hinbekommen ;-))

          Da ich das jetzt auch mal ohne Dateiendungen versuchen wollte, habe ich auch dazu noch mal ein Frage:

          Da ich vermutlich sowohl PHP als auch PERL-Dateien  verwenden werde, wie müßte dann eine Rewrite-Rule aussehen, die immer an das richtige(vorhandene) Script weiterleitet?
          (wenn schon dann direkt ein ordentlicher Schwierigkeitsgrad ;-))

          RewriteRule ^(.*?)??(.*?) $1.php?$2 [L]

          Also Request-Url, und ggfs. noch einen Paramter => Request-Url,".php und auf alle Fälle ein Paramter

          wäre ja so eine Regel für PHP, aber wie kann ich prüfen ob unter dem Namen (.*?) eine .pl oder eine .php - Datei existiert und dann entsprechend weiterleiten?

          Grüße
          Andreas

      2. Hallo,

        Ich habe zunächst nur mit Spreadsheet::WriteExcel zu tun gehabt. Also Spreadsheet::ParseExcel scheint das zu sein was ich suche.

        Ja, ich denke schon.

        Wenn ich das richtig verstehe erstellt Spreadsheet::ParseExcel ein Objekt aus der Excel-Datei, auf welches man dann zugreifen kann, oder?

        Bingo. Und die neueren Versionen könnnen dann auch über Spreadsheet::ParseExcel::SaveParser Dateien schreiben.

        Kannst Du mir sagen ob das ganze dann auch mit Excel 2002(XP) Dateien funktioniert?

        Warum probiest Du es nicht einfach aus?

        Grüße
          Klaus

        1. Hallo!

          Kannst Du mir sagen ob das ganze dann auch mit Excel 2002(XP) Dateien funktioniert?

          Warum probiest Du es nicht einfach aus?

          Was habe ich davon wenn eine kleine Testtabelle funktioniert aber wenn in der Anwendung komplexere Tabellen verwendet werden irgendwelche XP-Features zum Absturz führen!

          Aber meines Wissens ist 2000 und 2002 voll kompatibel, zumindest bei Word, oder? Nur leider weiß ich das nicht sicher!

          Grüße
          Andreas

          1. Hallo,

            Warum probiest Du es nicht einfach aus?

            Was habe ich davon wenn eine kleine Testtabelle funktioniert aber wenn in der Anwendung komplexere Tabellen verwendet werden irgendwelche XP-Features zum Absturz führen!

            Eine einfache Testdatei kann Dir nur zeigen, ob es grundsätzlich geht, also, ob es überhaupt möglich ist, auf ExcelXP-Dateien zuzugreifen.

            Und der absturzfreie Umgang mit komplexen Dateien ist ja nicht mal mit den Originalprogrammen von M$ gewährleistet. AUhc da hilft nur Trial&Error. Deren Produktpflege ist ja de facto nicht wirklich vorhanden. Wenn die etwas neues auf den Markt werfen, ist es kurze Zeit später so, als ob es Vorversionen gar nie gegeben hätte.

            Ein weiteres Problem ist, daß die ihre eigenen Standards nicht wirklich offenlegen oder zumindest nur einhalten, was es Nicht-MS-Entwicklern[1] einigermaßen schwer macht, sich auf etwas zu verlassen.

            Aber meines Wissens ist 2000 und 2002 voll kompatibel, zumindest bei Word, oder? Nur leider weiß ich das nicht sicher!

            Meines Wissens nach ist es auch so, aber so wirklich habe ich mich Office XP nicht beschäftigt.

            Grüße
              Klaus

            [1] Und wohl auch MS-Entwicklern;-)

  4. wenn das geht, dann müsste theoretisch auch ei "Excel-Chat" möglich sein oder ?

  5. Hallo!

    So, nachdem mein PC jetzt wieder einigermaßen so ist das man damit arbeiten kann habe ich mich doch mal direkt daran gemacht.

    Aber schon das parsen funktioniert leider nicht. Ich habe genau das Beipiel von http://search.cpan.org/author/KWITKNR/Spreadsheet-ParseExcel-0.2602/ParseExcel.pm verwendet, das sieht bei mir wie folgt aus:

    #!/usr/bin/perl

    use strict;
        use Spreadsheet::ParseExcel;

    print "Content-Type: text/html\n\n";

    my $oExcel = new Spreadsheet::ParseExcel;

    #1.1 Normal Excel 2000
        my $oBook = $oExcel->Parse('test.xls');
        my($iR, $iC, $oWkS, $oWkC);
        print "FILE  :", $oBook->{File} , "\n";
        print "COUNT :", $oBook->{SheetCount} , "\n";
        print "AUTHOR:", $oBook->{Author} , "\n";
        for(my $iSheet=0; $iSheet < $oBook->{SheetCount} ; $iSheet++) {
            $oWkS = $oBook->{Worksheet}[$iSheet];
            print "--------- SHEET:", $oWkS->{Name}, "\n";
            for(my $iR = $oWkS->{MinRow} ;
                    defined $oWkS->{MaxRow} && $iR <= $oWkS->{MaxRow} ; $iR++) {
                for(my $iC = $oWkS->{MinCol} ;
                                defined $oWkS->{MaxCol} && $iC <= $oWkS->{MaxCol} ; $iC++) {
                    $oWkC = $oWkS->{Cells}[$iR][$iC];
                    print "( $iR , $iC ) =>", $oWkC->Value, "\n" if($oWkC);  # Formatted Value
                    print "( $iR , $iC ) =>", $oWkC->{Val}, "\n" if($oWkC);  # Original Value
                }
            }
        }

    Wenn jetzt _keine_test.xls im selben Verzeichnis liegt wird

    FILE : COUNT : AUTHOR:

    ausgegeben, wenn aber eine Excel2000 Datei im Verzeichnis liegt, dann bleibt die Seite leer! NIX! gar nix.

    Wie kommt das? Das Modul ist jedenfalls verfügbar, nur die PERL Version ist etwas älter, Version 5.00503

    Hat jemand ne Idee was das sein könnte? Ich habe mehrere Dateien ausprobiert, auch eine open-office Export Datei.

    Grüße
    Andreas

    1. Halihallo Andreas

      [...]

      Wenn jetzt _keine_test.xls im selben Verzeichnis liegt wird
      FILE : COUNT : AUTHOR:
      ausgegeben,

      soweit wäre das noch OK.

      wenn aber eine Excel2000 Datei im Verzeichnis liegt, dann bleibt die Seite leer! NIX! gar nix.

      Hm. Das jedoch ist etwas faszinierender. Du rufst das Script über's Web auf ja? - Also Webserver als CGI-Script... Könnte mir nur vorstellen, dass es mit einem die stirbt... Wobei du dann ein 500 kassieren solltest. Könnte auch sein, dass nur warnungen ausgegeben werden => Weblog.

      Tip: Geb mal einige print's aus, einfach print 'step1...' ... pring 'step n'... so kannst du eventuell herausfinden in welcher Zeile es "hängen" bleibt. Eventuell kannst du auch folgendes an den Script anfang hängen:

      BEGIN {
         close(STDERR);
         open( STDERR, '>>error_log.log' );
      }

      END {
         close STDERR;
      }

      so werden eventuelle warn und Fehlermeldungen in die Datei geschrieben. Es kommt etwas auf die Webserverkonf. an, ob die Daten an STDERR ausgegeben (an den Client) werden, oder nicht. Zudem ist die Ausgabe STDERR und STDOUT asynchron => könnte sein, dass der Webserver das Socket schliesst, bevor STDERR gesendet wurde => mit dem oben genannten "Trick" kannst du die Meldungen der Datei entnehmen (alle, auch wenn das Socket schon geschlossen wurde => ist ja wurscht, da alles in die Datei umgeleitet wird).

      Zudem: Bei Webservern und Scripts im Teststadium kann ich nur

      use CGI::Carp qw(fatalsToBrowser);

      empfehlen => beim die wird dann die Fehlermeldung an den Client gesendet (Software-error, 'keine Datei gefunden at test.pl, line xxx')

      Wie kommt das? Das Modul ist jedenfalls verfügbar, nur die PERL Version ist etwas älter, Version 5.00503

      Schätze mal, dass das damit funktionieren sollte, weiss ich aber nicht mit sicherheit.

      Viele Grüsse

      Philipp

      1. Hallo Philipp!

        Danke Dir, jetzt bin ich schon einen Schritt weiter(ja, ich rufe das über den Browser auf):

        Erst nochmal (den Anfang ) des aktuellen Scripts:

        #!/usr/bin/perl

        use strict;
            use CGI::Carp qw(fatalsToBrowser);
            use Spreadsheet::ParseExcel;

        print "Content-Type: text/html\n\n";

        print "pos 1<br>\n";
            my $oExcel = new Spreadsheet::ParseExcel;

        print "pos 2<br>\n";
            #1.1 Normal Excel2000
            my $oBook = $oExcel->Parse('test.xls');
            my($iR, $iC, $oWkS, $oWkC);

        print "pos 3<br>\n";
            print "FILE  :", $oBook->{File} , "\n";
            print "COUNT :", $oBook->{SheetCount} , "\n";
            print "AUTHOR:", $oBook->{Author} , "\n";

        [...]

        Also, ausgegeben wird mir jetzt:

        pos 1
        pos 2
        Content-type: text/html
        Software error:

        Error PPS:0  at /usr/lib/perl5/site_perl/5.005/OLE/Storage_Lite.pm line 43.

        For help, please send mail to the webmaster...

        Wie kommt das? Das Modul ist jedenfalls verfügbar, nur die PERL Version ist etwas älter, Version 5.00503

        Schätze mal, dass das damit funktionieren sollte, weiss ich aber nicht mit sicherheit.

        Wenns nicht ginnge hätten die das wohl kaum installiert, oder? Also sollte das Problem woanders liegen!

        Aber schonmal Danke für Deine Hilfe, ich wußte wirklich kein Stück weiter!

        Grüße
        Andreas

        1. Halihallo Andreas

          pos 1
          pos 2
          Content-type: text/html
          Software error:

          Error PPS:0  at /usr/lib/perl5/site_perl/5.005/OLE/Storage_Lite.pm line 43.

          Au waja... Kann doch nicht sein, dass dein Excel-Parser auf OLE zugreift??? - Das wär nämlich ziemlich unmöglich auf linux-Systemen. OLE gibt's IMO nur für Win.

          Ne, hab's grad nachgeschaut: Das Problem entsteht hier:

          <quote aus="OLE/Storage_Lite.pm">
          sub new ($$$$$$$$$$;$$) {
          #1. Constructor for General Usage
            my($sClass, $iNo, $sNm, $iType, $iPrev, $iNext, $iDir,
               $raTime1st, $raTime2nd, $iStart, $iSize, $sData, $raChild) = @_;

          if($iType == OLE::Storage_Lite::PpsType_File()) { #FILE
              return OLE::Storage_Lite::PPS::File->_new
                  ($iNo, $sNm, $iType, $iPrev, $iNext, $iDir, $raTime1st, $raTime2nd,
                   $iStart, $iSize, $sData, $raChild);
            }
            elsif($iType == OLE::Storage_Lite::PpsType_Dir()) { #DIRECTRY
              return OLE::Storage_Lite::PPS::Dir->_new
                  ($iNo, $sNm, $iType, $iPrev, $iNext, $iDir, $raTime1st, $raTime2nd,
                   $iStart, $iSize, $sData, $raChild);
            }
            elsif($iType == OLE::Storage_Lite::PpsType_Root()) { #ROOT
              return OLE::Storage_Lite::PPS::Root->_new
                  ($iNo, $sNm, $iType, $iPrev, $iNext, $iDir, $raTime1st, $raTime2nd,
                   $iStart, $iSize, $sData, $raChild);
            }
            else {
              die "Error PPS:$iType $sNm\n";
            }
          }
          </quote>

          Aber was hier nun flasch ist, bzw. von wo diese Stelle aufgerufen wird kann ich leider nicht sagen. Aber ich könnte mir gut vorstellen, dass du dennoch irgendwo im Script einen Fehler hast (gefunden hab ich ihn nicht), denn ich würde mal darauf Tippen, dass zwischen dem Parser und diesem OLE-Modul keine Fehler entstehen ohne Grund. Hast du ein Referenzbeispiel, wo du nachsehen könntest, ob du irgendwas falsch verwendest? - Irgendwas passt da mit dem iType (was immer das auch ist ;)) nicht.

          Wenns nicht ginnge hätten die das wohl kaum installiert, oder? Also sollte das Problem woanders liegen!

          Jup.

          Viele Grüsse

          Philipp

          1. Halihallo Andreas

            [quotings]

            Hm. Ich hab's bis auf die Methode Parse zurückgeführt. Ein Blick in die Doku:

            <docu>
            =item I<$sFileName>

            name of the file to parse

            From 0.12 (with OLE::Storage_Lite v.0.06),
            scalar reference of file contents (ex. $sBuff) or
            IO::Handle object (inclucdng IO::File etc.) are also available.
            </docu>

            Naja, also hier sei anzumerken, dass das Script bei mir funktioniert (bis und _mit_ Stoppoint 3). Aber du kannst ja versuchen, den Content der Datei zu übergeben (als Referenz) und nicht den Dateinamen, eventuell funktioniert's dann (kann mir zwar nicht ausmalen, was das ändern sollte)??? - Ich sehe noch immer keinen Fehler im Script (entweder ich bin auch Fehlerblind oder es gibt wirklich keinen Fehler; eventuell hat dein Webspaceprovider eine veraltete Version von ParseExcel online???). Kann leider nicht weiter helfen ;-(

            Viele Grüsse

            Philipp

            1. From 0.12 (with OLE::Storage_Lite v.0.06),
              scalar reference of file contents (ex. $sBuff) or
              IO::Handle object (inclucdng IO::File etc.) are also available.
              </docu>

              BTW: was heisst denn "inclucdng" :-))

              Viele Grüsse

              Philipp

              1. From 0.12 (with OLE::Storage_Lite v.0.06),
                scalar reference of file contents (ex. $sBuff) or
                IO::Handle object (inclucdng IO::File etc.) are also available.
                </docu>

                BTW: was heisst denn "inclucdng" :-))

                Hm, ich habe mal meinen Support bemüht, mal schaun was da raus kommt, was mich halt wundert, das Beispiel war original so von CPAN, ich habe lediglich den Dateipfad angepasst. Wenn das nicht funktioniert - was dann?

                Danke Dir jedenfalls`für Deine Hilfe!

                Grüße
                Andreas

                1. Hallo,

                  Hm, ich habe mal meinen Support bemüht, mal schaun was da raus kommt, was mich halt wundert, das Beispiel war original so von CPAN, ich habe lediglich den Dateipfad angepasst. Wenn das nicht funktioniert - was dann?

                  Hmm, wie hast Du denn di eExceldatei hochgeladen? Wenn Du das im ASCII-Modus gemacht hast, kracht wahrscheinlich der Parser, bzw. Storage_Lite, ab, weil das Fileformat durcheinander gekommen ist. Ist nur so eine Vermutung.

                  Oder vielleicht stimmen die Permissions nicht.

                  Ich würde an Deiner stelle einaml ein Script schreiben, welches nicht über dem Webserver gestartet wird, sondern einfahc über die Shell.
                  Erst wenn Du dort keine Probleme mehr hast, solltest Du den Webserver wieder ins Spiel bringen.

                  Grüße
                    Klaus

                  1. Hi Klaus!

                    Hmm, wie hast Du denn di eExceldatei hochgeladen? Wenn Du das im ASCII-Modus gemacht hast, kracht wahrscheinlich der Parser, bzw. Storage_Lite, ab, weil das Fileformat durcheinander gekommen ist. Ist nur so eine Vermutung.

                    ... das darf nicht wahr sein! Du hast absolut Recht! Ich bin das gar nicht gewohnt das immer umzustellen... hoffentlich war mir das mal eine Lehre ;-)

                    Danke Dir!

                    Grüße
                    Andreas

                    1. Hallo,

                      ... das darf nicht wahr sein! Du hast absolut Recht! Ich bin das gar nicht gewohnt das immer umzustellen... hoffentlich war mir das mal eine Lehre ;-)

                      Erfahrung heißt, daß man schon so oft so viele Fehler gemacht hat, daß man bei der Suche nach dem eigentlichen Problem eine Latte an Möglichkeiten weiß, warum etwas nicht so funktioniert, wie es sollte.

                      Und daß man triviale Ursachen außen vor läßt, ist leider auch eine Tatsache. Ich habe heuer 3 Wochen, zwar nicht dauernd, aber doch, nach einem Fehler gesucht, der sporadisch in einem Programm (in C++) aufgetreten ist. Und was war's letztendlich? Eine Division durch 0, die nicht abgefangen wurde. Mist verd...., und ich dachte, daß mir dieser Fehler nicht mehr passiert:-(

                      Grüße
                        Klaus

                      1. PS: Weißt Du, was die erste Frage der DEC-Hotline an den Anrufer war?

                        'Liefert das Kraftwerk Strom?' *g*

                    2. Halihallo Andreas

                      Hmm, wie hast Du denn di eExceldatei hochgeladen? Wenn Du das im ASCII-Modus gemacht hast, kracht wahrscheinlich der Parser, bzw. Storage_Lite, ab, weil das Fileformat durcheinander gekommen ist. Ist nur so eine Vermutung.

                      ... das darf nicht wahr sein! Du hast absolut Recht! Ich bin das gar nicht gewohnt das immer umzustellen... hoffentlich war mir das mal eine Lehre ;-)

                      Na, war bei mir net anders: Hätt ich eigentlich auch riechen können, aber was hab ich gemacht? - Ich hab mir den Sourcecode von irgendwelchen Modulen angeschaut, um dir behilflich zu sein ;-)
                      Naja, beide drauf reingefallen ;-)
                      Klaus hat absolut recht... PS: Klaus: Mein Mathelehrer hat _immer_ folgendes gesagt (und zwar ca. 2 Mal pro Lektion, das ganze Semester lang):

                      "Mathematik ist wichtig! - Stellt euch vor, einer berechnet nicht die 0-Stellen der Funktion, was passiert? - Division durch null und das ganze Netzwerk stürtzt ab"... Darauf immer der vorlaute kleine Hasenfratz: "blödsinn, Herr xy, wegen dem stürtzt kein Netzwerk ab"... Mitlerweilen weiss ich, dass beide recht hatten ;-)

                      Viele Grüsse

                      Philipp

                      1. Hallo,

                        Na, war bei mir net anders: Hätt ich eigentlich auch riechen können, aber was hab ich gemacht? - Ich hab mir den Sourcecode von irgendwelchen Modulen angeschaut, um dir behilflich zu sein ;-)

                        Naja, bevor ich das Posting abschickte, habe ich doch noch schnell einmal auf dem Linuxrechner, mit dem ich gerade arbeitete, die Spreadsheet-Module installiert, um zu sehen, ob es das sein konnte. Man weiß ja nie;-)

                        "Mathematik ist wichtig! - Stellt euch vor, einer berechnet nicht die 0-Stellen der Funktion, was passiert? - Division durch null und das ganze Netzwerk stürtzt ab"... Darauf immer der vorlaute kleine Hasenfratz: "blödsinn, Herr xy, wegen dem stürtzt kein Netzwerk ab"... Mitlerweilen weiss ich, dass beide recht hatten ;-)

                        Mit dem nötigen Abstand lerne ich immer wieder die Lektionen meines Mathematikprofessors schätzen.[1] Obwohl er so etwas nie sagte. Das kann daran liegen, weil Netzwerke zu der Zeit nicht so verbreitet waren.

                        Aber wen meinst Du mit 'beide'? *g*

                        Grüße
                          Klaus

                        [1] Naja, eigentlich ich habe es auch damals geschätzt.

                        1. Hallo!

                          Ich wollte mich doch nochmal bei Euch beiden bedanken! Das ist wirklich nicht selbstverständlich wie Ihr mir geholfen habt!
                          Ich jedenfalls habe meine Lektion gelernt und weiß jetzt zusätzlich noch, wie ich an vernünftige Fehlermeldungen komme!

                          Danke Euch!

                          Viele Grüße
                          Andreas