You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 15:18:11