PDFBOX Same Stream with bold and normal text
I am trying to make something
Like: this (Having bold and normal text on the same line).
I've been using streams:
The preferable way for creating bold (or otherwise styled) text is to use a font variant which has been created explicitly for that variant. If no such font is available, though, it is possible to artificially emulate those styles:
- artificially bold: use text rendering mode 2 to not only fill the letter area but also draw a line along its outline
- artificially outlined: use text rendering mode 1 to draw a line along the outline of the letter instead of filling it
- artificially italic (actually slanted: change the text matrix to skew the output.
In code:
PDRectangle rec = new PDRectangle(220, 120);
PDDocument document = null;
document = new PDDocument();
PDPage page = new PDPage(rec);
document.addPage(page);
PDPageContentStream content = new PDPageContentStream(document, page, true, true);
content.beginText();
content.moveTextPositionByAmount(7, 105);
content.setFont(PDType1Font.HELVETICA, 12);
content.drawString("Normal text and ");
content.setFont(PDType1Font.HELVETICA_BOLD, 12);
content.drawString("bold text");
content.moveTextPositionByAmount(0, -25);
content.setFont(PDType1Font.HELVETICA_OBLIQUE, 12);
content.drawString("Italic text and ");
content.setFont(PDType1Font.HELVETICA_BOLD_OBLIQUE, 12);
content.drawString("bold italic text");
content.endText();
content.setLineWidth(.5f);
content.beginText();
content.moveTextPositionByAmount(7, 55);
content.setFont(PDType1Font.HELVETICA, 12);
content.drawString("Normal text and ");
content.appendRawCommands("2 Tr\n");
content.drawString("artificially bold text");
content.appendRawCommands("0 Tr\n");
content.moveTextPositionByAmount(0, -25);
content.appendRawCommands("1 Tr\n");
content.drawString("Artificially outlined text");
content.appendRawCommands("0 Tr\n");
content.setTextMatrix(1, 0, .2f, 1, 7, 5);
content.drawString("Artificially italic text and ");
content.appendRawCommands("2 Tr\n");
content.drawString("bold italic text");
content.appendRawCommands("0 Tr\n");
content.endText();
content.close();
document.save("StyledTexts.pdf");
document.close();
The result:
Frakcool
Sr Developer with 7+ years of experience Java Swing / Desktop apps fanatic Trying to become an iOS developer, have 1 year of experience on it and trying to increase that experience I love learning new things and working with new technologies. I really enjoy hard problems and challenges.
Updated on June 04, 2022Comments
-
Frakcool almost 2 years
Well I've been working with PDFBox I still don't understand it at all, but I've read the Documentation, working with fonts, and some other places, but I've found how to get the text from the PDF and it's style, but I'm creating it, not reading it.
I am trying to make something
Like: this (Having bold and normal text on the same line).
I've been using streams:
Not sure if this is all the code needed to help me, 'cause I just joined this project but it had started when I joined.
I would thank you all if you could help me implementing this code or maybe helping me with an idea or source where I could read the solution.
I leave my code here:
public void rCovernoteFooter(PDPageContentStream stream , float x, float y) throws IOException { y = y-20; String currentDate = df1.format(new Date()); String[] issues = constants.issued().split("/"); String issued = issues[0] + currentDate + issues[1]; y = rText(stream, x, y, 90, 0, 10, issued, null); stream.setFont(PDType1Font.TIMES_ROMAN, 8); y = rText(stream, x, y - 50, 117, 0, 10, constants.terms(), null); } public float rText(PDPageContentStream cStream, float x, float y, int col1, int col2, int spc, String data1, String data2) throws IOException { float y1 = 0f; float y2 = 0f; if (data2 == null) { y = iterate(data1, col1, x, y, spc, cStream); } else { y1 = iterate(data1, col1, x, y, spc, cStream); y2 = iterate(data2, col2, x + 125, y, spc, cStream); if (y1 >= y2) { return y2; } else { return y1; } } return y; } private float iterate(String text, int len, float x, float y, int space, PDPageContentStream stream) throws IOException { int rowHeight = 0; List<String> wordList = Lists.newArrayList(); wordList = wordLines(text, len); stream.setFont(PDType1Font.TIMES_BOLD, 10); for (String word : wordList) { stream.beginText(); stream.moveTextPositionByAmount(x, y - rowHeight); stream.drawString(word); stream.endText(); if (wordList.size() != 1) rowHeight = rowHeight + 10; } if (rowHeight >= space) { y = y - (rowHeight + 10); } else { y = y - space; } return y; }
Thanks in advice
-
Frakcool about 10 yearsThanks a lot, I'll read it and try to implement it; and btw thanks for the tip about the valid PDF I'll have it in mind
-
Frakcool about 10 yearsbtw could you teach me about how does "setTextMatrix(1, 0, .2f, 1, 7, 5);" works? just what does each parameter changes, I've been looking for it, but it only says: The Tm operator. Sets the text matrix to the given values. A current text matrix will be replaced with the new one. a - The a value of the matrix. thanks and sorry for asking such noob questions
-
mkl about 10 yearsYou might want to look at this answer and the sections of the PDF specification ISO 32000-1 referenced from there.
-
Dan King almost 8 yearsThis is a really useful answer, but appendRawCommands() is deprecated in the latest version of PDFBox. Any idea how you would create "artificially bold text" without using the deprecated API?
-
mkl almost 8 years@DanKing
getOutput().write(text.getBytes(Charsets.US_ASCII))
should work as a replacement forappendRawCommands(text)
in 2.0.x without deprecation warning. If that is what PDFBox development intended as replacement, I don't know. -
Dan King almost 8 yearsThanks mkl - but I can't see where that getOutput() method is coming from - it doesn't seem to exist on PDPageContentStream?
-
mkl almost 8 years@DanKing In 2.0.x it's inherited from
PDAbstractContentStream
, base class ofPDPageContentStream
. -
Dan King almost 8 yearsPDPageContentStream doesn't have a base class in pdfbox 2.0.2
-
mkl almost 8 yearsAh, sorry, I actually looked into the 2.1.0-SNAPSHOT development sources where
PDPageContentStream
has got a base classPDAbstractContentStream
- the issue PDFBOX-3353 is cause of this change. Thus, I assume this base class will soon be part of the release. -
mkl almost 8 years@DanKing In the current 2.0.x I do not see an alternative to
appendRawCommands
. -
Dan King almost 8 years:-( OK, thanks. It seems the PDFBox philosophy now is to move away from appending raw commands in favour of just using the API - which is fine as long as the API supports everything you want to be able to do...