theunreal
Goto Top

ItextSharp Wrapping auf doc.NewPage möglich?

Ich habe in einem Script einen Mailtext, der auch mal länger als ein DinA4 Blatt sein kann. Aus diesem Text erstelle ich eine PDF.
Nun ist mir aufgefallen (Ich habe leider nicht vorher drauf geachtet face-sad ), dass der Text am Ende der ersten Seite gekappt wird. Klar, der Paragraph ist bei mir ja nur eine Seite.
Welchen Ansatz muss ich nun verfolgen, um den Textbody ab einer bestimmten Länge auf mehreren Seiten abzulegen?

Pseudocode:

if($m.Textbody -gt maximaleZeichen die auf eine Seite passen){
         $doc.addPage()  
         $p.add($RestVomTextbodyfest)
         $doc.add($p)
}

Muss ich alle Zeichen des Textbodys zählen, gelle? Und dann max. Wert für eine Page wissen, damit ich weiß wann der Umbruch kommt und den Text hinterm Umbruch zufügen?

Was wäre hier Best Practice?
Vielen Dank im Voraus für eure Hilfe !
Gruß Sascha

Content-ID: 1230145521

Url: https://administrator.de/contentid/1230145521

Ausgedruckt am: 22.11.2024 um 07:11 Uhr

149062
Lösung 149062 05.09.2021 aktualisiert um 23:19:01 Uhr
Goto Top
https://www.mikesdotnetting.com/article/89/itextsharp-page-layout-with-c ...

Stichwort für im obigen Link Hasmoretext

ColumnText.HasMoreText(status) is a convenience method that takes an int as a parameter. It examines the value of the parameter to see if there is any more text to be added and returns true if there is. The value that returns false is 1. It is initialised at 0 to start, so HasMoreText returns true. Since i is also 0, the code executes to add the first column, then the YLine is set to the top of the column. This must be done, otherwise the application will just spin until the execution timeout occurs. Finally, the ColumnText.Go() method is called. This actually commits the contents of the ColumnText to the document, and also returns a value to the variable status. It returns either NO_MORE_TEXT, which is 1, and/or NO_MORE_COLUMN (2). If NO_MORE_TEXT is returned, everything has been written, otherwise the second column is created and the text added to that. Once ColumnText.HasMoreText returns false, the page is written.

Building on this, if the amount of text spans more than one page, the routine can be rewritten to call Document.NewPage(), and if Go() is called after each Phrase is added to the ColumnText object, it is possible to obtain the current Y position on the page to establish how much room there is left. this enables you to manage widows and orphans - single lines of text that are belong to a paragraph that appear at the end of the preceding page or column (orphans) or appear at the top of a new page or column (widows). It is also possible to pass the parameter "false" into Go(), which does not commit the text to the column, but still allows you to obtain the position as if it was to allow you much finer control over layout.  
colinardo
Lösung colinardo 06.09.2021 aktualisiert um 15:16:58 Uhr
Goto Top
Servus Sascha,
ein einfaches Beispiel das einen ColumnText sol lange auf nachfolgende Seiten fließen lässt bis der komplette Text auf die Seiten geschrieben ist, sollte dir weiterhelfen:
# new pdf path
$output = 'E:\test.pdf'  

Add-Type -Path  "E:\Pfad\zur\itextsharp.dll" -EA Stop  

# text to write
$text =1..10 | %{'Donec commodo eget felis sed vehicula. Suspendisse pretium ultrices quam in iaculis. Aliquam a vulputate nisl. Etiam quam nunc, dictum ac nulla vel, posuere hendrerit metus. Quisque ante lacus, adipiscing id elit vel, ornare consectetur nisi. Etiam pretium, sapien vitae lobortis tempor, nibh justo cursus orci, non dapibus magna sapien quis enim. Phasellus rutrum elit justo, id pellentesque magna tempus dapibus. Etiam sed augue eros. Cras nec varius eros. Aenean sodales tincidunt dolor. Nunc ac metus tristique, porttitor justo eu, luctus diam. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Ut egestas libero quis velit volutpat, at scelerisque mauris porttitor.'}  
 
try{
    $doc = New-Object iTextSharp.text.Document ([iTextSharp.text.PageSize]::A4,5,5,5,5)
    # create writer object
    $writer = [iTextSharp.text.pdf.PdfWriter]::GetInstance($doc,(New-Object System.IO.FileStream ($output,[System.IO.FileMode]::Create)))
    # open editing
    $doc.Open()
    # define font and size
    $font = [iTextSharp.text.FontFactory]::GetFont("HELVETICA",10)  
    # get pdf content byte object
    $cb = $writer.DirectContent
    # create column text object
    $col = New-Object iTextSharp.text.pdf.ColumnText $cb
    # set text alignment
    $col.Alignment = [iTextSharp.text.Element]::ALIGN_JUSTIFIED
    # create phrase
    $phrase = [iTextSharp.text.Phrase]::new($text, $font)
    # add phrase to column
    $col.AddText($phrase)
    # define initial hasmore text state
    $state = 0
    # while not all text has been written
    while([iTextSharp.text.pdf.ColumnText]::HasMoreText($state)){
        # set column rectangle on page
        $col.SetSimpleColumn(20,20,$doc.PageSize.Width -20,$doc.PageSize.Height -20)
        # write column content to page and return state 1 = NO_MORE_TEXT / 2 = NO_MORE_COLUMN
        $state = $col.Go()
        if($state -eq 2){
            # continue column text on new page
            [void]$doc.NewPage()
        }
    }
}catch{
    $_
}finally{
    if ($doc){
        $doc.Close()
        $doc.Dispose()
        $writer.Close()
    }
}
Link zur Referenz des ColumnText Objektes
https://api.itextpdf.com/iText5/java/5.5.13.2/com/itextpdf/text/pdf/Colu ...

Grüße Uwe
TheUnreal
TheUnreal 07.09.2021 um 13:28:55 Uhr
Goto Top
@149062
Mikes Seite habe ich vor ein paar Monaten mal komplett gelesen, aber das ist nicht hängen geblieben face-sad

@colinardo
Mal wieder herzlichsten Dank für deine Unterstützung! Funktioniert einwandfrei (war ja aber auch zu erwarten face-smile)

Danke für die Hilfe von euch beiden!
Gruß Sascha