使用Java iText生成PDF时印地语文本拼写显示异常问题
印地语文本在iText生成PDF中显示异常(复制文本正确)
问题描述
使用Java iText从JSON生成报表时,印地语文本“वर्धा”在PDF中显示拼写错误,但复制该文本得到的是正确内容。当前使用字体为NotoSansDevanagari-Regular.ttf,核心代码如下:
private void addTextToPdf(PdfDocument pdfDocument, String text, float x, float y, int pageNumber, int fontSize, PdfFont font) throws IOException { PdfPage page = pdfDocument.getPage(pageNumber); PdfCanvas canvas = new PdfCanvas(page); // Convert text to lowercase for case-insensitive comparison String lowerText = text.toLowerCase(); // Determine the color based on the text value DeviceRgb rectangleColor = null; String marathiText = text; // Default to the original text // Draw the rectangle with the determined color if (rectangleColor != null) { drawRectangle(pdfDocument, x-2f, y - 2.8f, 85.5f, 12f, rectangleColor); } // Add the Marathi text to the PDF canvas.beginText() .setFontAndSize(font, fontSize) .setColor(ColorConstants.BLACK, true) .moveText(x, y) .showText(marathiText) .endText(); }
解决方案
问题出在showText()方法上,它仅支持简单文本绘制,无法处理印地语这类需要复杂字形组合(如连字、重音合并)的文字。iText中需要使用高层API或适配复杂脚本的底层方法来解决:
方案1:使用高层API Canvas 替代 PdfCanvas
private void addTextToPdf(PdfDocument pdfDocument, String text, float x, float y, int pageNumber, int fontSize, PdfFont font) throws IOException { PdfPage page = pdfDocument.getPage(pageNumber); Canvas canvas = new Canvas(page, pdfDocument.getDefaultPageSize()); // 构建文本段落 Paragraph paragraph = new Paragraph(text) .setFont(font) .setFontSize(fontSize) .setFontColor(ColorConstants.BLACK); // 定位并绘制文本 canvas.showTextAligned(paragraph, x, y, pageNumber, TextAlignment.LEFT, VerticalAlignment.BOTTOM, 0); // 绘制矩形(如果需要) if (rectangleColor != null) { drawRectangle(pdfDocument, x-2f, y - 2.8f, 85.5f, 12f, rectangleColor); } }
方案2:使用底层API的showTextAligned()并配置字体
如果坚持使用PdfCanvas,需确保字体启用复杂脚本支持,并改用showTextAligned():
// 创建字体时启用复杂脚本编码 PdfFont font = PdfFontFactory.createFont("path/to/NotoSansDevanagari-Regular.ttf", PdfEncodings.IDENTITY_H, true); // 修改文本绘制逻辑 canvas.beginText() .setFontAndSize(font, fontSize) .setColor(ColorConstants.BLACK, true) .showTextAligned(TextAlignment.LEFT, marathiText, x, y, 0) .endText();
关键说明
- 印地语(天城文)属于复杂书写系统,需要字体支持OpenType布局(OTL)规则,
showText()无法处理这类规则,只会逐个绘制字符导致字形错误。 - 高层
Canvas或showTextAligned()会触发iText的复杂文本渲染逻辑,正确处理连字、字形合并等规则。 - 确保使用的NotoSansDevanagari字体文件完整无损坏。
内容的提问来源于stack exchange,提问作者Ranu drolia
相关产品推荐
相关产品推荐

