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

iText 9.2.0生成PDF时波斯语(法尔西语)文本渲染异常:字符拆分/破碎问题求助

iText 9.2.0生成PDF时波斯语(法尔西语)文本渲染异常:字符拆分/破碎问题求助

我现在用C#结合iText 9.2.0生成PDF文档,里面包含波斯语(法尔西语)文本,但这些字符显示完全不正常——要么是单个字符分开显示,要么是连写结构破碎,完全不符合波斯语的书写规范。

以下是我当前的实现代码:

public async Task<byte[]> GenerateOrderPdf(Guid orderId, CancellationToken cancellationToken)
{
    var order = await _orderRepository.GetOrderById(orderId, cancellationToken);
    var orderServicesList = await _orderServicesRepository.GetOrderServices(orderId, cancellationToken);
    var serviceIds = orderServicesList.Select(x => x.ServiceId);
    var services = await _serviceRepository.GetServices(serviceIds, cancellationToken);

    using var stream = new MemoryStream();
    var writer = new PdfWriter(stream);
    var pdf = new PdfDocument(writer);
    var document = new Document(pdf);

    var vazirFontPath = Path.Combine(AppContext.BaseDirectory, "Resources", "Fonts", "Vazirmatn-Regular.ttf");
    var vazirFont = PdfFontFactory.CreateFont(vazirFontPath, PdfEncodings.IDENTITY_H);

    document.Add(new Paragraph($"جزئیات سفارش - کد #{order.OrderCode}")
        .SetFontSize(20)
        .SetTextAlignment(TextAlignment.RIGHT)
        .SetBaseDirection(iText.Layout.Properties.BaseDirection.RIGHT_TO_LEFT)
        .SetFont(vazirFont));

    document.Add(new Paragraph("وضعیت : " + order.Status)
        .SetTextAlignment(TextAlignment.RIGHT)
        .SetBaseDirection(iText.Layout.Properties.BaseDirection.RIGHT_TO_LEFT)
        .SetFont(vazirFont));

    document.Add(new Paragraph("تاریخ ایجاد : " + order.CreateDate.ToString("yyyy-MM-dd"))
        .SetTextAlignment(TextAlignment.RIGHT)
        .SetBaseDirection(iText.Layout.Properties.BaseDirection.RIGHT_TO_LEFT)
        .SetFont(vazirFont));

    document.Add(new Paragraph("تاریخ پرداخت : " + order.ProcessedAt?.ToString("yyyy-MM-dd"))
        .SetTextAlignment(TextAlignment.RIGHT)
        .SetBaseDirection(iText.Layout.Properties.BaseDirection.RIGHT_TO_LEFT)
        .SetFont(vazirFont));

    document.Add(new Paragraph("آخرین تغییر وضعیت : " + order.LastStateChange?.ToString("yyyy-MM-dd"))
        .SetTextAlignment(TextAlignment.RIGHT)
        .SetBaseDirection(iText.Layout.Properties.BaseDirection.RIGHT_TO_LEFT)
        .SetFont(vazirFont));

    document.Add(new Paragraph(" ")
        .SetFontSize(15));

    var table = new Table(new float[] { 1, 1, 1, 1 });
    table.SetWidth(UnitValue.CreatePercentValue(100))
        .SetFont(vazirFont)
        .SetTextAlignment(TextAlignment.CENTER);

    var headerBgColor = new iText.Kernel.Colors.DeviceRgb(238, 238, 238);
    table.AddHeaderCell(new Cell()
        .SetBackgroundColor(headerBgColor)
        .Add(new Paragraph("خدمت")
            .SetBaseDirection(iText.Layout.Properties.BaseDirection.RIGHT_TO_LEFT)
            .SetFont(vazirFont)));
    table.AddHeaderCell(new Cell()
        .SetBackgroundColor(headerBgColor)
        .Add(new Paragraph("سیستم خدمت")
            .SetBaseDirection(iText.Layout.Properties.BaseDirection.RIGHT_TO_LEFT)
            .SetFont(vazirFont)));
    table.AddHeaderCell(new Cell()
        .SetBackgroundColor(headerBgColor)
        .Add(new Paragraph("وضعیت")
            .SetBaseDirection(iText.Layout.Properties.BaseDirection.RIGHT_TO_LEFT)
            .SetFont(vazirFont)));
    table.AddHeaderCell(new Cell()
        .SetBackgroundColor(headerBgColor)
        .Add(new Paragraph("جزئیات")
            .SetBaseDirection(iText.Layout.Properties.BaseDirection.RIGHT_TO_LEFT)
            .SetFont(vazirFont)));

    foreach (var os in orderServicesList)
    {
        var serviceName = services.FirstOrDefault(x => x.Id == os.ServiceId)?.Name?.GetValue() ?? "";
        table.AddCell(new Cell().Add(new Paragraph(serviceName)
            .SetBaseDirection(iText.Layout.Properties.BaseDirection.RIGHT_TO_LEFT)
            .SetFont(vazirFont)));
        table.AddCell(new Cell().Add(new Paragraph(os.ServiceSystem.ToString())
            .SetBaseDirection(iText.Layout.Properties.BaseDirection.RIGHT_TO_LEFT)
            .SetFont(vazirFont)));

        var statusCell = new Cell().Add(new Paragraph(os.Status.ToString())
            .SetBaseDirection(iText.Layout.Properties.BaseDirection.RIGHT_TO_LEFT)
            .SetFont(vazirFont));
        if (os.Status.ToString() == "ناموفق")
        {
            var redBgColor = new iText.Kernel.Colors.DeviceRgb(255, 204, 204);
            statusCell.SetBackgroundColor(redBgColor);
        }
        table.AddCell(statusCell);

        table.AddCell(new Cell().Add(new Paragraph(os.DeleteStatus.ToString())
            .SetBaseDirection(iText.Layout.Properties.BaseDirection.RIGHT_TO_LEFT)
            .SetFont(vazirFont)));
    }

    document.Add(table);
    document.Close();
    return stream.ToArray();
}

附:PDF中显示异常的部分效果:[波斯语文本字符拆分、连写结构破碎的截图]

我已经尝试了几种方法,但都没能解决问题:

  • 嵌入了多款波斯语字体(Vazirmatn、IRANSans等)
  • 创建字体时指定了PdfEncodings.IDENTITY_H编码
  • 给所有文本设置了右到左的排版方向和右对齐样式

后来我了解到iText有个叫PdfCalligraph的功能,专门处理复杂脚本语言的文本渲染,但我完全不知道怎么在C#代码里用它来修复这个字符破碎的问题。有没有大佬能给我指点一下具体的实现步骤?

内容来源于stack exchange

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.07 07:45:30