在 PDF 中,OP 指出(边距.pdf http://examples.itextpdf.com/results/part4/chapter15/margins.pdf来自 iText 样本本身)确实该框与文本不齐平:
但是,如果您查看 PDF 内容,您会发现许多行都有尾随空格字符,例如第一行:
(s I have worn out since I started my ) Tj
这些尾随空格字符是文本的一部分,因此,该框不会与可见文本齐平,但会与包含此类空格字符的文本齐平。
如果您想忽略此类空格字符,您可以尝试通过过滤此类尾随空格(或为了简单起见所有空格),然后再将它们送入TextMarginFinder
。为此,我会爆炸TextRenderInfo
按字符实例,然后过滤那些修剪为空字符串的实例。
用于分解渲染信息对象的辅助类:
import com.itextpdf.text.pdf.parser.ImageRenderInfo;
import com.itextpdf.text.pdf.parser.RenderListener;
import com.itextpdf.text.pdf.parser.TextRenderInfo;
public class TextRenderInfoSplitter implements RenderListener
{
public TextRenderInfoSplitter(RenderListener strategy) {
this.strategy = strategy;
}
public void renderText(TextRenderInfo renderInfo) {
for (TextRenderInfo info : renderInfo.getCharacterRenderInfos()) {
strategy.renderText(info);
}
}
public void beginTextBlock() {
strategy.beginTextBlock();
}
public void endTextBlock() {
strategy.endTextBlock();
}
public void renderImage(ImageRenderInfo renderInfo) {
strategy.renderImage(renderInfo);
}
final RenderListener strategy;
}
使用此帮助程序,您可以像这样更新 iText 示例:
RenderFilter spaceFilter = new RenderFilter() {
public boolean allowText(TextRenderInfo renderInfo) {
return renderInfo != null && renderInfo.getText().trim().length() > 0;
}
};
PdfReader reader = new PdfReader(src);
PdfReaderContentParser parser = new PdfReaderContentParser(reader);
PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(RESULT));
for (int i = 1; i <= reader.getNumberOfPages(); i++) {
TextMarginFinder finder = new TextMarginFinder();
FilteredRenderListener filtered = new FilteredRenderListener(finder, spaceFilter);
parser.processContent(i, new TextRenderInfoSplitter(filtered));
PdfContentByte cb = stamper.getOverContent(i);
cb.rectangle(finder.getLlx(), finder.getLly(), finder.getWidth(), finder.getHeight());
cb.stroke();
}
stamper.close();
reader.close();
结果:
如果是 slug 区域文本等,您可能需要过滤更多内容,例如裁剪框之外的任何内容。
但请注意,有些字体中的空格字符可能不可见,例如盒装字符的字体。在这种情况下,将空格从等式中剔除是错误的。