Möglichkeiten von Py, Umstieg evtl. der bessere Weg?

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
python21
User
Beiträge: 18
Registriert: Dienstag 21. September 2010, 14:36

Hi, würde gerne eine Einschätzung von Eurer Seite haben, um den richtigen Weg zu finden.
Für einen monatlichen DV-Job habe ich mir ein Script mit Python 3 erstellt. (Selbsteinschätzung: Anfänger mit Excel/Access-Kenntnissen und die Gabe, Lösungen zu finden auch wenn diese umständlich sind). Diesen kann ich zu 70 % per Python durchführen, vom Code kann ich vieles noch besser machen, Funktionen einbauen etc. Ich möchte jetzt die letzten 30% auch noch automatisieren. Und danach noch optimieren (den bisherigen Codeumfang reduzieren).

Aufgabe und Problembeschreibung:
Ich muss aus einer Excel-Tabelle Daten auslesen, daraus erstelle ich Druckproduktions-Daten und generiere Daten für die Dokumenterstellung (Lieferscheine; Produktionslisten etc.). Diese werden dann wieder als Excel-Tabelle bzw. die Lieferscheine als PDF-Dokument erstellt.

Die größte Hürde ist die Excel -Tabelle. In manchen Felder sind alle mögliche Satztrennungszeichen (Feste Umbrüche, Tabs, Semikolon etc) enthalten, welche dann bei der Umwandlung in CSV bzw. TXT zu einer fehlerhaften Struktur führen. Dieses löse ich direkt in Excel und wandle diese Zeichen um... (z.B. Zeichen 10 und 12 durch ein Leerzeichen ersetzen. Die zu vielen Leerzeichen werden dann mit der "Glätten"-Funktion bereiniget. Danach speichere ich diese Tabelle als CSV und danach wandle diese in txt um. Mit dem Speichern als CSV habe ich das Semikolon als Feldtrenner. Das umwandlen in TXT ist nur eine Vorsichtsmaßnahme). Wnn ich versehentlich die CSV aufmache, werden die Datenfelder mit einer führenden Null nicht als Text erkannt sondern als Zahl und "bereinigt" die führende Null. Beispiel. PLZ mit 01067 (Dresden) ist dann nur 1067.
Jetzt möchte ich diese manulle Vorgehen mit Python durchführen.
Frage zu diesem Punkt:
Kann es sein das für Python 3 noch kein Excel-Lib gibt? Muss ich dann mein Prog auf Python 2.x umwandeln. (xlrd-lib gibt es glaube ich dazu)
Kann man mit dieser Lib auch direkt auf Excel zugreifen bzw. auf die Feldinhalte.
Also Excel Tabelle öffnen, die fehlerhaften Satztrennzeichen in den Feldern umwandeln, zusätzliche Spalte einfügen und Befüllen und evtl. auch Sortierungen vornehmen usw.

Der zweite Punkt wäre die Dokument-Erstellung, am Ende als PDF. Im Moment gehe ich über die Serienbrief-Funktion von Word und speichere das erstellte Serienbrief-Dokument als PDF ab. Geht das evtl. auch mit Python?
Also direkt die Daten nehmen und ein PDF schreiben? Die PDF-Dokumente sind teilweise bis zu 800 Seiten (14 MB) groß. Auf jeder Seite kommt noch eine Firmenlogo mit drauf.
Ansonsten Text (Seriendruckfelder). Ich bin ja froh das dieses stabil über Word läuft... aber muss ich halt immer die neuen Daten verknüpfen, die Textdatei (spiele ich vorher noch in Excel ein, (Würde wohl auch mit Access besser gehen, aber die Macht der Gewohnheit/Dummheit :-)) Serienbrief-Funktion starten, umwandeln in PDF.
Habe schon was von reportlab gelesen, aber kann man damit auch Grafiken einfügen? Schafft das die OpenSoure-Version solch einen Dokumentenumfang?
Fragen zur PDF - Erstellung:
Was wäre jetzt der richtige Weg:
Umwandlen in Python 2.x, reportlab?
Oder sollte ich mir gleich Ironpython bzw. C# anschauen? Vermute mal das da der Zugriff besser geht.
Aber würde das gerne mit Python schaffen. Würde mich um ein Feedback freuen.
Grüße von python 21
(Python 3)
Darii
User
Beiträge: 1177
Registriert: Donnerstag 29. November 2007, 17:02

python21 hat geschrieben:Die größte Hürde ist die Excel -Tabelle. In manchen Felder sind alle mögliche Satztrennungszeichen (Feste Umbrüche, Tabs, Semikolon etc) enthalten, welche dann bei der Umwandlung in CSV bzw. TXT zu einer fehlerhaften Struktur führen.
Eigentlich escaped Excel diese Zeichen, du kannst dir das also alles sparen. Oder ich verstehe dein Problem nicht.
python21
User
Beiträge: 18
Registriert: Dienstag 21. September 2010, 14:36

Darii hat geschrieben:
python21 hat geschrieben:Die größte Hürde ist die Excel -Tabelle. In manchen Felder sind alle mögliche Satztrennungszeichen (Feste Umbrüche, Tabs, Semikolon etc) enthalten, welche dann bei der Umwandlung in CSV bzw. TXT zu einer fehlerhaften Struktur führen.
Eigentlich escaped Excel diese Zeichen, du kannst dir das also alles sparen. Oder ich verstehe dein Problem nicht.
Wäre ja schön wenn Excel das machen würde, könnte ich mir den ganzen Aufwand sparen. Aber ohne Bereinigung habe ich eine fehlerhafte Ausgabe. "Ausgabe" als CSV = die im Text enthalten ";" werde als Feldtrenner erkannt und das Feld wird getrennt. Somit bekomme ich dann statt 30 Felder 31... als txt geht auch nicht weil dann die festen Umbrüche innerhalb eines Feldes die Probleme bereite. Habe somit statt zb. 100 Zeilen dann mindestens pro fester Umbruch eine Zeile mehr.
Import in Access der gleiche Effekt.
Ich habe diese Excel in allen möglichen Varianten ausgegeben immer gab es eine fehlerhafte Ausgabe. Glaub mir sonst würde ich das nicht vor dem Export machen wollen. Würde das gerne über regular Express. abhandeln (ist glaube ich das richtige Thema dafür) aber dafür müsste ich ja auf die Excel-Tabelle zugreifen. (mit python). Ich vermute mal das ich dafür ironpython mich mal in ironpython einarbeiten muss.
Grüße von python 21
(Python 3)
BlackJack

@python21: Mir scheint nicht Excel ist das Problem, sondern das Programm, welches die CSV-Daten weiterverarbeiten will, wenn dieses Feldtrenner innerhalb von (geschützten) Feldern trotzdem zum Trennen verwendet. Denn Excel sollte das alles richtig machen! Gerade eben getestet — in Excel ohne irgendwelche besonderen Einstellungen als CSV gespeichert:

Code: Alles auswählen

hello;world;!
42;"hello
world";23
4711;"one; two; three";the end
Das ist eine Tabelle mit 3×3 Einträgen und sowohl der in der Mitte mit dem Zeilenumbruch als auch der unten Mitte mit Trennzeichen im Text sind korrekt escaped.

Mit Python eingelesen:

Code: Alles auswählen

In [113]: import csv

In [114]: with open('test.csv') as f:
   .....:     data = list(csv.reader(f, delimiter=';'))
   .....: 

In [115]: data
Out[115]: 
[['hello', 'world', '!'],
 ['42', 'hello\nworld', '23'],
 ['4711', 'one; two; three', 'the end']]
Jup, sind 3×3 Felder. Also ist Excel wohl eher nicht das Problem.

Edit: Das bedeutet übrigens, dass Du die mit Excel gespeicherte CSV-Datei mit Python nachbearbeiten kannst, wenn das weiterverarbeitende Programm nur eine Untermenge vom CSV-Format versteht.
python21
User
Beiträge: 18
Registriert: Dienstag 21. September 2010, 14:36

Hallo danke für die Info.
Ich habe meiner Tabelle mal reduziert und die Problemfälle in eine excel abgespeichert und als CSV ausgegeben.
Im Editior (notepad) habe ich mein bekanntes Problem. Umbrüche mitten im Datensatz und keine Escapen.
Allerdings wenn ich die Tabelle wieder als CSV in Excel öffne passt eigentlich alles, bis auf die Tatsache das meine Ostdeutschen PLZ-Adressen die fürhende Null verlieren.
Aus diesem Grund habe ich noch die Tabelle in txt umgewandelt mit dem Ergebnis das die Umbrüche falsch waren.
Kann es evtl. daran liegen das du die CSV-Felder alle als Text ausgibst? Also mit "". Irgendwie habe ich aber keine Möglichkeit zu sagen das er alles als Text deklarieren soll.. Im LibreOfffice frägt er speziell nach. aber Excel... muss mal die Optionen durchforsten.

Aber ich werde mal mein Python Script auf die CSV losjagen lassen. Mal sehen ob es trotzdem funktioniert.
Vielen Dank schon mal für Deine Mühe!
Grüße von python 21
(Python 3)
BlackJack

@python21: Umbrüche mitten im Datensatz ohne escapen kann ich nicht glauben. Das Feld ist tatsächlich nicht in " eingefasst?

Ob Text oder Zahl habe ich nicht explizit festgelegt. Das ein Feld mit einem Umbruch darin keine Zahl sein kann, erkennt Excel schon von alleine.

Wie sind denn die Postleitzahlen in Excel angelegt? Wenn die dort eine führende Null haben, dann muss es ja Text sein. Oder jemand hat tatsächlich die Formatvorlage für Zahlen entsprechend eingestellt. Letztendlich zeigt dass, das eine Tabellenkalkulation vielleicht nicht die richtige Anwendung für so etwas ist.
python21
User
Beiträge: 18
Registriert: Dienstag 21. September 2010, 14:36

Hey BlackJack.
Bin noch nicht dazugekommen. Muss mich leider beruflich umorientieren (interne). Habe mal aber schnell in meine Formel geschaut:
Handelt sich um die Zeichen 10 und 13 = fester Umbruch in einem Feld. Mit der Funktion wechseln(feld;Zeichen(59);",") haue ich auch die Semikolons um. Im Moment vermute ich mal die Text-Editior Programme hinter dem Fehler. Im Excel 2010 habe ich unter Optionen keinen Möglichkeit gefunden irgendwelche Exportfunktionen zu ändern, bzw. definieren. Teilweise wird die Überschrift mit "" und ohne "" ausgegeben. Über die Funktion zelle(Format) habe ich schon mal unterschiedliche Formatieren festgestellt. Standard, Text .0, also alles quer durch. Heute Abend werde ich mit Py über die CSV laufen... wäre schon klasse...!

Sonst noch einen Tipp für die PDF Erstellung?
Grüße von python 21
(Python 3)
Benutzeravatar
sparrow
User
Beiträge: 4164
Registriert: Freitag 17. April 2009, 10:28

@python21: Ich habe etwas Schwierigkeiten deinem letzten Post zu folgen.

Moch doch mal bitte folgendes:

1) Problematischen "Datensatz" in Excel anlegen
2) als CSV speichern
3) die Datei in Python laden und jede Zeile mit repr() ausgeben lassen (siehe Beispielcode)

Die Ausgabe dann bitte hier posten, damit wir nicht raten müssen ob deine Daten richtig formatiert sind. Wie BlackJack kann ich mir nicht vorstellen, dass bei dir außerhalb der Felder Zeilenumbrüche sind.

Beispielcode:

Code: Alles auswählen

with open("deineDatei") as f:
 for line in f:
  print(repr(f))
python21
User
Beiträge: 18
Registriert: Dienstag 21. September 2010, 14:36

Code: Alles auswählen

<_io.TextIOWrapper name='Versuch_csv.csv' encoding='cp1252'>
17 x
Grüße von python 21
(Python 3)
Benutzeravatar
sparrow
User
Beiträge: 4164
Registriert: Freitag 17. April 2009, 10:28

Ach Shit, ist natürlich Blödsinn:

Code: Alles auswählen

with open("deineDatei") as f:
 for line in f:
  print(repr(line))
Macht ja sonst keinen Sinn ;)
python21
User
Beiträge: 18
Registriert: Dienstag 21. September 2010, 14:36

Hi jack (sparrow),
danke für Deine Korrektur, habe schon die Hilfe-Ffunktion angeworfen.. war ein wenig verwirrt. Aber jetzt ist o.k. (Die Daten sind vom Inhalt von mir manipuliert da es sich teilweise um Adressdaten handelt... aber man kann sehen das "escaped" wird.) Habe mich also von der Sichtweise im Editor, Access bzw. Notepad++ blenden lassen. Hier das Ergebnis:

Code: Alles auswählen

'Feld 1;Feld 2;Feld 3;Feld 4;Feld 7;Feld 8;Feld 9;Feld10;Feld11;Feld12;Feld13;Feld14;"Feld \n'
'15";Feld16;Feld17;"Feld\n'
'18";"Feld\n'
'19";Feld20;;\n'
'123333;01070;Drüben;Straße 4;Firma;Straße 4, 01070 Drüben;1.087;Firma Verlag;Maier;Straße Verlag ;91665;Hausen/Dorf;17.10.2012;12:00 Uhr;20.10.2012;;"Montag - Freitag 08:00 Uhr - 16:00 Uhr;\n'
'sonst nur nach telefonischer Absprache mit Herrn  ";;;\n'
'99990;99085;Stolz;Straße 6;Firma;Straße 6, 99085 Stolz;1.497;Firma Verlag2;Schule;Straße Verlag ;87751;Woanders;17.10.2012;12:00 Uhr;20.10.2012;;"Montag - Freitag 07:00 Uhr - 17:00 Uhr;\n'
'sonst nur nach telefonischer Absprache mit Frau";;;\n'
'9999;12350;schönesland;Chaussee 500;Firma;Chaussee 500, 12350 Schönes Land;155;Firma Verlag3;Sommer;Straße Verlag ;54532;Dorf OT Felde;17.10.2012;12:00 Uhr;20.10.2012;;"LIeferannahme: \n'
'Montag-Dienstag: 07.00 bis 13.00 Uhr\n'
'Mittwoch-Donnerstag: : 07.00- 16.00 Uhr\n'
'Freitag 07.00- 08.00 Uhr";;;\n'
'111;13097;Woanders;Damm 1;Firma;Damm 1, 13097 Woanders;670;Firma Verlag4;"Winter\n'
'Gebäude 9 / Aufgang x / Erdgeschoss y";Straße Verlag ;43127;Weitweg;17.10.2012;12.00 Uhr;20.10.2012;;;;;\n'
'122112;91134;Heim;Alstoor 1;Firma;Alstoor 1, 91134 Heim;111;Firma Verlag5;Müller;Straße Verlag ;21174;Stadt/Land_Fluss;17.10.2012;12:00 Uhr;20.10.2012;;"Montag bis Freitag\n'
'08:00 Uhr - 18:00 Uhr  Frau";;;\n'
';;;;;;;;;;;;;;;;;;;\n'
Output:

BlackJack: deins hat (natürlich) auch funktioniert:

Code: Alles auswählen

[['Feld 1', 'Feld 2', 'Feld 3', 'Feld 4', 'Feld 7', 'Feld 8', 'Feld 9', 'Feld10', 'Feld11', 'Feld12', 'Feld13', 'Feld14', 'Feld \n15', 'Feld16', 'Feld17', 'Feld\n18', 'Feld\n19', 'Feld20', '', ''], ['123333', '01070', 'Drüben', 'Straße 4', 'Firma', 'Straße 4, 01070 Drüben', '1.087', 'Firma Verlag', 'Maier', 'Straße Verlag ', '91665', 'Hausen/Dorf', '17.10.2012', '12:00 Uhr', '20.10.2012', '', 'Montag - Freitag 08:00 Uhr - 16:00 Uhr;\nsonst nur nach telefonischer Absprache mit Herrn  ', '', '', ''], ['99990', '99085', 'Stolz', 'Straße 6', 'Firma', 'Straße 6, 99085 Stolz', '1.497', 'Firma Verlag2', 'Schule', 'Straße Verlag ', '87751', 'Woanders', '17.10.2012', '12:00 Uhr', '20.10.2012', '', 'Montag - Freitag 07:00 Uhr - 17:00 Uhr;\nsonst nur nach telefonischer Absprache mit Frau', '', '', ''], ['9999', '12350', 'schönesland', 'Chaussee 500', 'Firma', 'Chaussee 500, 12350 Schönes Land', '155', 'Firma Verlag3', 'Sommer', 'Straße Verlag ', '54532', 'Dorf OT Felde', '17.10.2012', '12:00 Uhr', '20.10.2012', '', 'LIeferannahme: \nMontag-Dienstag: 07.00 bis 13.00 Uhr\nMittwoch-Donnerstag: : 07.00- 16.00 Uhr\nFreitag 07.00- 08.00 Uhr', '', '', ''], ['111', '13097', 'Woanders', 'Damm 1', 'Firma', 'Damm 1, 13097 Woanders', '670', 'Firma Verlag4', 'Winter\nGebäude 9 / Aufgang x / Erdgeschoss y', 'Straße Verlag ', '43127', 'Weitweg', '17.10.2012', '12.00 Uhr', '20.10.2012', '', '', '', '', ''], ['122112', '91134', 'Heim', 'Alstoor 1', 'Firma', 'Alstoor 1, 91134 Heim', '111', 'Firma Verlag5', 'Müller', 'Straße Verlag ', '21174', 'Stadt/Land_Fluss', '17.10.2012', '12:00 Uhr', '20.10.2012', '', 'Montag bis Freitag\n08:00 Uhr - 18:00 Uhr  Frau', '', '', ''], ['', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '']]
Werde mich dann mal an die reg exp, bzw, Bereinigung per py wagen. Vielen Dank schon mal für die Horizonterweiterung! Dank natürlich auch an darri!
Grüße von python 21
(Python 3)
Antworten