Java PDFBox不一致PDTextField在setValue之后自动调整行为
我正在使用Apache PDFBox配置PDF文档中的Java PDFBox不一致PDTextField在setValue之后自动调整行为,java,jruby,pdfbox,Java,Jruby,Pdfbox,我正在使用Apache PDFBox配置PDF文档中的PDTextField,其中我使用以下方法将Lato加载到文档中: font = PDType0Font.load( @j_pd_document, java.io.FileInputStream.new('/path/to/Lato-Regular.ttf') ) # => Lato-Regular font_name = pd_default_resources.add(font).get_name # =>
PDTextField
,其中我使用以下方法将Lato
加载到文档中:
font = PDType0Font.load(
@j_pd_document,
java.io.FileInputStream.new('/path/to/Lato-Regular.ttf')
) # => Lato-Regular
font_name = pd_default_resources.add(font).get_name # => F4
然后,我将字体名称传递到PDTextField
的default\u外观\u字符串中,如下所示:
j_text_field.set_default_appearance("/#{font_name} 0 Tf 0 g") # where font_name is
# passed in from above
现在,当我继续调用PDTextField
上的setValue
时,问题就会出现。由于我将defaultappearancesstring
中的font\u size
设置为0
,因此根据库的设置,文本应自行缩放以适合文本框的给定区域。但是,对于某些字段,“按大小缩放”的行为是不一致的:它并不总是在PDTextField
中选择适合的最大字体大小。是否有任何进一步的配置允许这种情况发生?下面是我注意到出现此问题的PDF
未填充,已加载字体:
已填充,文本框文本大小不一致:
旁注:我通过jruby
使用PDFBox,它只是一个允许Ruby调用Java库的集成层。库中所有可用的java方法;像thisExampleMethod
这样的java方法将一对一地转换为rubythisExampleMethod
更新
作为对评论的回应,第二个上传文件示例中不正确的外观为:
- 第1页常驻名称字段(两个文本字段的文本对于给定的输入字段大小来说太小)
- 第二页电话字段(四个文本字段的文本溢出给定的输入字段大小)
尤其是居民姓名字段、电话字段和护理提供者地址字段的外观更为明显。OP只提到了前两个
让我们检查一下这些领域;所有屏幕截图均使用MS Windows上的Adobe Reader DC制作:
居民姓名字段
填写的居民姓名字段如下所示
虽然高度是适当的,但图示符比它们应该的窄。实际上,这种效果已经在原始PDF中看到:
此水平压缩是由字段窗口小部件矩形的纵横比不同于分别匹配的正常外观流边界框引起的:
- 小部件矩形:
[45.72 601.44 118.924 615.24]
和[119.282 601.127 192.486 614.927]
,即在这两种情况下都是73.204*13.8
- 外观边界框:
[0 0 147.24 13.8]
,即147.24*13.8
因此,它们具有相同的高度,但外观边界框的宽度约为小部件矩形的两倍。因此,当外观显示在窗口小部件矩形中时,通常在外观流中绘制的文本被压缩到其宽度的一半
设置字段值时,PDFBox不幸地按原样重新使用外观流,仅更新默认外观的详细信息,即字体名称、字体大小和颜色,以及实际文本值,显然,假定外观的其他属性因某种原因保持原样。因此,PDFBox输出也显示了这种水平压缩
要使PDFBox创建正确的外观,必须在设置新值之前删除旧外观
电话区
填充的电话字段如下所示
同样,原始文件中也有类似的显示
即使整个单词有足够的空间,也只显示前两个字母,这是由于这些字段的配置:它们被配置为最大长度为2个字符的组合字段
要在PDFBox完全显示且间距不太大的情况下在此处设置值,必须删除最大长度(或至少必须使其不小于值的长度)并取消设置梳状标志
护理提供者地址字段
填充它们看起来像这样:
最初它们看起来很相似:
这种垂直压缩也是由字段窗口小部件矩形的纵横比不同于分别匹配的正常外观流边界框引起的:
- 小部件矩形:
[278.6 642.928 458.36 657.96]
,即179.76*15.032
- 外观边界框:
[0 179.76 58.56]
,即179.76*58.56
与上面的常驻名称字段一样,在设置新值以使PDFBox创建正确的外观之前,有必要删除旧外观
并发症
实际上,在填写Care Providers Address(护理提供者地址)字段时还有一个问题,在删除旧外观后,它们看起来是这样的:
这是由于PDFBox的一个缺点:这些字段被配置为多行文本字段。虽然用于单行文本字段的PDFBox会根据内容正确计算字体大小,并随后精细地确保文本垂直适合,但对于多行字段,它进行得非常粗糙,它选择硬编码字体大小12,并且不会微调垂直位置,请参阅AppearanceGeneratorHelper
方法calculateFontSize(PDFont,PDRectangle)
和insertGeneratedAppearance(PDAnnotationWidget,PDAppearanceStream,OutputStream)
由于在您的表单中,这些地址字段无论如何都只有一行高,一个明显的解决方案是将这些字段设置为单行字段,即清除多行标志
示例代码
使用Java可以实现上述解决方案,如下所示:
final int FLAG\u MULTILINE=1不幸的是,您没有明确指出您认为哪些字段是错误的。我想你是指护理提供者的地址字段