perle6: Spreadsheet::WriteExcel in bestehende Datei

Hallo,

ich habe folgendes Problem. Ich möchte Daten eines HTML-Formulars in eine Excel-Datei speichern. Ich habe gelesen, das man mit "Spreadsheet::WriteExcel" eine Exceldatei erzeugen kann. Das habe ich auch probiert, und es funktionierte. Nun soll aber zur bestehenden Datei weitere Datensätze eingefügt werden. Wenn also wieder ein Besucher das Formular ausgefüllt hat, sollen die Daten zur bestehenden Excel-Datei hinzugefügt werden. Leider habe ich noch keinen Lösungsweg gefunden. Mit "Spreadsheet::WriteExcel" wird die bestehende Datei immer wieder überschrieben. Gibt es hier eine Lösung ? Wenn ja, welche ?

Beide Module "Spreadsheet::WriteExcel" und "Spreadsheet::ParseExcel" sind bereits installiert.

Vielen Dank schon mal !

  1. Halihallo

    ich habe folgendes Problem. Ich möchte Daten eines HTML-Formulars in eine Excel-Datei speichern. Ich habe gelesen, das man mit "Spreadsheet::WriteExcel" eine Exceldatei erzeugen kann. Das habe ich auch probiert, und es funktionierte. Nun soll aber zur bestehenden Datei weitere Datensätze eingefügt werden. Wenn also wieder ein Besucher das Formular ausgefüllt hat, sollen die Daten zur bestehenden Excel-Datei hinzugefügt werden. Leider habe ich noch keinen Lösungsweg gefunden. Mit "Spreadsheet::WriteExcel" wird die bestehende Datei immer wieder überschrieben. Gibt es hier eine Lösung ? Wenn ja, welche ?

    Beide Module "Spreadsheet::WriteExcel" und "Spreadsheet::ParseExcel" sind bereits installiert.

    Perfekt. Mit ParseExcel einlesen und mit WriteExcel wieder überschreiben (mit den neuen _und_ alten Daten). Oder
    Spreadsheet::ParseExcel::SaveParser verwenden; dort kann man parsen, bearbeiten und wieder speichern in einem.

    Viele Grüsse

    Philipp

    1. Halihallo

      ich habe folgendes Problem. Ich möchte Daten eines HTML-Formulars in eine Excel-Datei speichern. Ich habe gelesen, das man mit "Spreadsheet::WriteExcel" eine Exceldatei erzeugen kann. Das habe ich auch probiert, und es funktionierte. Nun soll aber zur bestehenden Datei weitere Datensätze eingefügt werden. Wenn also wieder ein Besucher das Formular ausgefüllt hat, sollen die Daten zur bestehenden Excel-Datei hinzugefügt werden. Leider habe ich noch keinen Lösungsweg gefunden. Mit "Spreadsheet::WriteExcel" wird die bestehende Datei immer wieder überschrieben. Gibt es hier eine Lösung ? Wenn ja, welche ?

      Beide Module "Spreadsheet::WriteExcel" und "Spreadsheet::ParseExcel" sind bereits installiert.

      Perfekt. Mit ParseExcel einlesen und mit WriteExcel wieder überschreiben (mit den neuen _und_ alten Daten). Oder
      Spreadsheet::ParseExcel::SaveParser verwenden; dort kann man parsen, bearbeiten und wieder speichern in einem.

      Viele Grüsse

      Philipp

      Hi Philipp,

      danke für die schnelle Antwort. Eigentlich bin ich noch Anfänger in Sachen Perl. Vielleicht kannst du mir mit ein paar Zeilen Quelltext auf die Sprünge helfen ? :-)
      Das wäre echt spitze !!!

      Vielen Dank.

      Gruß
      Dirk

      1. Hi!

        danke für die schnelle Antwort. Eigentlich bin ich noch Anfänger in Sachen Perl. Vielleicht kannst du mir mit ein paar Zeilen Quelltext auf die Sprünge helfen ? :-)

        bei CPAN stehen einige Beispiele:
        http://search.cpan.org/author/KWITKNR/Spreadsheet-ParseExcel-0.2602/ParseExcel.pm
        http://search.cpan.org/author/JMCNAMARA/Spreadsheet-WriteExcel-0.39/WriteExcel.pm
        http://search.cpan.org/author/KWITKNR/Spreadsheet-ParseExcel-0.2602/ParseExcel/SaveParser.pm

        Grüße
        Andreas

        1. Hi!

          danke für die schnelle Antwort. Eigentlich bin ich noch Anfänger in Sachen Perl. Vielleicht kannst du mir mit ein paar Zeilen Quelltext auf die Sprünge helfen ? :-)
          bei CPAN stehen einige Beispiele:
          http://search.cpan.org/author/KWITKNR/Spreadsheet-ParseExcel-0.2602/ParseExcel.pm
          http://search.cpan.org/author/JMCNAMARA/Spreadsheet-WriteExcel-0.39/WriteExcel.pm
          http://search.cpan.org/author/KWITKNR/Spreadsheet-ParseExcel-0.2602/ParseExcel/SaveParser.pm

          Grüße
          Andreas

          Vielen Dank an alle ! Ich werde mich mal durch den Quelltext arbeiten.
          Mal sehen, was rauskommt. Wer noch mehr Vorschläge hat, nur zu !

          Grüße
          Dirk

          1. Halihallo Dirk

            Vielen Dank an alle ! Ich werde mich mal durch den Quelltext arbeiten.
            Mal sehen, was rauskommt. Wer noch mehr Vorschläge hat, nur zu !

            Du willst noch mehr? - Nun denn. Dir werd ichs geben du!!! :-))

            läuft leider nur auf Win-Systemen (M$ OLE), aber wär auch ne Lösung.

            Viele Grüsse

            Philipp

            Use OLE to control MS Excel.

            use OLE;

            Create an instance of Excel.

            $app = CreateObject OLE "Excel.Application" ||
             die "Unable to open Excel.";

            Make application visible.

            $app->{'Visible'} = 1;

            Create a new workbook.

            $app->Workbooks->Add();

            Set values in a "range".

            $app->Range("A1")->{'Value'} = "Developer";
            $app->Range("B1")->{'Value'} = "Bugs";

            $app->Range("B2")->{'Value'} = "Assigned";
            $app->Range("C2")->{'Value'} = "Fixed";

            $app->Range("A3")->{'Value'} = "Eric J.";
            $app->Range("B3")->{'Value'} = 10;
            $app->Range("C3")->{'Value'} = 10;

            $app->Quit();

            Leave Excel running. USe $app->Quit() to exit.

            msexcel.pl

            1. Halihallo Dirk

              Vielen Dank an alle ! Ich werde mich mal durch den Quelltext arbeiten.
              Mal sehen, was rauskommt. Wer noch mehr Vorschläge hat, nur zu !

              Du willst noch mehr? - Nun denn. Dir werd ichs geben du!!! :-))

              läuft leider nur auf Win-Systemen (M$ OLE), aber wär auch ne Lösung.

              Viele Grüsse

              Philipp

              Use OLE to control MS Excel.

              use OLE;

              Create an instance of Excel.

              $app = CreateObject OLE "Excel.Application" ||
              die "Unable to open Excel.";

              Make application visible.

              $app->{'Visible'} = 1;

              Create a new workbook.

              $app->Workbooks->Add();

              Set values in a "range".

              $app->Range("A1")->{'Value'} = "Developer";
              $app->Range("B1")->{'Value'} = "Bugs";

              $app->Range("B2")->{'Value'} = "Assigned";
              $app->Range("C2")->{'Value'} = "Fixed";

              $app->Range("A3")->{'Value'} = "Eric J.";
              $app->Range("B3")->{'Value'} = 10;
              $app->Range("C3")->{'Value'} = 10;

              $app->Quit();

              Leave Excel running. USe $app->Quit() to exit.

              msexcel.pl

              Hallo Philipp,

              habe das Programm ausprobiert. Funktioniert, aber es soll eigentlich nicht das Excelprogramm beim Benutzer geöffnet werden. Die Exceldatei liegt ja auf dem Webserver. Nur der Webmaster hat darauf Zugriff.
              Ich habe aber diese Lösung:

              use strict;
                  use Spreadsheet::ParseExcel::SaveParser;
                  my $oExcel = new Spreadsheet::ParseExcel::SaveParser;
                  my $oBook = $oExcel->Parse('test.xls');

              # Anzahl der Reihen (Datensätze) ermitteln
                  # ??????

              # Update / Daten hinzufügen
                  $oBook->AddCell(0, 2, 2, 'Wert1'),
                  $oBook->AddCell(0, 1, 1, 'Wert2');

              # Speichern
                  $oExcel->SaveAs($oBook, 'temp.xls'); # in neue Datei
                  $oExcel->SaveAs($oBook, 'test.xls'); # oder Datei überschreiben

              Jetzt aber noch ein kleines Problem. Ich brauche noch die Anzahl der Reihen ( Datensätze ) die schon vorhanden sind. Hatte da schon was probiert, funktionierte aber nicht. Kannst du helfen ?

              Gruß
              Dirk

              1. Halihallo Dirk

                habe das Programm ausprobiert. Funktioniert, aber es soll eigentlich nicht das Excelprogramm beim Benutzer geöffnet werden.

                Tut's auch nicht. Es startet eine Excel-Instanz auf dem Computer, wo das Script ausgeführt wird, in dem Falle auf deinem Webserver (voraussetzung er ist ein WinRechner).

                Jetzt aber noch ein kleines Problem. Ich brauche noch die Anzahl der Reihen ( Datensätze ) die schon vorhanden sind. Hatte da schon was probiert, funktionierte aber nicht. Kannst du helfen ?

                ParseExcel bzw. SaveParser gibt dir ein $book zurück, welches verschiedene Worksheets enthält. Bei dem ersten Worksheet kannst du auf die einzelnen Zellen zugreifen:

                $aCell = $worksheet->{Cells}[$iR][$iC];

                Der Wert davon : $aCell->Value (formatiert) oder $aCell->{Val} (unformatiert).

                Mir fällt nur die Lösung ein, dass du über Zeilen (ggf. Spalten) iterierst und solange die Zellen abgrast, bis kein Wert mehr enthalten ist (undef => if (defined($oCell->{Val})), nicht ''!); dann hast du die Grenze gefunden.

                Viele Grüsse

                Philipp

                1. Halihallo Dirk

                  Mir fällt nur die Lösung ein, dass du über Zeilen (ggf. Spalten) iterierst und solange die Zellen abgrast, bis kein Wert mehr enthalten ist (undef => if (defined($oCell->{Val})), nicht ''!); dann hast du die Grenze gefunden.

                  Würg, wie unschö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++) {
                        ## mach was mit [$iR, $iC]...
                     }
                  }

                  ich sollte mir erst die Doku ansehen, bevor ich was schreib... sorry.

                  Viele Grüsse

                  Philipp

                  1. Halihallo Dirk

                    Mir fällt nur die Lösung ein, dass du über Zeilen (ggf. Spalten) iterierst und solange die Zellen abgrast, bis kein Wert mehr enthalten ist (undef => if (defined($oCell->{Val})), nicht ''!); dann hast du die Grenze gefunden.

                    Würg, wie unschö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++) {
                          ## mach was mit [$iR, $iC]...
                       }
                    }

                    ich sollte mir erst die Doku ansehen, bevor ich was schreib... sorry.

                    Viele Grüsse

                    Philipp

                    Hallo Philipp,

                    sorry, funktioniert irgendwie nicht.
                    Vielleicht noch mal eine genauere Beschreibung:

                    Ich brauche die genaue Anzahl der schon vorhandenen Datensätze, nehmen wir mal $AnzDS. Wenn ich den nächsten Datensatz schreibe, dann sieht das so aus:
                    $oBook->AddCell(0, $AnzDs, 1, 'Wert1');

                    So würde dann jeder Datensatz an den nächsten angefügt, Reihe für Reihe. Aber wie ?
                    Ich weiß, ich bin lästig. :-))))))))

                    Gruß
                    Dirk

                    1. Halihallo Dirk

                      Mir fällt nur die Lösung ein, dass du über Zeilen (ggf. Spalten) iterierst und solange die Zellen abgrast, bis kein Wert mehr enthalten ist (undef => if (defined($oCell->{Val})), nicht ''!); dann hast du die Grenze gefunden.

                      Würg, wie unschö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++) {
                            ## mach was mit [$iR, $iC]...
                         }
                      }

                      ich sollte mir erst die Doku ansehen, bevor ich was schreib... sorry.

                      Viele Grüsse

                      Philipp

                      Hallo Philipp,

                      sorry, funktioniert irgendwie nicht.
                      Vielleicht noch mal eine genauere Beschreibung:

                      Ich brauche die genaue Anzahl der schon vorhandenen Datensätze, nehmen wir mal $AnzDS. Wenn ich den nächsten Datensatz schreibe, dann sieht das so aus:
                      $oBook->AddCell(0, $AnzDs, 1, 'Wert1');

                      So würde dann jeder Datensatz an den nächsten angefügt, Reihe für Reihe. Aber wie ?
                      Ich weiß, ich bin lästig. :-))))))))

                      Gruß
                      Dirk

                      Hallo noch mal,

                      Problem selbst gelöst. Vielen Dank noch mal, für die gute Zusammenarbeit !
                      Hier meine Lösung:

                      Anzahl der Reihen (Datensätze) ermitteln

                      my($iR, $oWkS, $az);
                          $oWkS = $oBook->{Worksheet}[0];

                      for(my $iR = $oWkS->{MinRow} ;
                               defined $oWkS->{MaxRow} && $iR <= $oWkS->{MaxRow} ; $iR++) {
                                  $az++; # Anzahl der vorhandenen Datensätze
                           }

                      Viele Grüße
                      Dirk

                      1. Halihallo Dirk

                        Ich weiß, ich bin lästig. :-))))))))

                        Es gibt schlimmere! :-))

                        Problem selbst gelöst.

                        Das hört man am liebsten *g*

                        Vielen Dank noch mal, für die gute Zusammenarbeit !

                        War das jetzt eine Kritik? :-)

                        Anzahl der Reihen (Datensätze) ermitteln

                        my($iR, $oWkS, $az);
                            $oWkS = $oBook->{Worksheet}[0];

                        for(my $iR = $oWkS->{MinRow} ;
                                 defined $oWkS->{MaxRow} && $iR <= $oWkS->{MaxRow} ; $iR++) {
                                    $az++; # Anzahl der vorhandenen Datensätze
                             }

                        Perfektissimo! und Gratulation...

                        Viele Grüsse

                        Philipp

                        PS: http://www.learn.to/quote : nicht immer das ganze Posting stehen lassen bitte, sondern nur die Zeilen, auf die du dich äusserst (ich versuchte mal als gutes Beispiel voranzugehen :-)) THX.

                2. Hallo,

                  Tut's auch nicht. Es startet eine Excel-Instanz auf dem Computer, wo das Script ausgeführt wird, in dem Falle auf deinem Webserver (voraussetzung er ist ein WinRechner).

                  Das ist auch der GRund, warum ich Spreadsheet::* vorziehen würde. Da benötigst Du kein Excel, nicht einmal Windows ist notwendig.

                  Grüße
                    Klaus

                  1. Halihallo Klaus

                    Tut's auch nicht. Es startet eine Excel-Instanz auf dem Computer, wo das Script ausgeführt wird, in dem Falle auf deinem Webserver (voraussetzung er ist ein WinRechner).

                    Das ist auch der GRund, warum ich Spreadsheet::* vorziehen würde. Da benötigst Du kein Excel, nicht einmal Windows ist notwendig.

                    Für was für einen Menschen hälst du mich? :-)
                    Das einzige, wo ich OLE verwende ist implizit durch ASP und selbst dieses verwende ich nur noch all Schaltjahr. ;)

                    Viele Grüsse

                    Philipp

              2. Hallo,

                Jetzt aber noch ein kleines Problem. Ich brauche noch die Anzahl der Reihen ( Datensätze ) die schon vorhanden sind. Hatte da schon was probiert, funktionierte aber nicht. Kannst du helfen ?

                Wenn Du Dir das Beispiel von Spreadsheet::ParseExcel durchgesehen hättest, wäre Dir sicherlich $oWkS->{MaxRow} bzw auch $oWkS->{MinRow} aufgefallen. Ersteres enthält die größte verwendete Zeilenummer und letzteres die kleinset verwendete Zeilennummer (siehe auch in der Doku).
                die Anzahl ermittelt sich aus der Differenz der beiden Werte, wobei jedoch glaube, daß $oWkS->{MaxRow} der von Dir gesuchte Wert ist, da Du wahrscheinlich in $oWkS->{MaxRow}+1 etwas schreiben willst.

                Grüße
                  Klaus

                1. Hallo!

                  Wenn Du Dir das Beispiel von Spreadsheet::ParseExcel durchgesehen hättest, wäre Dir sicherlich $oWkS->{MaxRow} bzw auch $oWkS->{MinRow} aufgefallen. Ersteres enthält die größte verwendete Zeilenummer und letzteres die kleinset verwendete Zeilennummer (siehe auch in der Doku).
                  die Anzahl ermittelt sich aus der Differenz der beiden Werte, wobei jedoch glaube, daß $oWkS->{MaxRow} der von Dir gesuchte Wert ist, da Du wahrscheinlich in $oWkS->{MaxRow}+1 etwas schreiben willst.

                  Das ist ja alles schön und gut, habe aber die ERfahrung gemacht, wenn das Excel-Sheet nicht absolut neu ist, oder mal was an den Feldgrößen oder was weiß ich veändert wurde, dann erkennt er so nicht merh das ende, daher habe ich das mit einer Schleife und iener regEx gemacht, die auf \w prüft.

                  Grüße
                  Andreas

      2. Vielleicht kannst du mir mit ein paar Zeilen Quelltext auf die Sprünge helfen ? :-)

        http://search.cpan.org/author/KWITKNR/Spreadsheet-ParseExcel-0.2602/ParseExcel/SaveParser.pm