itext7 - 如何在 PDF 中绘制水平虚线?
itext7 - How to draw horizontal dashed line in PDF?
我使用的是 itext7 的社区版本(版本 7.1.9
)。
我想创建一个 PDF 文档,我在其中插入文本段落和水平分隔符,如下所示:
some interesting text
-----------
more interesting text
-----------
still interesting text
-----------
you get the idea
-----------
为了实现这个文档结构,我使用了 Paragraph
s 和 LineSeparator
以及 DashedLine
class。但是,即使是最小的示例,各个破折号最终也是 垂直 ,如下所示:
some interesting text
|||||||||||||
more interesting text
|||||||||||||
整个分隔符仍然水平运行,但传递一个 width
参数(如 Javadoc 中所定义)似乎实际上为行提供了 高度 。我是不是做错了什么?
如何生成带有水平虚线的分隔符,其中虚线本身也是水平的(30.0 的宽度是一个通用示例)?
最小复制示例(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()
}
}
生成的输出文件(截图,如果需要我可以提供PDF):
width参数不是设置线段的宽度,而是设置水平线的宽度,正好由线段组成,所以不会出错
默认情况下,分段之间的距离在 DashedLine
中不可配置,但您可以创建自己的 class 并覆盖 draw
操作以创建您自己的外观。
如果你想让你的线由更长的线段组成,你可以使用 setLineDash
方法的 unitsOn
、unitsOff
和 phase
参数。这里只是一个参考实现和可视化结果:
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();
}
}
创建时只需使用这个新实现 LineSeparator
:
LineSeparator dashedLine = new LineSeparator(new CustomDashedLine(3f));
结果如下所示:
我使用的是 itext7 的社区版本(版本 7.1.9
)。
我想创建一个 PDF 文档,我在其中插入文本段落和水平分隔符,如下所示:
some interesting text
-----------
more interesting text
-----------
still interesting text
-----------
you get the idea
-----------
为了实现这个文档结构,我使用了 Paragraph
s 和 LineSeparator
以及 DashedLine
class。但是,即使是最小的示例,各个破折号最终也是 垂直 ,如下所示:
some interesting text
|||||||||||||
more interesting text
|||||||||||||
整个分隔符仍然水平运行,但传递一个 width
参数(如 Javadoc 中所定义)似乎实际上为行提供了 高度 。我是不是做错了什么?
如何生成带有水平虚线的分隔符,其中虚线本身也是水平的(30.0 的宽度是一个通用示例)?
最小复制示例(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()
}
}
生成的输出文件(截图,如果需要我可以提供PDF):
width参数不是设置线段的宽度,而是设置水平线的宽度,正好由线段组成,所以不会出错
默认情况下,分段之间的距离在 DashedLine
中不可配置,但您可以创建自己的 class 并覆盖 draw
操作以创建您自己的外观。
如果你想让你的线由更长的线段组成,你可以使用 setLineDash
方法的 unitsOn
、unitsOff
和 phase
参数。这里只是一个参考实现和可视化结果:
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();
}
}
创建时只需使用这个新实现 LineSeparator
:
LineSeparator dashedLine = new LineSeparator(new CustomDashedLine(3f));
结果如下所示: