0

私は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 オブジェクトを要素リストに追加できません

4

1 に答える 1

0

解決策は、次のように TableData プロセッサを拡張する td TagProcessor を使用することです。

public class XHTMLCellMarkTagProcessor extends TableData {

    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");

        List<Element> retval = super.end(ctx, tag, currentContent);

        if (isMark && StringUtils.isNotBlank(strName)) {
            for (Element element : retval) {
                if (element instanceof PdfPCell) {
                    final TextField namedField = new TextField(writer, new Rectangle(0, 0, 10, 5), strName);
                    try {

                        final PdfFormField formField = namedField.getTextField();
                        final int width = 0;

                        PdfPCellEvent cellEvent = new PdfPCellEvent() {
                            @Override
                            public void cellLayout(PdfPCell cell, Rectangle position, PdfContentByte[] canvas) {
                                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;
    }
}
于 2015-09-30T21:49:34.847 に答える