私はpdfを作成し、ワークフローで後処理してコンテンツを更新する必要があります。これを見つける最良の方法は、注釈付きのPdfFormFieldを作成することです。
注釈付きのフィールドを作成した後、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 を使用しています (セルが長方形を取得するために使用されていることがわかります)フィールド用)
同じフィールドを 2 つの方法で作成しようとしています。セル (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;
}
}
親が呼び出されたかどうかにかかわらず、要素は常にゼロです。テーブルや div などのセルのデフォルト プロセッサは存在し ません。
入力プロセッサ
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 に何も表示されません。 Element インターフェイスの拡張がないため、TextField オブジェクトを要素リストに追加できません