Entwickler-Ecke
Sonstiges (.NET) - PdfSharp
Tedd - Sa 07.03.15 23:18
Titel: PdfSharp
Hallo Zusammen,
habe es nun hinbekommen mit PdfSharp ein PDF zu generieren mit den gewünschten Inhalten.
Aber das Problem ist, dass das PDF immer im .bin-Ordner abgelegt wird.
Kann man das PDF direkt nach dem Erstellen öffnen, so dass de Ablageort direkt vom PDF-Dokument selbst gewählt werden kann?
Das wäre aus meiner Sicht die leichteste Lösung....oder?
Gruß
jaenicke - Sa 07.03.15 23:45
Kannst du bei document.Save nicht einen Pfad mit angeben? :gruebel:
Tedd - So 08.03.15 09:46
Geht das? Wie soll denn dann die Ergänzung in diesem Code hier aussehen?
C#-Quelltext
1:
| document.Save(filename); |
Gruß
Moderiert von
Th69: C#-Tags hinzugefügt
jaenicke - So 08.03.15 11:58
Du kannst z.B. einen SaveFileDialog benutzen um den Benutzer nach dem Dateinamen inkl. Pfad zu fragen. Oder du fügst dem Pfad selbst hinzu.
Hier findest du ein Beispiel:
https://msdn.microsoft.com/de-de/library/sfezx97z
Tedd - So 08.03.15 17:09
Ein Save.dialog wäre eine Idee klar. Das werde ich mal ausprobieren.
Ein weiteres Problem habe ich bei der Einbindung von Bilder.
Vorgegangen bin ich wie folgt:
C#-Quelltext
1: 2:
| XImage image = XImage.FromFile("Unknown.jpg"); gfx.DrawImage(image, new Point(30, 30)); |
Leider bekomme ich immer einen Fehler bzw. zwei :-)
1) NullReferenceException (Fehler) wird ausgelöst
2) oder der Pfad vom Bild kann ich gefunden werden. (abgelegt im bin-Ordner mit dem Namen Unknown.jpg.)
Hat jemand eine Idee :-) ??
Danke
Moderiert von
Th69: C#-Tags hinzugefügt
Ralf Jansen - So 08.03.15 17:58
Wir wissen weder was ein XImage ist (gehört nicht zum Framework) noch was hinter gfx (ein Graphics Object?) steckt.
Insofern bleibt nur raten.
Wenn irgendwo was vom Filesystem geladen werden soll wird nach einem Pfad gefragt nicht einfach nur nach einem Dateinamen. Wenn du nur einen Dateinamen angibst wird der zu benutzende Pfad aus dem Arbeitsordner und dem Dateinamen zusammengesetzt. Der Arbeitsordner ist nur zufällig oft das gleiche wie der Ordner in dem deine Anwendung liegt kann aber auch was anderes sein oder sich zur Laufzeit ändern. (Z.b. die angesprochenen FileOpen oder SaveFileDialoge ändern den Arbeitsordner) Irgendwo also nur einen Dateinamen anzugeben ist eher ein Glücksspiel und solltest du nicht machen.
Wenn du relativ zu deiner Anwendung irgendwas zum öffnen ablegst solltest du den Pfad selber zusammenbauen und diesen dann verwenden. Z.B. Wenn deine Anwendung eine Winforms Anwendung ist
dann
C#-Quelltext
1: 2:
| string path = Path.Combine(Application.StartupPath, "Unknown.jpg"); XImage image = XImage.FromFile(path); |
Über dein NullReferenceException können wir nicht mal spekulieren dafür wiesen wir zu wenig über das was du da hast um aus den 2 Zeilen irgendwas abzulesen.
Tedd - So 08.03.15 18:32
Ja sorry...da habe ich mir dir Hälfte gedacht.
Meine Anwendung ist eine Windows-form und ich nutze PdfSharp um ein PDf-Dokument zu generieren.
Texte kann ich darstellen, aber halt noch keine Bilder.
Ich habe nun ein wenig recherchiert und bin dann auf meine dargestellte Lösung gekommen.
Es funktioniert nicht und deine vorgeschlagene Lösung auch nicht bzw. ..ja vielleicht doch, aber irgendwie bei mir nicht.
C#-Quelltext
1: 2: 3:
| string path = Path.Combine(Application.StartupPath, "Unknown.jpg"); XImage image = XImage.FromFile(path); gfx.DrawImage(image,100,20,300,200); |
Die Code-Zeilen habe ich nun mit mehreren Beispielen aus dem Internet verglichen.
Die müssten passen. Das Bild liegt im .bin-Ordner meiner Anwendung. Passt auch!
Und genau da soll sich PdfSharp das Bild rausziehen, denn dann wird ein Fehler rausgeschmissen.
Also passt doch irgendwas nicht. Oh man....
Moderiert von
Th69: C#-Tags hinzugefügt (bitte demnächst selber beachten)
Tedd - Di 31.03.15 22:01
Hallo Zusammen,
weiß jemand den Befehl von PdfSharp für einen Zeilenumbruch?
Ich habe eine textBox und füge dort meine Inhalte ein.
In der Box selbst kann ich ja mit Environment.newLine arbeiten, aber der Zeilenumbruch aus der Box wird ja leider nicht von PdfSharp erkannt.
Habe schon probiert alle Einträge in Listen zu packen und dann Zeile für Zeile in das Pdf zu packen, aber das will auch nicht funktionieren.
Wäre über einen Tipp sehr dankbar.
Viele Grüße
Yankyy02 - Di 31.03.15 23:00
Hallo Tedd,
für das Zeichnen des Textes in PdfSharp gibt's ein nettes Beispiel
http://www.pdfsharp.net/wiki/Unicode-sample.ashx.
Wenn du den Text aus einer Textbox mit Multiline = true ausliest dann wird der Zeilenumbruch mit /r/n "hinterlegt". Du musst also
bevor du den Text übergibst die Escape Sequenz /r herausfiltern das sollte ja kein Problem darstellen.
Lg
Tedd - Di 31.03.15 23:17
Hi und erstmal besten Dank für dein Feedback.
Ich muss leider zugeben, dass ich nicht ganz genau deine vorgeschlagene Vorgehensweise verstehe.
Wie filtert man den Zeichenliterale?
Direkt in den Eigenschaften der Textbox?
Und mit der Lösung soll ich mich dann an dem Beispiel (Link)orientieren?
Gruß
Yankyy02 - Di 31.03.15 23:43
Servus,
hast du dir das Beispiel angesehen? Die Methode kannst du für's erste ja mal 1:1 übernehmen und mit dem Text deiner Textbox probieren. Ich muss zugeben ich hab noch nicht mit PdfSharp gearbeitet hat aber auf anhieb funktioniert. Die Schleife mußt du halt weglassen.
Auf die schnelle das Beispiel mit einer Textbox:
C#-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17:
| PdfDocument document = new PdfDocument();
XPdfFontOptions options = new XPdfFontOptions(PdfFontEncoding.Unicode, PdfFontEmbedding.Always);
XFont font = new XFont("Times New Roman", 12, XFontStyle.Regular, options);
PdfPage page = document.AddPage(); XGraphics gfx = XGraphics.FromPdfPage(page); XTextFormatter tf = new XTextFormatter(gfx); tf.Alignment = XParagraphAlignment.Left;
tf.DrawString(textBox1.Text.Replace('\r',' '), font, XBrushes.Black, new XRect(100, 100, page.Width - 200, 600), XStringFormats.TopLeft); const string filename = "Unicode_tempfile.pdf"; document.Save(filename); Process.Start(filename); |
Dabei wird der Text mit den Zeilenumbrüchen wie sie in der Textbox stehen übernommen was ja dein Problem war ?
[edit]Dabei wird jedoch nicht berücksichtigt ob der Text zu lange für die Zeile ist darum musst du dich kümmern.[edit]
Lg
Tedd - Mi 01.04.15 18:27
Hmm..es will nicht klappen. Ich habe genau deinen Code verwendet und in der TextBox habe ich mit Environment.NewLine gearbeitet.
Ich habe echt keine Idee mehr...
Yankyy02 - Mi 01.04.15 18:34
Wie meinst du das du arbeitest in der TextBox mit Environment.NewLine? Ich stell mir das so vor: Du stellst dem User eine TextBox mit Multiline = true zur verfügung. Dieser schreibt seinen Text in die Textbox und diesen möchtest du dann als Pdf haben??
Lg
Tedd - Mi 01.04.15 18:37
Wenn ich den Text in eine Liste gepackt habe.
Wie erfolgt dann bei PdfSharp die Abfrage an dieser Stelle?
C#-Quelltext
1: 2: 3:
| gfx.DrawString(XXXXX?????, font, XBrushes.Black, new XRect(30,700, page.Width, page.Height), XStringFormats.TopLeft); |
Moderiert von
Th69: C#-Tags hinzugefügt
Ralf Jansen - Mi 01.04.15 19:49
In DrawString geht ein String rein keine Liste (was immer auch Liste für ein Datentyp ist. Den Typ Liste gibt es nicht).
Wie man einen String aus deiner Liste bekommt hat dann nix mit PDFSharp zu tun sondern das geht wie immer ;)
Übrigens spaßeshalber habe ich den Code von Yankyy02 ausprobiert und der geht. Wenn er bei dir nicht geht solltest du uns lieber zeigen was du stattdessen gemacht hast. Wenn du nur sagst es geht nicht wir aber nicht wirklich wissen was du genau gemacht hast ist das fischen im trüben und ausgesprochen unproduktiv.
Tedd - Mi 01.04.15 19:58
Ich nehme Alles zurück...mein Fehler...habt vielen Dank. Endlich klappt es :-)
Tedd - Fr 03.04.15 15:58
Das Programm haut zwar nun bei mir hin, aber ich wollte nochmal den Grund für das Filtern der Zeichenliteralen verstehen.
/n steht für Zeilenumbruch
/r steht für Wagenrücklauf, also Zeilenanfang
Wieso muss man nun bei PdfSharp das /r herausfiltern?
Denn auch hier ist doch "eigentlich" ein Sprung zum Zeilenanfang nicht verkehrt oder?
Gruß
Ralf Jansen - Fr 03.04.15 17:05
Zitat: |
Denn auch hier ist doch "eigentlich" ein Sprung zum Zeilenanfang nicht verkehrt oder? |
Die ursprüngliche Bedeutung von \n bzw. \r hilft dir Heutzutage überhaupt nicht mehr. Außer vielleicht um den historischen Hintergrund zu verstehen warum verschiedene Systeme verschiedene Bytes oder Bytefolgen benutzen um einen Zeilenumbruch anzudeuten. Allein die Bezeichnungen Zeilenvorschub und Wagenrücklauf sollte dir anzeigen das das aus einer anderen Zeit entstammt und es ist einfach heute nur noch die Bezeichnung dieses Bytes dahinter verbirgt sich aber
keine bestimmte Funktion (mehr). Es ist einfach nur ein historisch geprägter Name.
Du solltest immer berücksichtigen das es da unterschiedliche Formate gibt die andere Zeichen als Zeilenumbruch benutzen. Das kann \n oder \r\n oder \n\r nur \r oder was auch immer sein. Es kommt auf die genaue Definition des benutzen Formats an die man sich halt ansehen und berücksichtigen muss. Genauso wie du drauf achten musst was für ein Encoding (z.B. ANSI, UTF-8 ) erwartet wird. Text ist nicht eindeutig Text und ein Zeilenumbruch nicht eindeutig ein Zeilenumbruch.
In Windows ist ein Zeilenumbruch eigentlich immer \r\n darum kommt das aus der Textbox. Die Definition in PDF besagt aber eben \n. Zum Beispiel die Definition von RTF ist auch \n. Hättest du anstatt eine TextBox zu verwenden eine RichTextBox genommen hätte das ~zufällig~ gepasst und dir wäre das ~Problem~ nicht mal aufgefallen.
Tedd - Fr 03.04.15 18:59
Ok,...eine Frage noch zu dem Thema:
Was genau ist dann der Unterschied zwischen den beiden Codeblöcken?
C#-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10:
| gfx.DrawString(textBox.Text, font, XBrushes.Black, new XRect(30,660, page.Width, page.Height), XStringFormats.TopLeft);
XPdfFontOptions options = new XPdfFontOptions(PdfFontEncoding.Unicode, PdfFontEmbedding.Always);
tf.DrawString(textBox.Text.Replace(' ', ' '), font, XBrushes.Black, new XRect(30, 220, page.Width - 10, 700), XStringFormats.TopLeft); |
[cs]
Besten Dank
Ralf Jansen - Fr 03.04.15 19:15
Es gibt im gezeigten Code keinen Unterschied.
Die 2.te Code erzeugt Options du im gezeigten Code nicht verwendest und der Replace ersetzt Zeichen mit sich selbst ist also funktionlos.
Wenn du den Code den du verwendet hast und nicht funktionierte mit dem vergleichst der jetzt funktioniert ist das jetzt gezeigte nicht der relevante Unterschied.
Edit: Ich habe gerade nochmal den Code von Yankyy02 ohne das Replace durchgespielt und der funktioniert dann genauso richtig. Wen du also nicht funktionierenden Code hattest ist die Definition des Zeilenumbruchs nicht das Problem gewesen. Die Kapselung durch PDFSharp scheint intelligent genug zu sein um verschiedene Arten von Zeilenumbrüchen als Zeilenumbruch zu erkennen und für den PDF Output richtig umzusetzen.
Tedd - So 05.04.15 16:07
Frohe Ostern :lol:
Ich habe noch folgendes Problem.
Ich erstelle mit PdfSharp ein Dokument und im letzten Schritt will ich es öffnen, so dass ich mir meinen Ablagepfad direkt in Adobe auswählen kann.
Soweit so gut...es läuft nur teilweise, denn wenn ich ein PDF erzeuge wird das zwar geöffnet und ich kann es speichern, aber das funktioniert genau einmal.
Denn die Anwendung schiebt das PDF in den .bin-Ordner und öffnet dann immer wieder das PDF aus dem -bin-Ordner, obwohl ich andere Inhalte eingestellt habe.
Folgenden Code habe ich verwendet,..wäre super wenn einer eine Idee hat.
C#-Quelltext
1: 2: 3: 4: 5:
| PdfDocument document = new PdfDocument(); ...... const string filename = "Test"; document.Save(filename); System.Diagnostics.Process.Start(filename) |
Th69 - So 05.04.15 16:13
Ohne Pfadangabe wird es natürlich immer die Datei aus dem aktuellen WorkingDirectory öffnen.
Du mußt also irgendwo deinem Programm den Ablagepfad angeben.
Tedd - So 05.04.15 16:24
Hallo Th69,
besten Dank für das schnelle Feedback.
Wie kann ich denn den Dateipfad hinterlegen?
Tedd - So 05.04.15 18:29
Es wäre auch vollkommen ausreichend zu wissen, wie man jedes NEU erstellte Dokument anschließend öffnet.
So kann der Nutzer dann in dem AdobeReader selbst den Pfad wählen.
Vielleicht will man es auch nur Einsehen und gar nicht speichern.
Von daher wäre das die ideale Lösung...
Ralf Jansen - So 05.04.15 18:42
Der Adobe Reader ist wie jeder andere File Viewer dazu gedacht Files anzuzeigen. Insofern wirst du das PDF irgendwo ablegen müssen bevor es angezeigt wird. Das der Benutzer es aus dem Reader wo anders speichern kann wenn er es einmal angezeigt hat ist dann seine Entscheidung.
Wenn du nicht weißt wohin und das für dich erstmal nicht relevant ist nimm z.B. den
Temp [
https://msdn.microsoft.com/de-de/library/system.io.path.gettemppath%28v=vs.110%29.aspx] Ordner.
Den Pfad zu nehmen wo die Executable liegt oder wohin zufällig die WorkingDirectory zeigt ist auf jedenfalls nicht gut. In den meisten Fällen hat ein normaler User da keine Schreibrechte.
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2025 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!