Я создаю pdf, и мне нужна пост-обработка в рабочем процессе для обновления контента, для этого лучшим способом поиска является создание PdfFormField с аннотацией.xmlworker создавать аннотации в поле формы для дальнейших поисков
После создания полей с аннотациями я могу искать позиции через объект AcroField и получать страницы и позиции.
public static List<FieldPosition> getPositions(PdfReader pdfReader, String name) {
AcroFields acroFields = pdfReader.getAcroFields();
List<FieldPosition> fieldPositions = acroFields.getFieldPositions(name);
return fieldPositions;
}
И вы можете нарисовать текст в позиции, как это:
public static void writeString(PdfReader pdfReader, PdfStamper pdfStamper, String name, String valueStr, Font fontType, float leftDiff,
float bottomDiff) throws IOException, DocumentException {
Phrase pagePhrase = new Phrase(valueStr, fontType);
float left;
float bottom;
List<FieldPosition> fieldPositions = getPositions(pdfReader, name);
if (fieldPositions != null) {
for (FieldPosition fieldPos : fieldPositions) {
left = fieldPos.position.getLeft() + leftDiff;
bottom = fieldPos.position.getBottom() + bottomDiff;
PdfContentByte cover = pdfStamper.getOverContent(fieldPos.page);
ColumnText.showTextAligned(cover, Element.ALIGN_LEFT, pagePhrase, left, bottom, 0);
}
}
}
Вы можете проверить образец для создания поля форм здесь http://itextpdf.com/examples/iia.php?id=157 образец выше, используя простой IText API со столом и клеток (вы можете см. ячейку используется для получения прямоугольника для поля)
Я пытаюсь создать те же поля двумя способами. Создать процессор для ячейки (TD) или для поля (вход или любой другой)
TagProcessorFactory tagProcessorFactory = Tags.getHtmlTagProcessorFactory();
tagProcessorFactory.addProcessor(new XHTMLTableTagProcessor(), new String[] { "table" });
tagProcessorFactory.addProcessor(new XHTMLCellMarkTagProcessor(writer), new String[] { "td" });
tagProcessorFactory.addProcessor(new XHTMLInputMarkTagProcessor(writer), new String[] { "input" });
HtmlPipelineContext htmlContext = new HtmlPipelineContext(null);
htmlContext.setTagFactory(tagProcessorFactory);
Сотовый процессор
public class XHTMLCellMarkTagProcessor extends AbstractTagProcessor {
private PdfWriter writer;
public XHTMLCellMarkTagProcessor(PdfWriter writer) {
this.writer = writer;
}
@Override
public List<Element> end(WorkerContext ctx, Tag tag, List<Element> currentContent) {
String mark = "mark";
String strMark = tag.getAttributes().get(mark);
String strName = tag.getAttributes().get("name");
boolean isMark = StringUtils.isAlpha(strMark) && strMark.equalsIgnoreCase("true");
System.out.println(String.format(currentContent.size() + "<<< %s %s ", strName, strMark));
List<Element> retval = super.end(ctx, tag, currentContent);
if (isMark && StringUtils.isNotBlank(strName)) {
for (Element element : retval) {
if (element instanceof PdfPCell) {
final TextField nameField = new TextField(writer, new Rectangle(0, 0, 1, 5), strName);
try {
final PdfFormField formField = nameField.getTextField();
final int width = 1;
PdfPCellEvent cellEvent = new PdfPCellEvent() {
@Override
public void cellLayout(PdfPCell cell, Rectangle position, PdfContentByte[] canvases) {
try {
formField.setWidget(new Rectangle(position.getLeft(), position.getBottom(), position.getLeft() + width,
position.getTop()), PdfAnnotation.HIGHLIGHT_NONE);
writer.addAnnotation(formField);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
};
((PdfPCell) element).setCellEvent(cellEvent);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
}
return retval;
}
}
элементы всегда равны нулю, даже если родитель вызывается или нет, не существует процессора по умолчанию для таких ячеек, как таблицы или divs Получить ошибку: java.lang.IllegalArgumentException: количество столбцов в конструкторе PdfPTable должно быть больше нуля.
вход процессора
public class XHTMLInputMarkTagProcessor extends AbstractTagProcessor {
private PdfWriter writer;
public XHTMLInputMarkTagProcessor(PdfWriter writer) {
this.writer = writer;
}
@Override
public List<Element> start(final WorkerContext ctx, final Tag tag) {
List<Element> elements = super.start(ctx, tag);
try {
String mark = "mark";
String strMark = tag.getAttributes().get(mark);
String strType = tag.getAttributes().get("type");
String strName = tag.getAttributes().get("name");
String strSize = tag.getAttributes().get("size");
String strValue = tag.getAttributes().get("value");
boolean isMark = StringUtils.isAlpha(strMark) && strMark.equalsIgnoreCase("true");
int size = StringUtils.isNumeric(strSize) ? new Integer(strSize.trim()) : 0;
System.out.println(String.format("<<< %s %s %s %s %s", strName, strType, strMark, strSize, size));
if (isMark && StringUtils.isNotBlank(strType) && strType.equals("text")) {
TextField nameField = new TextField(writer, new Rectangle(100, 100, 100, 50), strName);
nameField.setBackgroundColor(BaseColor.GREEN);
PdfFormField formField = nameField.getTextField();
formField.setValueAsString(strValue);
formField.setWidget(new Rectangle(100, 100, 100, 100), PdfAnnotation.HIGHLIGHT_PUSH);
writer.addAnnotation(formField);
//System.out.println("ADDDD");
}
} catch (Exception e) {
throw new RuntimeException(e);
}
return elements;
}
}
Я не вижу ничего в результате PDF. Объект TextField, не могут быть добавлены в список элементов, поскольку не распространяется на элемент интерфейса