如何使用 iText 读取 PDF 文件作为模板
How to read PDF file as template using iText
我正在尝试读取单页 PDF 文件并动态替换其中的一些内容(即日期、页码)。
Here 是我的示例 PDF 文件。
(文件是用 MS Word
创建的。所有元素都是表格)
我知道我可以用 Acro Form
做到这一点,但在 Word
中,用户创建模板要简单得多。
在这个例子中,我想用当前日期替换 {CREATE_DATE}
,{DATA_AREA}
是内容区域,{PAGE_NUMBER}
是当前页码。
到目前为止我所做的是覆盖 ITextExtractionStrategy
并将其作为 delegate
传递给 GlyphTextEventListener
。
通过这样做,我可以读取每个字符,获取它的位置并计算它占用的总宽度,然后,我将每个新页面的结果传递给 IEventHandler
。
private void renderText(TextRenderInfo renderInfo) {
if (renderInfo.getText().trim().length() == 0) {
if (text.isEmpty()) {
return;
} else {
LineSegment ascent = renderInfo.getAscentLine();
endX = ascent.getEndPoint().get(0);
endY = ascent.getEndPoint().get(1);
Rectangle rectangle = new Rectangle(initX, initY, endX - initX, endY - initY);
FontFilter fontFilter = new FontFilter(rectangle);
boolean accept = fontFilter.accept(renderInfo, EventType.RENDER_TEXT);
float fontSize;
if (accept) {
fontSize = fontFilter.getFontSize();
}else {
fontSize = 8;
}
SimpleTextWithRectangle textWithRectangle = new SimpleTextWithRectangle(rectangle, text,
fontSize);
textWithRectangleList.add(textWithRectangle);
text = "";
initX = 0; initY = 0; endX = 0; endY = 0;
return;
}
}
LineSegment descent = renderInfo.getDescentLine();
if (text.isEmpty()) { // start word
initX = descent.getStartPoint().get(0);
initY = descent.getStartPoint().get(1);
}
text = text + renderInfo.getText();
}
我想要实现的是获得边界(如果可能的话,线)以便我可以定义数据区域。
提前致谢。
我找到了一个解决方案,为我提供了线路。
我的解决方案是覆盖RegexBasedLocationExtractionStrategy
,然后实现
eventOccurred
像这样:
public void eventOccurred(IEventData data, EventType type) {
if (data instanceof TextRenderInfo) {
super.eventOccurred(data, type);
} else if (type == EventType.RENDER_PATH) {
readRectangles((PathRenderInfo) data);
} else if (type == EventType.RENDER_IMAGE) {
readImage((ImageRenderInfo) data);
}
}
现在 readRectangles
我可以从路径中获取所有行并计算数据区域边界。
我正在尝试读取单页 PDF 文件并动态替换其中的一些内容(即日期、页码)。
Here 是我的示例 PDF 文件。
(文件是用 MS Word
创建的。所有元素都是表格)
我知道我可以用 Acro Form
做到这一点,但在 Word
中,用户创建模板要简单得多。
在这个例子中,我想用当前日期替换 {CREATE_DATE}
,{DATA_AREA}
是内容区域,{PAGE_NUMBER}
是当前页码。
到目前为止我所做的是覆盖 ITextExtractionStrategy
并将其作为 delegate
传递给 GlyphTextEventListener
。
通过这样做,我可以读取每个字符,获取它的位置并计算它占用的总宽度,然后,我将每个新页面的结果传递给 IEventHandler
。
private void renderText(TextRenderInfo renderInfo) {
if (renderInfo.getText().trim().length() == 0) {
if (text.isEmpty()) {
return;
} else {
LineSegment ascent = renderInfo.getAscentLine();
endX = ascent.getEndPoint().get(0);
endY = ascent.getEndPoint().get(1);
Rectangle rectangle = new Rectangle(initX, initY, endX - initX, endY - initY);
FontFilter fontFilter = new FontFilter(rectangle);
boolean accept = fontFilter.accept(renderInfo, EventType.RENDER_TEXT);
float fontSize;
if (accept) {
fontSize = fontFilter.getFontSize();
}else {
fontSize = 8;
}
SimpleTextWithRectangle textWithRectangle = new SimpleTextWithRectangle(rectangle, text,
fontSize);
textWithRectangleList.add(textWithRectangle);
text = "";
initX = 0; initY = 0; endX = 0; endY = 0;
return;
}
}
LineSegment descent = renderInfo.getDescentLine();
if (text.isEmpty()) { // start word
initX = descent.getStartPoint().get(0);
initY = descent.getStartPoint().get(1);
}
text = text + renderInfo.getText();
}
我想要实现的是获得边界(如果可能的话,线)以便我可以定义数据区域。
提前致谢。
我找到了一个解决方案,为我提供了线路。
我的解决方案是覆盖RegexBasedLocationExtractionStrategy
,然后实现
eventOccurred
像这样:
public void eventOccurred(IEventData data, EventType type) {
if (data instanceof TextRenderInfo) {
super.eventOccurred(data, type);
} else if (type == EventType.RENDER_PATH) {
readRectangles((PathRenderInfo) data);
} else if (type == EventType.RENDER_IMAGE) {
readImage((ImageRenderInfo) data);
}
}
现在 readRectangles
我可以从路径中获取所有行并计算数据区域边界。