简体   繁体   中英

itext7 - How to draw horizontal dashed line in PDF?

I am using the community version of itext7 (version 7.1.9 ). I would like to create a PDF document where I insert text paragraphs and a horizontal divider in between like so:

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. 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. 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)?

Minimal reproduction example (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): 有问题的输出

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.

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.

If you want your line to consist of longer segments you can play around with unitsOn , unitsOff and phase parameters of setLineDash method. 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 dashedLine = new LineSeparator(new CustomDashedLine(3f));

Result looks like this:

结果

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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