You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@pdfbox.apache.org by Tim Mann <ha...@gmail.com> on 2025/03/24 17:11:04 UTC

line wrapping text in a table

Greetings.  I am a novice, hobbyist Java programmer.  I am working on a
method that will properly line wrap text, as necessary, to fit within a
defined table cell.

The page' s width is set as   fullPageWidth =
page1.getMediaBox().getWidth() - leftMargin - rightMargin;  .  I then
divide the fullPageWidth by the number of columns needed to get at the
width of each cell. Note that all cell widths are not necessarily equal.
To populate each cell in a line of the table, I pass the text to be
displayed (variable* myText)* to a method with the following code.  Note
some code not relevant to text rendering has been removed.

private static int printCellContents(PDPageContentStream content, PDPage
page, PDFont font, int sizeOfFont, float startingLineNumber, float
headerHeight, float columnIndent, *String myText,* int fieldNumber, float
cellRight, int locationLineNumber)

        char[] characters = *myText*.toCharArray();
        String cellText = "";
        float cellPrintableArea = displayColWidth[fieldNumber];// holds
width of each table cell in a horizontal row
        int numberOfCellTextLines = 1;

        try {
            content.beginText();// 02262025
            content.setLeading(utilities.setLeading(fontSize));// 03062025
added
            content.newLineAtOffset(cellRight, pageHeight - marginTop -
headerHeight - (startingLineNumber * lineSpacing));// set position to print

                // line wrap the cell contents as necessary to fit within
the cell
                for (int charIterator = 0; charIterator <
characters.length; charIterator++) {

                    // note in the below equation the use of Math.ceil
rounds up the string width
                    // subtracting 1 from the cellPrintableArea accounts
for the 0.5 vertical border line width on each side of the cell
                    if (Math.ceil(*fontPlain.getStringWidth(cellText +
characters[charIterator]) / 1000 * sizeOfFont) <= cellPrintableArea - 1*)
{// 03242025 removed + variablePadText
                        cellText += characters[charIterator];
                    } else {
                        if (cellText.length() > 0) {
                            content.showText(cellText);
                            cellText = "";
                            content.newLine();
                            numberOfCellTextLines++;
                            charIterator--;
                        }
                }
                if (cellText.length() > 0) { // this is to print the final
myText string
                    try {
                        content.showText(cellText);
                    } catch (IOException ex) {

Logger.getLogger(handleComments.class.getName()).log(Level.SEVERE, null,
ex);
                        utilities.writeToResultsWindow(3, "error in the
 field");
                    }
                }
            }
            content.endText();
        } catch (IOException ex) {
            Logger.getLogger(handleCars.class.getName()).log(Level.SEVERE,
null, ex);
        }
        return numberOfCellTextLines;
    }

This approach for some reason does not work as text often, but not always,
overwrites the cell boundary lines.  For example processing the string "*Loyall
yard track 2 (D)" *results in the calculated width of the text as 78.24
versus a cell width of 79.0.  (Helvetica plain font, size = 10) Thus
suggesting the text will fit, however the resulting table cell in the PDF
shows that it should have wrapped the line before the "2".


[image: image.png]

When using Courier size 10 font the failure is also present.

[image: image.png]


I have read much of the ISO standard regarding text.  I've done numerous
internet searches on this.  I've looked at using bounding boxes, character
widths, character displacements, etc  but I cannot find a suitable approach
to consistently wrap the text within the table cell boundaries.  Any
assistance would be greatly appreciated.  NOTE this code is for commercial
use, but for a freeware program that I'm developing.

-- 
Regards,

Tim Mann

Fwd: line wrapping text in a table

Posted by Tim Mann <ha...@gmail.com>.
My apologies for the second email, but I made a significant error in the
last line of my email.  My code is NOT being used for a commercial.  I give
the program away for free.

---------- Forwarded message ---------
From: Tim Mann <ha...@gmail.com>
Date: Mon, Mar 24, 2025 at 12:11 PM
Subject: line wrapping text in a table
To: <us...@pdfbox.apache.org>



Greetings.  I am a novice, hobbyist Java programmer.  I am working on a
method that will properly line wrap text, as necessary, to fit within a
defined table cell.

The page' s width is set as   fullPageWidth =
page1.getMediaBox().getWidth() - leftMargin - rightMargin;  .  I then
divide the fullPageWidth by the number of columns needed to get at the
width of each cell. Note that all cell widths are not necessarily equal.
To populate each cell in a line of the table, I pass the text to be
displayed (variable* myText)* to a method with the following code.  Note
some code not relevant to text rendering has been removed.

private static int printCellContents(PDPageContentStream content, PDPage
page, PDFont font, int sizeOfFont, float startingLineNumber, float
headerHeight, float columnIndent, *String myText,* int fieldNumber, float
cellRight, int locationLineNumber)

        char[] characters = *myText*.toCharArray();
        String cellText = "";
        float cellPrintableArea = displayColWidth[fieldNumber];// holds
width of each table cell in a horizontal row
        int numberOfCellTextLines = 1;

        try {
            content.beginText();// 02262025
            content.setLeading(utilities.setLeading(fontSize));// 03062025
added
            content.newLineAtOffset(cellRight, pageHeight - marginTop -
headerHeight - (startingLineNumber * lineSpacing));// set position to print

                // line wrap the cell contents as necessary to fit within
the cell
                for (int charIterator = 0; charIterator <
characters.length; charIterator++) {

                    // note in the below equation the use of Math.ceil
rounds up the string width
                    // subtracting 1 from the cellPrintableArea accounts
for the 0.5 vertical border line width on each side of the cell
                    if (Math.ceil(*fontPlain.getStringWidth(cellText +
characters[charIterator]) / 1000 * sizeOfFont) <= cellPrintableArea - 1*)
{// 03242025 removed + variablePadText
                        cellText += characters[charIterator];
                    } else {
                        if (cellText.length() > 0) {
                            content.showText(cellText);
                            cellText = "";
                            content.newLine();
                            numberOfCellTextLines++;
                            charIterator--;
                        }
                }
                if (cellText.length() > 0) { // this is to print the final
myText string
                    try {
                        content.showText(cellText);
                    } catch (IOException ex) {

Logger.getLogger(handleComments.class.getName()).log(Level.SEVERE, null,
ex);
                        utilities.writeToResultsWindow(3, "error in the
 field");
                    }
                }
            }
            content.endText();
        } catch (IOException ex) {
            Logger.getLogger(handleCars.class.getName()).log(Level.SEVERE,
null, ex);
        }
        return numberOfCellTextLines;
    }

This approach for some reason does not work as text often, but not always,
overwrites the cell boundary lines.  For example processing the string "*Loyall
yard track 2 (D)" *results in the calculated width of the text as 78.24
versus a cell width of 79.0.  (Helvetica plain font, size = 10) Thus
suggesting the text will fit, however the resulting table cell in the PDF
shows that it should have wrapped the line before the "2".


[image: image.png]

When using Courier size 10 font the failure is also present.

[image: image.png]


I have read much of the ISO standard regarding text.  I've done numerous
internet searches on this.  I've looked at using bounding boxes, character
widths, character displacements, etc  but I cannot find a suitable approach
to consistently wrap the text within the table cell boundaries.  Any
assistance would be greatly appreciated.  NOTE this code is for commercial
use, but for a freeware program that I'm developing.

-- 
Regards,

Tim Mann



-- 
Regards,

Tim Mann

Re: line wrapping text in a table

Posted by Tilman Hausherr <TH...@t-online.de>.
Hi,

The image attachments didn't get through, either make them inline 
(thunderbird does this), or upload them. Also upload the result PDF, and 
some minimal self-working code.

There could be so many things... maybe there is a transformation, or 
maybe the cells aren't where you think they are...

Re positions etc, try using PDFDebugger, when moving the mouse it shows 
the actual positions.

Tilman

On 24.03.2025 18:11, Tim Mann wrote:
>
> Greetings.  I am a novice, hobbyist Java programmer.  I am working on 
> a method that will properly line wrap text, as necessary, to fit 
> within a defined table cell.
>
> The page' s width is set as   fullPageWidth = 
> page1.getMediaBox().getWidth() - leftMargin - rightMargin;  .  I then 
> divide the fullPageWidth by the number of columns needed to get at the 
> width of each cell. Note that all cell widths are not necessarily 
> equal.    To populate each cell in a line of the table, I pass the 
> text to be displayed (variable*myText)* to a method with the following 
> code.  Note some code not relevant to text rendering has been removed.
>
> private static int printCellContents(PDPageContentStream content, 
> PDPage page, PDFont font, int sizeOfFont, float startingLineNumber, 
> float headerHeight, float columnIndent, *String myText,* int 
> fieldNumber, float cellRight, int locationLineNumber)
>
> char[] characters = *myText*.toCharArray();
>         String cellText = "";
>         float cellPrintableArea = displayColWidth[fieldNumber];// 
> holds width of each table cell in a horizontal row
>         int numberOfCellTextLines = 1;
>
>         try {
>             content.beginText();// 02262025
> content.setLeading(utilities.setLeading(fontSize));// 03062025 added
>             content.newLineAtOffset(cellRight, pageHeight - marginTop 
> - headerHeight - (startingLineNumber * lineSpacing));// set position 
> to print
>
>                 // line wrap the cell contents as necessary to fit 
> within the cell
>                 for (int charIterator = 0; charIterator < 
> characters.length; charIterator++) {
>
>                     // note in the below equation the use of Math.ceil 
> rounds up the string width
>                     // subtracting 1 from the cellPrintableArea 
> accounts for the 0.5 vertical border line width on each side of the cell
>                     if (Math.ceil(*fontPlain.getStringWidth(cellText + 
> characters[charIterator]) / 1000 * sizeOfFont) <= cellPrintableArea - 
> 1*) {// 03242025 removed + variablePadText
>                         cellText += characters[charIterator];
>                     } else {
>                         if (cellText.length() > 0) {
>                             content.showText(cellText);
>                             cellText = "";
>                             content.newLine();
>                             numberOfCellTextLines++;
>                             charIterator--;
>                         }
>                 }
>                 if (cellText.length() > 0) { // this is to print the 
> final myText string
>                     try {
>                         content.showText(cellText);
>                     } catch (IOException ex) {
> Logger.getLogger(handleComments.class.getName()).log(Level.SEVERE, 
> null, ex);
>                         utilities.writeToResultsWindow(3, "error in 
> the  field");
>                     }
>                 }
>             }
>             content.endText();
>         } catch (IOException ex) {
> Logger.getLogger(handleCars.class.getName()).log(Level.SEVERE, null, ex);
>         }
>         return numberOfCellTextLines;
>     }
>
> This approach for some reason does not work as text often, but not 
> always, overwrites the cell boundary lines.  For example processing 
> the string "*Loyall yard track 2 (D)" *results in the 
> calculated**width of the text as 78.24 versus a cell width of 79.0.  
> (Helvetica plain font, size = 10) Thus suggesting the text will fit, 
> however the resulting table cell in the PDF shows that it should have 
> wrapped the line before the "2".
>
>
> image.png
>
> When using Courier size 10 font the failure is also present.
>
> image.png
>
>
> I have read much of the ISO standard regarding text.  I've done 
> numerous internet searches on this.  I've looked at using bounding 
> boxes, character widths, character displacements, etc  but I cannot 
> find a suitable approach to consistently wrap the text within the 
> table cell boundaries.  Any assistance would be greatly appreciated.  
> NOTE this code is for commercial use, but for a freeware program that 
> I'm developing.
>
> -- 
> Regards,
>
> Tim Mann
>