Text missing in generated pdf

In the following example, the resulting pdf consists of one page with 69 lines of text, altough it should be 5 pages with 300 lines.


com.aspose.pdf.Document document = new com.aspose.pdf.Document();
com.aspose.pdf.Page page = document.getPages().add();

for (int i = 0; i < 300; i++) {
    com.aspose.pdf.FloatingBox floatingBox = new com.aspose.pdf.FloatingBox();
    page.getParagraphs().add(floatingBox);
    floatingBox.getParagraphs()
               .add(new com.aspose.pdf.TextFragment(i + " A line of text. \n "));
}

document.save("missingLines.pdf");

missingLines.pdf (2.4 KB)

In the next example with a bit longer text aspose decides that after paragraph 69 (page 4) it stops adding new content, again it should print 300 paragraphs instead.


com.aspose.pdf.Document document = new com.aspose.pdf.Document();
com.aspose.pdf.Page page = document.getPages().add();

for (int i = 0; i < 300; i++) {
    com.aspose.pdf.FloatingBox floatingBox = new com.aspose.pdf.FloatingBox();
    page.getParagraphs().add(floatingBox);
    floatingBox.getParagraphs()
               .add(new com.aspose.pdf.TextFragment(i + "Lorem ipsum dolor sit amet, nec facilisi explicari "
                                                        + "intellegat at, ei nec aeque rationibus. No nisl "
                                                        + "commodo duo, ius te fugit nusquam. Ex eam melius "
                                                        + "probatus. Eam ex brute partiendo intellegat, ne "
                                                        + "sed consul soleat dictas, ea dicam dictas legendos"
                                                        + "Erant vitae assueverit ex mea. Sed regione "
                                                        + "electram adipiscing cu"));
}

document.save("missingLines2.pdf");

missingLines2.pdf (6.3 KB)

We need the FloatingBox to format groups of TextFragments (margin, padding, border…), this is just the bare minimum to reproduce the issue.

Would you be so kind to provide a workaround where we can format groups of TextFragments without loosing content in the resulting pdf?
Looking forward to the solution.

(Using aspose pdf version 18.6)

Kind regards,
Stefan Raubal

@stefan.raubal

Thank you for contacting support.

We have noticed the difference with shared code snippets. It first adds only a single page with the second line in your code and the next pages are added only if the text overflows, as soon as a TextFragment is entirely added on a PDF page, next page is not added unless added explicitly. This has been the case with both PDF documents. However, we have logged a ticket with ID PDFJAVA-37998 for further investigations.

Regarding the workaround, we will be checking if your requirements can be met with some other approach and we will let you know our findings if there is any approach. However, would you please elaborate your requirements a little more for our reference so that we may assist you accordingly.

We have a nested data structure of ‘Fields’. Each field has content which should get printed, and each nested group of fields should have padding and border. We do not know how many fields we have and how much text they contain. Below is a simplified example, we actually have different visit(…) methods for different types of fields (date fields, checkbox fields, table fields, text fields…).


public class Field {
    private String text;
    private List<Field> children; 
}

 public BaseParagraph visit(Field field) {
	FloatingBox floatingBox = new FloatingBox();
	
	floatingBox.setMargin(new MarginInfo(0, 10, 0, 10));
	
	if (!StringUtils.isEmpty(field.getText())) {
		TextFragment textFragment = new TextFragment(field.getText());
		textFragment.getTextState().setFontSize(FIELDSET_LABEL_FONT_SIZE);
		textFragment.getTextState().setForegroundColor(FIELDSET_LABEL_COLOR);
		textFragment.setMargin(new MarginInfo(0,0,0,10));
		
		floatingBox.getParagraphs().add(textFragment);
		
		floatingBox.setPadding(new MarginInfo(0, 5, 0, 0));
	} 
					 
	if (!field.getChildren.isEmpty()) {     
		List renderedChildren = new ArrayList<>();
		for(Field child : field.getChildren()) {
			BaseParagraph baseParagraph = visit(child);          
			renderedChildren.add(baseParagraph);            
		}		
	
		FloatingBox childContainer = new FloatingBox();
		renderedChildren.forEach(childContainer.getParagraphs()::add);		
		childContainer.setPadding(new MarginInfo(5, 5, 5, 5));			
		childContainer.setBorder(new BorderInfo(BorderSide.ALL, .25f, FIELDSET_BORDER_COLOR));
		
		floatingBox.getParagraphs().add(childContainer); 
	}
	
	return floatingBox;
}

// Entry point

List fields = ...;
com.aspose.pdf.Document document = new com.aspose.pdf.Document();
com.aspose.pdf.Page page = document.getPages().add();

for (Field field: fields) {
 BaseParagraph renderedField = visit(field);
  page.getParagraphs().add(field);
}

document.save("myExample.pdf");

Kind regards,
Stefan Raubal

We always want to have a next page if there is more content in the (FloatingBox’s) Paragraphs collection, not only when a single TextFragment in the Paragraphs collection coincidentally overflows. How can I ensure that a new page is created when a FloatingBox overflows?

@stefan.raubal

We have investigated your requirements and would like to suggest a workaround using the table wrapper. It also allows to set additional information for builder (alignment, color, margins, width).

    com.aspose.pdf.Document document = new com.aspose.pdf.Document();
    com.aspose.pdf.Page page = document.getPages().add();
    Table table = new Table();
    table.setColumnWidths("500");
    com.aspose.pdf.FloatingBox floatingBox = new com.aspose.pdf.FloatingBox();
    Cell cell = table.getRows().add().getCells().add();
    for (int i = 0; i < 300; i++) {
        page.getParagraphs().add(floatingBox);
        cell.getParagraphs()
//                    .add(new com.aspose.pdf.TextFragment(i + " A line of text. \n "));

                .add(new com.aspose.pdf.TextFragment(i + "Lorem ipsum dolor sit amet, nec facilisi explicari "
                        + "intellegat at, ei nec aeque rationibus. No nisl "
                        + "commodo duo, ius te fugit nusquam. Ex eam melius "
                        + "probatus. Eam ex brute partiendo intellegat, ne "
                        + "sed consul soleat dictas, ea dicam dictas legendos"
                        + "Erant vitae assueverit ex mea. Sed regione "
                        + "electram adipiscing cu"));
    }
    floatingBox.getParagraphs()
            .add(table);
    document.save(myDir+"missingLines2"+version+"_table_one_cell_width500.pdf");

We have attached generated PDF files for shorter and longer text.
missingLines2_18_8__table_one_cell_width500.pdf
missingLines_18_8__table_one_cell_width500.pdf

We will further investigate the ticket for cut text in a floating box object and will let you know our findings accordingly.

Thank you very much for your workaround, we appreciate your help. I will give feedback as soon as we have tested it thouroghly, but it seems to do the job.

@stefan.raubal

We hope suggested approach will satisfy your requirements. Please take your time and get back to us as per your convenience.

So we replaced all FloatingBoxes with


Table floatingBox = new Table();
floatingBox.setColumnWidths("1000");
Cell cell = floatingBox.getRows().add().getCells().add();

This fixes the problem of missing paragraphs, the pdf is generated correctly now.

Sadly now another issue emerged. After a certain amount of content in the pdf, aspose is stuck indefinitely when executing document.processParagraphs() or document.save(outputStream), whatever comes first.
So at a certain point, the pdf is generated quickly (< 0.5s), but after adding one additional line of text document.save() takes forever.

Do you have any experience with that kind of issue?

@stefan.raubal

We are glad to know that suggested approach suited your requirements. Moreover, would you please share a narrowed down sample application reproducing the problem so that we may try to reproduce and investigate it further.

Here an example to reproduce the issue.
On my machine when looping 8 times (IntStream.range(1,8)) it generates the correct pdf,
but when looping 9 times (as in the example below) it is stuck on document.save(“myExample.pdf”) for at least 5 minutes, after which I stopped the test. Such behaviour in the Aspose library which we cannot anticipate upfront is really worrying for us, it would be nice to know how we can avoid this in the future.


private static final String LONG_TEXT = "Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy "
    + "eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed "
    + "diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum."
    + " Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum "
    + "dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing "
    + "elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna"
    + " aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo "
    + "dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus"
    + " est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur"
    + " sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et "
    + "dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam "
    + "et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea "
    + "takimata sanctus est Lorem ipsum dolor sit amet.   \n"
    + "\n"
    + "Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse "
    + "molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero"
    + " eros et accumsan et iusto odio dignissim qui blandit praesent luptatum"
    + " zzril delenit augue duis dolore te feugait nulla facilisi. Lorem ipsum"
    + " dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh "
    + "euismod tincidunt ut laoreet dolore magna aliquam erat volutpat.   \n"
    + "\n"
    + "Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper "
    + "suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem "
    + "vel eum iriure dolor in hendrerit in vulputate velit esse molestie "
    + "consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et "
    + "accumsan et iusto odio dignissim qui blandit praesent luptatum zzril "
    + "delenit augue duis dolore te feugait nulla facilisi.   \n"
    + "\n"
    + "Nam liber tempor cum soluta nobis eleifend option congue nihil "
    + "imperdiet doming id quod mazim placerat facer possim assum. Lorem ipsum"
    + " dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh "
    + "euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut "
    + "wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper "
    + "suscipit lobortis nisl ut aliquip ex ea commodo consequat.   \n"
    + "\n"
    + "Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse "
    + "molestie consequat, vel illum dolore eu feugiat nulla facilisis.   \n"
    + "\n"
    + "At vero eos et accusam et justo duo dolores et ea rebum. Stet clita "
    + "kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet."
    + " Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam "
    + "nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, "
    + "sed diam voluptua. At vero eos et accusam et justo duo dolores et ea "
    + "rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem "
    + "ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing"
    + " elitr, At accusam aliquyam diam diam dolore dolores duo eirmod eos "
    + "erat, et nonumy sed tempor et et invidunt justo labore Stet clita ea et"
    + " gubergren, kasd magna no rebum. sanctus sea sed takimata ut vero "
    + "voluptua. est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, "
    + "consetetur";

@Test
public void testBug()  {
    List<Field> nestedFields = new ArrayList<>();

    FieldSetField nested1 = new FieldSetField();
    nested1.setLabelKey(LONG_TEXT);
    nested1.setFields(new ArrayList<>());
    IntStream.range(1,9).forEach(i -> nestedFields.add(nested1));

    FieldSetField field1 = new FieldSetField();
    field1.setLabelKey("my.label.key");
    field1.setFields(nestedFields);

    List<FieldSetField> fields = new ArrayList();
    IntStream.range(1,10).forEach(i -> fields.add(field1));

    com.aspose.pdf.Document document = new com.aspose.pdf.Document();
    com.aspose.pdf.Page page = document.getPages().add();

    for (FieldSetField field: fields) {
        BaseParagraph renderedField = visit(field);
        page.getParagraphs().add(renderedField);
    }

    document.save("myExample.pdf");
}

public BaseParagraph visit(FieldSetField field) {
    Table table = new Table();
    table.setColumnWidths("500");
    Cell cell = table.getRows().add().getCells().add();

    table.setMargin(new MarginInfo(0, 10, 0, 10));

    if (!StringUtils.isEmpty(field.getLabelKey())) {
        TextFragment textFragment = new TextFragment(field.getLabelKey());
        textFragment.getTextState().setFontSize(14);
        textFragment.getTextState().setForegroundColor(Color.getDarkSlateGray());
        textFragment.setMargin(new MarginInfo(0,0,0,10));

        cell.getParagraphs().add(textFragment);

        cell.setMargin(new MarginInfo(0, 5, 0, 0));
    }

    if (!field.getFields().isEmpty()) {
        for(Field child : field.getFields()) {
            BaseParagraph baseParagraph = visit((FieldSetField) child);
            cell.getParagraphs().add(baseParagraph);
        }
    }

    return table;
}


public class Field {
    private String labelKey;

   public String getLabelKey() {
       return labelKey;
   }

   public void setLabelKey(String labelKey) {
       this.labelKey = labelKey;
   }
}

public class FieldSetField extends Field {
    private List<Field> fields;

   public List<Field> getFields() {
       return fields;
   }

   public void setFields(List<Field> fields) {
       this.fields = fields;
   }
}

The generated pdf when using IntStream.range(1,8):
myExample.pdf (102.3 KB)

@stefan.raubal

Thank you for sharing requested data. However, please share a narrowed down sample application instead of the code snippet as currently few methods including setLabelKey, setFields etc. are not included. So, please upload an application so that we may proceed further to help you out. Please also mention your environment details (OS details, JDK/JRE version etc) for our reference.

I included getters and setters in the example above.

jdk1.8.0_92

java version “1.8.0_92”
Java™ SE Runtime Environment (build 1.8.0_92-b14)
Java HotSpot™ 64-Bit Server VM (build 25.92-b14, mixed mode)

OS Name Microsoft Windows 10 Pro
Version 10.0.17134 Build 17134

allocated heap size 2GB

@stefan.raubal

Thank you for sharing requested information.

The code ends up with an error on below line of code.

IntStream.range(1,9).forEach(i -> nestedFields.add(nested1));

Please share the definition for this method so that we may proceed to help you.

Here the complete code including the import statements:


package com.example;

import com.aspose.pdf.BaseParagraph;
import com.aspose.pdf.Cell;
import com.aspose.pdf.Color;
import com.aspose.pdf.MarginInfo;
import com.aspose.pdf.Table;
import com.aspose.pdf.TextFragment;
import org.apache.commons.lang3.StringUtils;
import org.junit.Test;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.IntStream;

public class ExampleCode {

    private static final String LONG_TEXT = "Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy "
        + "eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed "
        + "diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum."
        + " Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum "
        + "dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing "
        + "elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna"
        + " aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo "
        + "dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus"
        + " est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur"
        + " sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et "
        + "dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam "
        + "et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea "
        + "takimata sanctus est Lorem ipsum dolor sit amet.   \n"
        + "\n"
        + "Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse "
        + "molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero"
        + " eros et accumsan et iusto odio dignissim qui blandit praesent luptatum"
        + " zzril delenit augue duis dolore te feugait nulla facilisi. Lorem ipsum"
        + " dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh "
        + "euismod tincidunt ut laoreet dolore magna aliquam erat volutpat.   \n"
        + "\n"
        + "Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper "
        + "suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem "
        + "vel eum iriure dolor in hendrerit in vulputate velit esse molestie "
        + "consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et "
        + "accumsan et iusto odio dignissim qui blandit praesent luptatum zzril "
        + "delenit augue duis dolore te feugait nulla facilisi.   \n"
        + "\n"
        + "Nam liber tempor cum soluta nobis eleifend option congue nihil "
        + "imperdiet doming id quod mazim placerat facer possim assum. Lorem ipsum"
        + " dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh "
        + "euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut "
        + "wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper "
        + "suscipit lobortis nisl ut aliquip ex ea commodo consequat.   \n"
        + "\n"
        + "Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse "
        + "molestie consequat, vel illum dolore eu feugiat nulla facilisis.   \n"
        + "\n"
        + "At vero eos et accusam et justo duo dolores et ea rebum. Stet clita "
        + "kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet."
        + " Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam "
        + "nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, "
        + "sed diam voluptua. At vero eos et accusam et justo duo dolores et ea "
        + "rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem "
        + "ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing"
        + " elitr, At accusam aliquyam diam diam dolore dolores duo eirmod eos "
        + "erat, et nonumy sed tempor et et invidunt justo labore Stet clita ea et"
        + " gubergren, kasd magna no rebum. sanctus sea sed takimata ut vero "
        + "voluptua. est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, "
        + "consetetur";

    @Test
    public void testBug()  {
        List<Field> nestedFields = new ArrayList<>();

        FieldSetField nested1 = new FieldSetField();
        nested1.setLabelKey(LONG_TEXT);
        nested1.setFields(new ArrayList<>());
        IntStream.range(1, 9).forEach(i -> nestedFields.add(nested1));

        FieldSetField field1 = new FieldSetField();
        field1.setLabelKey("my.label.key");
        field1.setFields(nestedFields);

        List<FieldSetField> fields = new ArrayList();
        IntStream.range(1,10).forEach(i -> fields.add(field1));

        com.aspose.pdf.Document document = new com.aspose.pdf.Document();
        com.aspose.pdf.Page page = document.getPages().add();

        for (FieldSetField field: fields) {
            BaseParagraph renderedField = visit(field);
            page.getParagraphs().add(renderedField);
        }

        document.save("myExample.pdf");
    }

    public BaseParagraph visit(FieldSetField field) {
        Table table = new Table();
        table.setColumnWidths("500");
        Cell cell = table.getRows().add().getCells().add();

        table.setMargin(new MarginInfo(0, 10, 0, 10));

        if (!StringUtils.isEmpty(field.getLabelKey())) {
            TextFragment textFragment = new TextFragment(field.getLabelKey());
            textFragment.getTextState().setFontSize(14);
            textFragment.getTextState().setForegroundColor(Color.getDarkSlateGray());
            textFragment.setMargin(new MarginInfo(0,0,0,10));

            cell.getParagraphs().add(textFragment);

            cell.setMargin(new MarginInfo(0, 5, 0, 0));
        }

        if (!field.getFields().isEmpty()) {
            for(Field child : field.getFields()) {
                BaseParagraph baseParagraph = visit((FieldSetField) child);
                cell.getParagraphs().add(baseParagraph);
            }
        }

        return table;
    }

    public class Field {
        private String labelKey;

        public String getLabelKey() {
            return labelKey;
        }

        public void setLabelKey(String labelKey) {
            this.labelKey = labelKey;
        }
    }

    public class FieldSetField extends Field {
        private List<Field> fields;

        public List<Field> getFields() {
            return fields;
        }

        public void setFields(List<Field> fields) {
            this.fields = fields;
        }
    }

}

@stefan.raubal

Thank you for sharing the code.

We are checking the scenario in our environment and will get back to you soon.

@stefan.raubal

We have been able to notice the problem in our environment. A ticket with ID PDFJAVA-38024 has been logged in our issue management system for further investigation and resolution. The ticket ID has been linked with this thread so that you will receive notification as soon as the ticket is resolved.

We are sorry for the inconvenience.