11

I am facing a problem when invoking the setValue method of a PDField and trying to set a value which contains special characters.

field.setValue("TEST-BY  (TEST)")

In detail, if my value contains characters as U+00A0 i am getting the following exception:

Caused by: java.lang.IllegalArgumentException: U+00A0 is not available in this font's encoding: WinAnsiEncoding

A complete stracktrace can be found here: Stacktrace

I currently have set PDType1Font.TIMES_ROMAN as font. In order to solve this problem i tried with other available fonts as well. The same problem persisted.

I found the following suggestion in this answer https://stackoverflow.com/a/22274334/7434590 but since we use the setValue and not any of the methods showText/drawText that can manipulate bytes, i could not use this approach since setValue accepts only string as a parameter.

Note: I cannot replace the characters with others to solve this issue, i must be able to set any kind of supported by the font character in the setValue method.

assuna
  • 135
  • 1
  • 1
  • 8
  • Do you have any fonts that don't use `WinAnsiEncoding`? The question you linked is not related to your problem. It's about using the wrong encoding. Your question is about you insisting on using a character that doesn't exist in that font. Change the character or change the font. – Kayaman Sep 28 '17 at 13:29
  • Which PDFBox version do you use? – mkl Sep 28 '17 at 14:14
  • 1
    the version I use is 2.0.7 – assuna Sep 28 '17 at 17:18

2 Answers2

4

You'll have to embed a font and not use WinAnsiEncoding:

PDFont formFont = PDType0Font.load(doc, new FileInputStream("c:/windows/fonts/somefont.ttf"), false); // check that the font has what you need; ARIALUNI.TTF is good but huge
PDResources res = acroForm.getDefaultResources(); // could be null, if so, then create it with the setter
String fontName = res.add(formFont).getName();
String defaultAppearanceString = "/" + fontName + " 0 Tf 0 g"; // adjust to replace existing font name
textField.setDefaultAppearance(defaultAppearanceString);

Note that this code must be ran before calling setValue().

More about this in the CreateSimpleFormWithEmbeddedFont.java example from the source code download.

Tilman Hausherr
  • 17,731
  • 7
  • 58
  • 97
0

Avoid using WinAnsiEncoding (problems with encoding)

PDDocument document = new PDDocument();

//Fonts
InputStream fontInputStreamAvenirMedium = new URL(Constants.S3 + "/Fonts/Avenir-Medium.ttf").openStream();
InputStream fontInputStreamAvenirBlack = new URL(Constants.S3 + "/Fonts/Avenir-Black.ttf").openStream();
InputStream fontInputStreamDINCondensedBold = new URL(Constants.S3 + "/Fonts/DINCondensedBold.ttf").openStream();

PDFont font = PDType0Font.load(document, fontInputStreamAvenirMedium);
PDFont fontBold = PDType0Font.load(document, fontInputStreamAvenirBlack);
PDFont fontDIN = PDType0Font.load(document, fontInputStreamDINCondensedBold);


//PDFont font = PDTrueTypeFont.load(document, fontInputStreamAvenirMedium, WinAnsiEncoding.INSTANCE); /* encoding problems  */
//PDFont fontBold = PDTrueTypeFont.load(document, fontInputStreamAvenirBlack, WinAnsiEncoding.INSTANCE); /* encoding problems  */
//PDFont fontDIN = PDTrueTypeFont.load(document, fontInputStreamDINCondensedBold, WinAnsiEncoding.INSTANCE); /* encoding problems  */

See also: https://pdfbox.apache.org/2.0/faq.html#fontencoding

Davijr
  • 1,093
  • 11
  • 10