Creating Lists with PDFBox-Layout
The last article gave you a brief introduction on what you can do with PDFBox-Layout. The new release 0.6.0 added support for indentation and lists, and that’s what this article is about.
So what do we do here: we add an indent of 50pt width. This indent will be automatically inserted after each newline until the end of the paragraph…or a new indent is inserted. That’s what we do here, we insert an indent of 70pt:
An indent may also have a label (after all, this is the foundation for lists). By default the label is right aligned, as this makes sense for lists. But you may specify an alignment to fit your needs:
Indents run until the end of a paragraph, or until another indentation starts. But you can you can explicitly end the indentation with
The default indent is 4 characters, but you can customize this by specifying the desired indentation in
To create lists with bullets, use the
You can specify different levels of indentation just be prefixing the indent markup with one or multiple spaces:
You can customize the indent size and the bullet character (after all, this is the indentation label). Let's do an indent of 8 characters and use
Enumerated lists are supported also, just use the
Again, you can customize the indent size and also the enumeration type. The default type is arabic numbers, but let's use the roman enumerator: `-#{I:6em}. The following enumerator types are built in:
But you may also write your own enumerator and use it in markup, see class
Regards
Ralf
Indentation
Indentation is often used to structure content, and it is also the base for creating lists. Let’s start with some simple example using the Indent element.paragraph.addMarkup( "This is an example for the new indent feature. Let's do some empty space indentation:\n", 11, BaseFont.Times); paragraph.add(new Indent(50, SpaceUnit.pt)); paragraph.addMarkup("Here we go indented.\n", 11, BaseFont.Times); paragraph.addMarkup( "The Indentation holds for the rest of the paragraph, or... \n", 11, BaseFont.Times); paragraph.add(new Indent(70, SpaceUnit.pt)); paragraph.addMarkup("any new indent comes.\n", 11, BaseFont.Times);
So what do we do here: we add an indent of 50pt width. This indent will be automatically inserted after each newline until the end of the paragraph…or a new indent is inserted. That’s what we do here, we insert an indent of 70pt:
An indent may also have a label (after all, this is the foundation for lists). By default the label is right aligned, as this makes sense for lists. But you may specify an alignment to fit your needs:
paragraph = new Paragraph(); paragraph .addMarkup( "New paragraph, now indentation is gone. But we can indent with a label also:\n", 11, BaseFont.Times); paragraph.add(new Indent("This is some label", 100, SpaceUnit.pt, 11, PDType1Font.TIMES_BOLD)); paragraph.addMarkup("Here we go indented.\n", 11, BaseFont.Times); paragraph .addMarkup( "And again, the Indentation holds for the rest of the paragraph, or any new indent comes.\nLabels can be aligned:\n", 11, BaseFont.Times); paragraph.add(new Indent("Left", 100, SpaceUnit.pt, 11, PDType1Font.TIMES_BOLD, Alignment.Left)); paragraph.addMarkup("Indent with label aligned to the left.\n", 11, BaseFont.Times); paragraph.add(new Indent("Center", 100, SpaceUnit.pt, 11, PDType1Font.TIMES_BOLD, Alignment.Center)); paragraph.addMarkup("Indent with label aligned to the center.\n", 11, BaseFont.Times); paragraph.add(new Indent("Right", 100, SpaceUnit.pt, 11, PDType1Font.TIMES_BOLD, Alignment.Right)); paragraph.addMarkup("Indent with label aligned to the right.\n", 11, BaseFont.Times); document.add(paragraph);
Lists
As already said, indentations where introduced in order to support list, so let's build one. It's nothing but indentation with a label, where the label is a bullet character:paragraph = new Paragraph(); paragraph.addMarkup( "So, what can you do with that? How about lists:\n", 11, BaseFont.Times); paragraph.add(new Indent(bulletOdd, 4, SpaceUnit.em, 11, PDType1Font.TIMES_BOLD, Alignment.Right)); paragraph.addMarkup("This is a list item\n", 11, BaseFont.Times); paragraph.add(new Indent(bulletOdd, 4, SpaceUnit.em, 11, PDType1Font.TIMES_BOLD, Alignment.Right)); paragraph.addMarkup("Another list item\n", 11, BaseFont.Times); paragraph.add(new Indent(bulletEven, 8, SpaceUnit.em, 11, PDType1Font.TIMES_BOLD, Alignment.Right)); paragraph.addMarkup("Sub list item\n", 11, BaseFont.Times); paragraph.add(new Indent(bulletOdd, 4, SpaceUnit.em, 11, PDType1Font.TIMES_BOLD, Alignment.Right)); paragraph.addMarkup("And yet another one\n", 11, BaseFont.Times);
Ordered Lists with Enumerators
Ordered lists are quite helpful to structure and reference text. You already have all ingredients to build an ordered lists; just use increasing numbers as labels, and that's it. What would I need an API for to do that?!? How about a list with roman numbers:RomanEnumerator e1 = new RomanEnumerator(); LowerCaseAlphabeticEnumerator e2 = new LowerCaseAlphabeticEnumerator(); paragraph = new Paragraph(); paragraph.addMarkup("Also available with indents: Enumerators:\n", 11, BaseFont.Times); paragraph.add(new Indent(e1.next() + ". ", 4, SpaceUnit.em, 11, PDType1Font.TIMES_BOLD, Alignment.Right)); paragraph.addMarkup("First item\n", 11, BaseFont.Times); paragraph.add(new Indent(e1.next() + ". ", 4, SpaceUnit.em, 11, PDType1Font.TIMES_BOLD, Alignment.Right)); paragraph.addMarkup("Second item\n", 11, BaseFont.Times); paragraph.add(new Indent(e2.next() + ") ", 8, SpaceUnit.em, 11, PDType1Font.TIMES_BOLD, Alignment.Right)); paragraph.addMarkup("A sub item\n", 11, BaseFont.Times); paragraph.add(new Indent(e2.next() + ") ", 8, SpaceUnit.em, 11, PDType1Font.TIMES_BOLD, Alignment.Right)); paragraph.addMarkup("Another sub item\n", 11, BaseFont.Times); paragraph.add(new Indent(e1.next() + ". ", 4, SpaceUnit.em, 11, PDType1Font.TIMES_BOLD, Alignment.Right)); paragraph.addMarkup("Third item\n", 11, BaseFont.Times); document.add(paragraph);
Enumerators ease the task of generating ordered lists programmatically (and the markup API could not live without 'em ;-). Currently the following enumerators are supported:
- ArabicEnumerator (1, 2, 3, 4...)
- RomanEnumerator (I, II, III, IV...)
- LowerCaseRomanEnumerator (i, ii, iii, iv...)
- AlphabeticEnumerator (A, B, C, D...)
- LowerCaseAlphabeticEnumerator (a, b, c, d...)
Markup
The markup API eases the burden of creating features programatically, and for sure you can do indentation and lists with markup. We're gonna start with some simple indentation. You start the indentation with--
at the beginning of a new line:"--At vero eos et accusam\n"
Indents run until the end of a paragraph, or until another indentation starts. But you can you can explicitly end the indentation with
!-
:"-!And end the indentation.\n"
The default indent is 4 characters, but you can customize this by specifying the desired indentation in
pt
or em
, so the markup --{50pt}
will give you an indent of 50pt. Be aware that this size is per indent level, so if you prefix a space, you will get 100pt in this case.
To create lists with bullets, use the
-+
markup:"-+This is a list item\n" "-+Another list item\n"
You can specify different levels of indentation just be prefixing the indent markup with one or multiple spaces:
" -+A sub list item\n"
You can customize the indent size and the bullet character (after all, this is the indentation label). Let's do an indent of 8 characters and use
>>
as the bullet: -+{>>:8em}
Enumerated lists are supported also, just use the
-#
markup:"-#This is a list item\n" "-#Another list item\n" " -#{a:}A sub list with lower case letter\n" "-#And yet another one\n\n"
Again, you can customize the indent size and also the enumeration type. The default type is arabic numbers, but let's use the roman enumerator: `-#{I:6em}. The following enumerator types are built in:
- 1 arabic
- I roman, upper case
- i roman, lower case
- A alphabetic, upper case
- a alphabetic, lower case
"-#This is a list item\n" "-!And you can customize it:\n" "-#{I ->:5}This is a list item\n" "-#{I ->:5}Another list item\n" " -#{a ~:30pt}A sub list item\n" "-#{I ->:5}And yet another one\n\n";
But you may also write your own enumerator and use it in markup, see class
EnumeratorFactory
for more details on that.Regards
Ralf
The human animal differs from the lesser primates in his passion for lists.
H. Allen Smith
This comment has been removed by the author.
ReplyDeleteHi. I think this is what I am looking for. How do I get this as a .jar file to include in my project? I'm very new to this please.
ReplyDeleteHi. I think this is what I am looking for. How do I get this as a .jar file to include in my project? I'm very new to this please.
ReplyDeleteMost people use maven, gradle etc. dependency management. However, I've added some download links on the GitHub readme page, so you may directly download the jars :-)
ReplyDeleteRegards
Ralf
Thanks for an amazing work, I am having an issue with creating a table based layout with multiple rows and columns using Paragraph and Indentation. Is there an example I can refer or is there any support for table based layout? Much appreciated.
DeleteThank you very much.
ReplyDeleteVery usefull library
Hi, thanks a lot for this very useful API.
ReplyDeleteOne enhancement to be considered in my opinion is the automatic first line indentation of paragraphs. I tried to add the tabulation character '\t' at the beginning of my paragraph but I got an error (IllegalArgumentException in PDType1Font.java line 425 in the 'encode' method).
Hi Ralf,
ReplyDeleteyou did a great job.
How do I put some text on a page and then insert another text into another. Ad example PAGE A CONTENT (BLABLABLA) PAGE B CONTENT (TESTTEST).
Thanks.
großartige Arbeit.
Hi, I just wanted to ask, if the pdfbox-layout supports loading existing pdfs and extracting layout and other information. Or are these features only for the creation of new documents.
ReplyDeleteThank you