将文本添加到现有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
1 回答
页面上的内容使用ISO 32000中描述的PDF语法定义 . 如果您在iText中使用高级对象,则无需担心细节:iText负责处理它们 .
iText还有一系列低级方法,允许您创建PDF语法 . ISO 32000中描述的每个操作员在iText中都有相应的低级方法 .
例如:可以使用
beginText()
方法添加BT
运算符,可以使用endText()
方法添加ET
运算符 . 这两个运算符BT
和ET
定义了一个文本对象 .ISO 32000告诉您文本对象中只允许使用文本状态运算符 . 通过下划线文本,您将引入图形状态运算符
m
(moveTo()
),_ 279447(lineTo()
)和S
(stroke()
) . 这是被禁止的,这也是你的错误告诉你的 .然而,这不是唯一的问题 . 您的代码段中有一个
beginText()
,但是您没有endText()
,因此您正在创建一个永不关闭的文本对象 . 这违反了ISO 32000 .此外,由于您使用的是
ColumnText.showTextAligned()
,因此无需创建文本对象 .showTextAligned()
方法为您做到了这一点 . 通过添加额外的beginText()
,您正在嵌套BT
和ET
运算符,这也违反了ISO 32000,所以请首先删除行over.beginText();
该行应该从未添加过 .最后,强调字体的属性是错误的 . 这是iText 5中众多设计缺陷之一,最终导致iText的完全重写,从而产生了iText 7 .
使用
ColumnText.showTextAligned()
作为普通文本要好得多,然后使用moveTo()
,lineTo()
和stroke()
绘制线条 . 你知道Y
坐标(727 - 基线和你想绘制的线之间的距离)起始X
位置(67);您需要根据String
的长度计算结束X
位置(有不同的方法可以计算该长度) .当然:如果您升级到iText 7(具有与iText 5相同的许可证:AGPL或商业版),您会发现在绝对位置添加文本要容易得多 .