Java 在工作期间,itext如何找到坐标文本?

Java 在工作期间,itext如何找到坐标文本?,java,itext,itext7,Java,Itext,Itext7,我想知道添加到页面的文本的坐标。 并将画布应用于此文本。(例如自定义下划线、删除线或三角形内的文本) 我只需要几个字 List<String> listString = new ArraList(); PdfDocument pdfDoc = new PdfDocument(new PdfWriter(DEST)); Document doc = new Document(pdfDoc, PageSize.A4); for(String s:listString) //**

我想知道添加到页面的文本的坐标。 并将画布应用于此文本。(例如自定义下划线、删除线或三角形内的文本)

我只需要几个字

List<String> listString = new ArraList();

PdfDocument pdfDoc = new PdfDocument(new PdfWriter(DEST));

Document doc = new Document(pdfDoc, PageSize.A4);
for(String s:listString)
   //**underlineWord** hidden it will be removed
 if( s.contains("**underlineWord**")){
     s.replace("**underlineWord**","");
    Text text = new Text(s)
    Float[] coords = getCoords(text)
     Canvas canvas = new Canvas(...);
     setCustomUderline(coords)
 }


 doc.add(new Paragraph(text) );
List listString=new ArraList();
PdfDocument pdfDoc=新PdfDocument(新PdfWriter(DEST));
文档文档=新文档(pdfDoc,PageSize.A4);
for(字符串s:listString)
//**underlineWord**隐藏它将被删除
如果(s.包含(“**下划线**”)){
s、 替换(“**下划线*”,“”);
文本文本=新文本
Float[]coords=getCoords(文本)
画布=新画布(…);
设置自定义数据线(coords)
}
添加文件(新的段落(文本));

我知道PdfCanvasProcessor,但我不使用它,因为我不知道某些单词(其中包含
**underlineWord**

在iText7中,您可以使用自定义
渲染器执行这些任务。该技术如图所示:

i、 e.您只需将自定义的
渲染器
设置为所讨论的
文本
位。在本例中,自定义
渲染器
类是

protected class DashedLineTextRenderer extends TextRenderer {
    public DashedLineTextRenderer(Text textElement) {
        super(textElement);
    }

    @Override
    public void draw(DrawContext drawContext) {
        super.draw(drawContext);
        Rectangle rect = this.getOccupiedAreaBBox();
        PdfCanvas canvas = drawContext.getCanvas();
        canvas
                .saveState()
                .setLineDash(3, 3)
                .moveTo(rect.getLeft(), rect.getBottom() - 3)
                .lineTo(rect.getRight(), rect.getBottom() - 3)
                .stroke()
                .restoreState();
    }
}
如您所见,您可以覆盖
draw
以首先调用
super
实现来正常绘制文本。之后,您可以通过调用
getoccupiederabbox
检索用于绘制文本的区域,并将其用于您的任务,无论是用于装饰文本还是仅将位置存储在某处


如果您想知道为什么此示例出现在
事件
子包中。。。该示例对应于iText5示例,在iText5中,您可以通过将通用标记设置到所讨论的
,并在页面事件侦听器的
onGenericTag
方法中侦听该通用标记来实现此任务,请参阅示例


在你询问的评论中

我可以用桌子吗?(使用帮助画布绘制边框)

是,再次使用关联的渲染器,例如,请参见:

这里,第一个表显示了如何在关闭标准表格单元格边框后使用表格渲染器执行此操作,而第二个表显示了如何使用单元格渲染器执行此操作

自定义的渲染器类是

private class DottedLineTableRenderer extends TableRenderer {
    public DottedLineTableRenderer(Table modelElement, Table.RowRange rowRange) {
        super(modelElement, rowRange);
    }

    @Override
    public void drawChildren(DrawContext drawContext) {
        super.drawChildren(drawContext);
        PdfCanvas canvas = drawContext.getCanvas();
        canvas.setLineDash(3f, 3f);
        // first horizontal line
        CellRenderer[] cellRenderers = rows.get(0);
        canvas.moveTo(cellRenderers[0].getOccupiedArea().getBBox().getLeft(),
                cellRenderers[0].getOccupiedArea().getBBox().getTop());
        canvas.lineTo(cellRenderers[cellRenderers.length - 1].getOccupiedArea().getBBox().getRight(),
                cellRenderers[cellRenderers.length - 1].getOccupiedArea().getBBox().getTop());

        for (int i = 0; i < rows.size(); i++) {
            cellRenderers = rows.get(i);
            // horizontal lines
            canvas.moveTo(cellRenderers[0].getOccupiedArea().getBBox().getX(),
                    cellRenderers[0].getOccupiedArea().getBBox().getY());
            canvas.lineTo(cellRenderers[cellRenderers.length - 1].getOccupiedArea().getBBox().getRight(),
                    cellRenderers[cellRenderers.length - 1].getOccupiedArea().getBBox().getBottom());
            // first vertical line
            Rectangle cellRect = cellRenderers[0].getOccupiedArea().getBBox();
            canvas.moveTo(cellRect.getLeft(), cellRect.getBottom());
            canvas.lineTo(cellRect.getLeft(), cellRect.getTop());
            // vertical lines
            for (int j = 0; j < cellRenderers.length; j++) {
                cellRect = cellRenderers[j].getOccupiedArea().getBBox();
                canvas.moveTo(cellRect.getRight(), cellRect.getBottom());
                canvas.lineTo(cellRect.getRight(), cellRect.getTop());
            }
        }
        canvas.stroke();
    }
}
分别



如中所述,
渲染器的完整自定义也应该覆盖
getNextRenderer()
方法。特别是,如果问题对象中可能出现区域中断,这是必要的,否则自定义仅在OP观察到的第一个区域中工作。

在iText7中,您可以使用自定义
渲染器执行此类任务。该技术如图所示:

i、 e.您只需将自定义的
渲染器
设置为所讨论的
文本
位。在本例中,自定义
渲染器
类是

protected class DashedLineTextRenderer extends TextRenderer {
    public DashedLineTextRenderer(Text textElement) {
        super(textElement);
    }

    @Override
    public void draw(DrawContext drawContext) {
        super.draw(drawContext);
        Rectangle rect = this.getOccupiedAreaBBox();
        PdfCanvas canvas = drawContext.getCanvas();
        canvas
                .saveState()
                .setLineDash(3, 3)
                .moveTo(rect.getLeft(), rect.getBottom() - 3)
                .lineTo(rect.getRight(), rect.getBottom() - 3)
                .stroke()
                .restoreState();
    }
}
如您所见,您可以覆盖
draw
以首先调用
super
实现来正常绘制文本。之后,您可以通过调用
getoccupiederabbox
检索用于绘制文本的区域,并将其用于您的任务,无论是用于装饰文本还是仅将位置存储在某处


如果您想知道为什么此示例出现在
事件
子包中。。。该示例对应于iText5示例,在iText5中,您可以通过将通用标记设置到所讨论的
,并在页面事件侦听器的
onGenericTag
方法中侦听该通用标记来实现此任务,请参阅示例


在你询问的评论中

我可以用桌子吗?(使用帮助画布绘制边框)

是,再次使用关联的渲染器,例如,请参见:

这里,第一个表显示了如何在关闭标准表格单元格边框后使用表格渲染器执行此操作,而第二个表显示了如何使用单元格渲染器执行此操作

自定义的渲染器类是

private class DottedLineTableRenderer extends TableRenderer {
    public DottedLineTableRenderer(Table modelElement, Table.RowRange rowRange) {
        super(modelElement, rowRange);
    }

    @Override
    public void drawChildren(DrawContext drawContext) {
        super.drawChildren(drawContext);
        PdfCanvas canvas = drawContext.getCanvas();
        canvas.setLineDash(3f, 3f);
        // first horizontal line
        CellRenderer[] cellRenderers = rows.get(0);
        canvas.moveTo(cellRenderers[0].getOccupiedArea().getBBox().getLeft(),
                cellRenderers[0].getOccupiedArea().getBBox().getTop());
        canvas.lineTo(cellRenderers[cellRenderers.length - 1].getOccupiedArea().getBBox().getRight(),
                cellRenderers[cellRenderers.length - 1].getOccupiedArea().getBBox().getTop());

        for (int i = 0; i < rows.size(); i++) {
            cellRenderers = rows.get(i);
            // horizontal lines
            canvas.moveTo(cellRenderers[0].getOccupiedArea().getBBox().getX(),
                    cellRenderers[0].getOccupiedArea().getBBox().getY());
            canvas.lineTo(cellRenderers[cellRenderers.length - 1].getOccupiedArea().getBBox().getRight(),
                    cellRenderers[cellRenderers.length - 1].getOccupiedArea().getBBox().getBottom());
            // first vertical line
            Rectangle cellRect = cellRenderers[0].getOccupiedArea().getBBox();
            canvas.moveTo(cellRect.getLeft(), cellRect.getBottom());
            canvas.lineTo(cellRect.getLeft(), cellRect.getTop());
            // vertical lines
            for (int j = 0; j < cellRenderers.length; j++) {
                cellRect = cellRenderers[j].getOccupiedArea().getBBox();
                canvas.moveTo(cellRect.getRight(), cellRect.getBottom());
                canvas.lineTo(cellRect.getRight(), cellRect.getTop());
            }
        }
        canvas.stroke();
    }
}
分别



如中所述,
渲染器的完整自定义也应该覆盖
getNextRenderer()
方法。特别是,如果问题对象中可能出现区域中断,则这是必要的,否则定制仅在OP观察到的第一个区域有效。

请更清楚地解释。多次阅读您的问题后,我仍然不知道它是关于什么的。@mkl我想在某些包含标记的文本上添加画布,例如hello。当我在doc中添加word时,我想让这个词用画布或画线strikethrough@mkl(请帮助)对于下划线,只需将
com.itextpdf.layout.property.property.UNDERLINE
属性与
com.itextpdf.layout.property.UNDERLINE
值一起使用即可。@mkl我知道这一点。我只是举了一个例子。我需要在某些单词上使用画布。请更清楚地解释。多次阅读您的问题后,我仍然不知道它是关于什么的。@mkl我想在某些包含标记的文本上添加画布,例如hello。当我在doc中添加word时,我想让这个词用画布或画线strikethrough@mkl(请帮助)对于下划线,只需将
com.itextpdf.layout.property.property.UNDERLINE
属性与
com.itextpdf.layout.property.UNDERLINE
值一起使用即可。@mkl我知道这一点。我只是举了一个例子。我需要在某些单词上使用画布。非常感谢。我爱你!你从哪里得到这些信息?也许有一本书?“你从哪里得到所有这些信息”-嗯,我确信它必须是一个渲染器(因为它可能是什么),但不可否认,我发现这个例子只是因为我知道在itext 5中可以使用通用标记:所以我找了itext 5使用通用标记的例子,找到了itext 5变体,从这里切换到itext 7示例。@forset420“我能用t完成吗
private class DottedLineCellRenderer extends CellRenderer {
    public DottedLineCellRenderer(Cell modelElement) {
        super(modelElement);
    }

    @Override
    public void draw(DrawContext drawContext) {
        super.draw(drawContext);
        drawContext.getCanvas().setLineDash(3f, 3f);
        drawContext.getCanvas().rectangle(this.getOccupiedArea().getBBox());
        drawContext.getCanvas().stroke();
    }
}