将文本添加到现有PDF / A文档时,只要文本没有加下划线,一切正常。如果是这样,我会得到一个例外:
com.itextpdf.text.exceptions.IllegalPdfSyntaxException: Path construction or drawing operators aren't allowed inside a text object.
at com.itextpdf.text.pdf.PdfContentByte.moveTo(PdfContentByte.java:919)
at com.itextpdf.text.pdf.PdfContentByte.moveTo(PdfContentByte.java:904)
at com.itextpdf.text.pdf.PdfDocument.writeLineToContent(PdfDocument.java:1615)
at com.itextpdf.text.pdf.ColumnText.go(ColumnText.java:1160)
at com.itextpdf.text.pdf.ColumnText.go(ColumnText.java:993)
at com.itextpdf.text.pdf.ColumnText.go(ColumnText.java:981)
at com.itextpdf.text.pdf.ColumnText.showTextAligned(ColumnText.java:1400)
at com.itextpdf.text.pdf.ColumnText.showTextAligned(ColumnText.java:1418)
at de.arbeitsagentur.kiwi.common.drucken.itext.PdfUtils.stampVerworfen(PdfUtils.java:97)
以下是代码:
PdfReader reader = new PdfReader(inputStream);
PdfStamper stamp = new PdfStamper(reader, outputStream);
PdfContentByte over = stamp.getOverContent(1);
over.beginText();
BaseFont bf = BaseFont.createFont(FONT, BaseFont.WINANSI, true);
Font font = new Font(bf, 14, Font.BOLD | Font.UNDERLINE);
Phrase phrase = new Phrase("Hello World!", font);
ColumnText.showTextAligned(over, Element.ALIGN_LEFT, phrase, 67, 727, 0);
如果省略Font.UNDERLINE,则没有问题。
我的iText版本是5.5.13
答案 0 :(得分:1)
页面上的内容是使用ISO 32000中描述的PDF语法定义的。如果您在iText中使用高级对象,则不必担心细节:iText负责处理它们。
iText还有一系列低级方法,允许您创建PDF语法。 ISO 32000中描述的每个操作员在iText中都有相应的低级方法。
例如:可以使用BT
方法添加beginText()
运算符,可以使用ET
方法添加endText()
运算符。这两个运算符BT
和ET
定义了一个文本对象。
ISO 32000告诉您文本对象中只允许文本状态运算符。通过下划线文字,您可以介绍图形状态运算符 m
(moveTo()
),l
(lineTo()
)和S
( stroke()
)。这是被禁止的,这也是你的错误告诉你的。
beginText()
,但您没有endText()
,因此您正在创建一个永不关闭的文本对象。这违反了ISO 32000。
此外,由于您使用的是ColumnText.showTextAligned()
,因此您无需创建文本对象。 showTextAligned()
方法适合您。通过添加额外的beginText()
,您正在嵌套BT
和ET
运算符,这也违反了ISO 32000,因此请首先删除行{{1}那条线永远不应该被添加到那里。
最后,强调字体的属性是错误的。这是iText 5中众多设计缺陷之一,最终导致了iText的完全重写,从而产生了iText 7。
将over.beginText();
用于普通文本会更好,然后使用ColumnText.showTextAligned()
,moveTo()
和lineTo()
来绘制线条。您知道stroke()
坐标(727 - 基线与您想要绘制的线之间的距离)起始Y
位置(67);您需要根据X
的长度计算结束X
位置(有不同的方法可以计算该长度)。
当然:如果你升级到iText 7(它具有与iText 5相同的许可证:AGPL或商业版),你会发现在绝对位置添加文本要容易得多。