简体   繁体   English

itext7 - 如何在 PDF 中绘制水平虚线?

[英]itext7 - How to draw horizontal dashed line in PDF?

I am using the community version of itext7 (version 7.1.9 ).我正在使用 itext7 的社区版本(版本7.1.9 )。 I would like to create a PDF document where I insert text paragraphs and a horizontal divider in between like so:我想创建一个 PDF 文档,在其中插入文本段落和一个水平分隔线,如下所示:

some interesting text
-----------
more interesting text
-----------
still interesting text
-----------
you get the idea
-----------

To realise this document structure I am using Paragraph s and a LineSeparator in conjunction with the DashedLine class.为了实现这个文档结构,我将ParagraphLineSeparatorDashedLine类结合使用。 However, even with a minimal example the individual dashes end up vertical , like so:然而,即使有一个最小的例子,单个破折号最终都是垂直的,如下所示:

some interesting text
|||||||||||||
more interesting text
|||||||||||||

The overall separator still runs horizontally, but passing a width parameter (as defined in Javadoc) seems to actually give height to the lines.整体分隔符仍然水平运行,但传递width参数(如 Javadoc 中定义的)似乎实际上为行提供了高度 Am I doing something wrong here?我在这里做错了吗?

What can I do to generate a separator with horizontal dashed lines where the dashes themselves are also horizontal (width of 30.0 is a generic example)?我该怎么做才能生成带有水平虚线的分隔符,其中虚线本身也是水平的(30.0 的宽度是一个通用示例)?

Minimal reproduction example (Kotlin):最小复制示例(Kotlin):

import com.itextpdf.io.font.constants.StandardFonts
import com.itextpdf.kernel.font.PdfFontFactory
import com.itextpdf.kernel.pdf.PdfDocument
import com.itextpdf.kernel.pdf.PdfWriter
import com.itextpdf.kernel.pdf.canvas.draw.DashedLine
import com.itextpdf.layout.Document
import com.itextpdf.layout.element.LineSeparator
import com.itextpdf.layout.element.Paragraph
import java.io.File

object DashedLineBugReproduction {
    private fun render() {
        val docWriter = PdfWriter(File("/tmp/foobar_dashes.pdf"))
        val document = PdfDocument(docWriter)

        document.writeContents()

        document.close()
    }

    fun PdfDocument.writeContents() {
        val doc = Document(this)

        val font = PdfFontFactory.createFont(StandardFonts.TIMES_ROMAN)

        val dashedLine = LineSeparator(DashedLine(30f))
        val paragraph = Paragraph("Lorem ipsum dolor sit amet.")
            .setFont(font)
            .setFontSize(20f)

        doc.add(dashedLine)

        for (i in 0 until 8) {
            doc.add(paragraph)
            doc.add(dashedLine)
        }

        doc.close()
    }

    @JvmStatic
    fun main(args: Array<String>) {
        render()
    }
}

Resulting output file (screenshot, I can provide the PDF if required):结果输出文件(截图,如果需要,我可以提供PDF): 有问题的输出

The width parameter does not set the width of a line segment but instead sets the width of the horizontal line which happens to consist of segments so there is no mistake there. width 参数不设置线段的宽度,而是设置恰好由线段组成的水平线的宽度,因此没有错误。

By default the distance between segments is not configurable in DashedLine but you can create your own class and override draw operation to create your own appearance.默认情况下,线段之间的距离在DashedLine不可配置,但您可以创建自己的类并覆盖draw操作以创建自己的外观。

If you want your line to consist of longer segments you can play around with unitsOn , unitsOff and phase parameters of setLineDash method.如果您希望您的线包含更长的段,您可以使用setLineDash方法的unitsOnunitsOffphase参数。 Here is just a reference implementation and visual result:这里只是一个参考实现和视觉效果:

private static class CustomDashedLine extends DashedLine {
    public CustomDashedLine(float lineWidth) {
        super(lineWidth);
    }

    @Override
    public void draw(PdfCanvas canvas, Rectangle drawArea) {
        canvas.saveState()
                .setLineWidth(getLineWidth())
                .setStrokeColor(getColor())
                .setLineDash(20, 4, 2)
                .moveTo(drawArea.getX(), drawArea.getY() + getLineWidth() / 2)
                .lineTo(drawArea.getX() + drawArea.getWidth(), drawArea.getY() + getLineWidth() / 2)
                .stroke()
                .restoreState();
    }
}

Just use this new implementation when creating LineSeparator :创建LineSeparator时只需使用这个新实现:

LineSeparator dashedLine = new LineSeparator(new CustomDashedLine(3f));

Result looks like this:结果如下所示:

结果

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM