Java 如何在使用PDFBox将字符串打印为PDF之前对其进行消毒
我正在从UTF-8用户输入创建PDF文档 除了显示PDF之外,创建本身也会失败,原因是Java 如何在使用PDFBox将字符串打印为PDF之前对其进行消毒,java,pdf,encoding,utf-8,pdfbox,Java,Pdf,Encoding,Utf 8,Pdfbox,我正在从UTF-8用户输入创建PDF文档 除了显示PDF之外,创建本身也会失败,原因是java.lang.IllegalArgumentException:U+039B在此字体的编码中不可用:winansienceoding 这里的大多数答案都指向“使用具有更好UTF-8支持的字体”,但由于我无法控制用户输入,这种UTF-8支持永远都不够好,我需要一个防弹解决方案(比如打印一些东西而不是出错) 答案是,在将文本添加到PDF之前,应该对其进行消毒 问题是我找不到有效的例子来实现这一点。 所有的例子
java.lang.IllegalArgumentException:U+039B在此字体的编码中不可用:winansienceoding
这里的大多数答案都指向“使用具有更好UTF-8支持的字体”,但由于我无法控制用户输入,这种UTF-8支持永远都不够好,我需要一个防弹解决方案(比如打印一些东西而不是出错)
答案是,在将文本添加到PDF之前,应该对其进行消毒
问题是我找不到有效的例子来实现这一点。
所有的例子似乎都指向删除的代码(font.setToUnicode
或某种编码方法,一次转换一个字符)
简而言之,我有一个字符串,我想要一个防弹方法将它的大部分写入PDFBox文档(显然,字体中缺少的字符将被替换或不打印)
非常感谢,,
JM我结束了一个字符一个字符的清理 这里是我的消毒功能的样子 为了避免重新处理字符,我正在缓存每个给定字体的每个字符的可用性 当字体中的代码点不可用时,我将尝试使用“标准”替换字符,如果不可用,我将使用问号替换 这确实是低效的,但我还没有找到另一种更有效的方法来做到这一点,因为我没有控制权,也不知道正在打印什么 可能有很多地方需要改进,但这对我的用例是有效的
private String getPrintableString(String string, PDFont font) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < string.length(); i++) {
int codePoint = string.codePointAt(i);
if (codePoint == 0x000A) {
sb.appendCodePoint(codePoint);
continue;
}
String fontName = font.getName();
int cpKey = fontName.hashCode();
cpKey = 31 * cpKey + codePoint;
if (codePointAvailCache.get(cpKey) == null) {
try {
font.encode(string.substring(i, i + 1));
codePointAvailCache.put(cpKey, true);
} catch (Exception e) {
codePointAvailCache.put(cpKey, false);
}
}
if (!codePointAvailCache.get(cpKey)) {
// Need to make sure our font has a replacement character
try {
codePoint = 0xFFFD;
font.encode(new String(new int[] { codePoint }, 0, 1));
} catch (Exception e) {
codePoint = 0x003F;
}
}
sb.appendCodePoint(codePoint);
}
return sb.toString();
}
私有字符串getPrintableString(字符串字符串,PDFont){
StringBuilder sb=新的StringBuilder();
对于(int i=0;i
您使用哪个PDFBox版本?正如你提到的答案,版本1.8。x和2.0.xi-AM使用2.0.3(最后一个版本)的情况不同。你使用哪种字体?你如何使用它?Pdfbox 2.0.x允许您嵌入包含所需字形的字体子集。@mkl是的,我尝试了Ubuntu字体,这在一定程度上改进了一些东西,但它永远都不够好,因为我无法提前知道将打印哪些字符。我正在打印用户输入的文本,基本上他们可以访问整个UTF-8集。有没有办法知道字体中的字形代表什么代码点?这将是非常低效的,但我可以扫描所有字符串,并用PlaceHLoder替换丢失的字符。。。这有助于删除不可打印的字符