PDFBox U+00A0 在此字体编码中不可用
PDFBox U+00A0 is not available in this font's encoding
我在调用 PDField 的 setValue 方法并尝试设置包含特殊字符的值时遇到问题。
field.setValue("TEST-BY (TEST)")
具体来说,如果我的值包含 U+00A0 这样的字符,我会遇到以下异常:
Caused by: java.lang.IllegalArgumentException: U+00A0 is not
available in this font's encoding: WinAnsiEncoding
完整的 stracktrace 可以在这里找到:Stacktrace
我目前已将 PDType1Font.TIMES_ROMAN 设置为字体。为了解决这个问题,我也尝试了其他可用的字体。同样的问题仍然存在。
我在这个答案中发现了以下建议 但由于我们使用的是 setValue 而不是任何可以操作字节的方法 showText/drawText ,我无法使用这种方法,因为 setValue 只接受字符串作为参数。
注意:我无法用其他字符替换字符来解决这个问题,我必须能够在setValue方法中设置字体字符支持的任何类型。
你必须嵌入字体而不是使用 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);
注意这个代码必须是运行才能调用setValue()
.
在源代码下载的 CreateSimpleFormWithEmbeddedFont.java 示例中有更多相关信息。
避免使用 WinAnsiEncoding(编码问题)
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 */
我在调用 PDField 的 setValue 方法并尝试设置包含特殊字符的值时遇到问题。
field.setValue("TEST-BY (TEST)")
具体来说,如果我的值包含 U+00A0 这样的字符,我会遇到以下异常:
Caused by: java.lang.IllegalArgumentException: U+00A0 is not available in this font's encoding: WinAnsiEncoding
完整的 stracktrace 可以在这里找到:Stacktrace
我目前已将 PDType1Font.TIMES_ROMAN 设置为字体。为了解决这个问题,我也尝试了其他可用的字体。同样的问题仍然存在。
我在这个答案中发现了以下建议 但由于我们使用的是 setValue 而不是任何可以操作字节的方法 showText/drawText ,我无法使用这种方法,因为 setValue 只接受字符串作为参数。
注意:我无法用其他字符替换字符来解决这个问题,我必须能够在setValue方法中设置字体字符支持的任何类型。
你必须嵌入字体而不是使用 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);
注意这个代码必须是运行才能调用setValue()
.
在源代码下载的 CreateSimpleFormWithEmbeddedFont.java 示例中有更多相关信息。
避免使用 WinAnsiEncoding(编码问题)
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 */