itext 中使用自定义字体的千位分隔符的错误渲染

发布于 2025-01-10 23:43:15 字数 3188 浏览 0 评论 0原文

自从我使用自定义字体升级到 iText 7.2(从 7.1.7)以来,我遇到了渲染问题。

千位分隔符未正确呈现。

使用 iText 7.1.7

使用 iText 7.2

tableArticles.AddCell(new Cell(1, 2)
                .Add(new Paragraph($"{bonCommande.Total:C}")
                    .SetFontSize(14)
                    .SetBold()
                    .SetTextAlignment(TextAlignment.RIGHT)
                    .SetFixedLeading(LeadingSize))
                .SetBorder(new SolidBorder(1))
                .SetVerticalAlignment(VerticalAlignment.MIDDLE)
                .SetPadding(5));

我尝试通过为 unicode char 阿拉伯千位分隔符 (U+066C) 绘制一些内容来更新字体,但没有成功。

我来自比利时,使用“fr-BE”。

感谢您的任何帮助。

编辑 : 这是一些带有字体和 pdf 示例的代码示例。 WeTransfer 链接到 PDF 和字体

 public class PdfCurrencyModel : PageModel
    {
        private readonly IPdfCurrencyService _pdfCurrencyService;

        public PdfCurrencyModel(IPdfCurrencyService pdfCurrencyService)
        {
            _pdfCurrencyService = pdfCurrencyService;
        }
        public IActionResult OnGetAsync()
        {
            //var stream =  _pdfCurrencyService.GetPDFMemoryStream();
            //return File(stream, MediaTypeNames.Application.Pdf, "Values.pdf");

            var bytesArray =  _pdfCurrencyService.GetPDFBytesArray();
            return new FileContentResult(bytesArray, MediaTypeNames.Application.Pdf);
        }
    }
public interface IPdfCurrencyService
    {
        public MemoryStream GetPDFMemoryStream();
        public byte[] GetPDFBytesArray();
    }

    public class PdfCurrencyService : IPdfCurrencyService
    {
        public MemoryStream GetPDFMemoryStream()
        {
            // Fonts
            var fontTexte = PdfFontFactory.CreateFont(FontConstants.BrownBold,
                PdfFontFactory.EmbeddingStrategy.FORCE_EMBEDDED);

            // Initialisation
            var ms = new MemoryStream();

            // Initialize PDF writer
            var writer = new iText.Kernel.Pdf.PdfWriter(ms);
            writer.SetCloseStream(false);

            // Initialize PDF document
            var pdfDoc = new iText.Kernel.Pdf.PdfDocument(writer);

            // Initialize document
            var document = new Document(pdfDoc, iText.Kernel.Geom.PageSize.A4)
                .SetFont(fontTexte).SetFontSize(10);

            // Values
            for (var i = 1000; i <= 2000; i += 100)
                document.Add(new Paragraph(i.ToString("C")));

            // Close document
            document.Close();

            //ms.Flush();
            ms.Position = 0;

            return ms;
        }

        public byte[] GetPDFBytesArray()
        {
            return GetPDFMemoryStream().ToArray();
        }
    }

编辑 2:我创建了一个有问题的简单网络应用程序 项目链接

I have a rendering issue since I upgraded to iText 7.2 (from 7.1.7) with a custom font.

The thousand separator is not rendered correctly.

With iText 7.1.7

With iText 7.2

tableArticles.AddCell(new Cell(1, 2)
                .Add(new Paragraph(
quot;{bonCommande.Total:C}")
                    .SetFontSize(14)
                    .SetBold()
                    .SetTextAlignment(TextAlignment.RIGHT)
                    .SetFixedLeading(LeadingSize))
                .SetBorder(new SolidBorder(1))
                .SetVerticalAlignment(VerticalAlignment.MIDDLE)
                .SetPadding(5));

I tried to update the font by drawing something for unicode char arabic thousands separator (U+066C) but without success.

I'm from Belgium and use "fr-BE".

Thanks for any help.

EDIT :
Here is some code example with the font and pdfs examples.
WeTransfer Link To PDFs and Font

 public class PdfCurrencyModel : PageModel
    {
        private readonly IPdfCurrencyService _pdfCurrencyService;

        public PdfCurrencyModel(IPdfCurrencyService pdfCurrencyService)
        {
            _pdfCurrencyService = pdfCurrencyService;
        }
        public IActionResult OnGetAsync()
        {
            //var stream =  _pdfCurrencyService.GetPDFMemoryStream();
            //return File(stream, MediaTypeNames.Application.Pdf, "Values.pdf");

            var bytesArray =  _pdfCurrencyService.GetPDFBytesArray();
            return new FileContentResult(bytesArray, MediaTypeNames.Application.Pdf);
        }
    }
public interface IPdfCurrencyService
    {
        public MemoryStream GetPDFMemoryStream();
        public byte[] GetPDFBytesArray();
    }

    public class PdfCurrencyService : IPdfCurrencyService
    {
        public MemoryStream GetPDFMemoryStream()
        {
            // Fonts
            var fontTexte = PdfFontFactory.CreateFont(FontConstants.BrownBold,
                PdfFontFactory.EmbeddingStrategy.FORCE_EMBEDDED);

            // Initialisation
            var ms = new MemoryStream();

            // Initialize PDF writer
            var writer = new iText.Kernel.Pdf.PdfWriter(ms);
            writer.SetCloseStream(false);

            // Initialize PDF document
            var pdfDoc = new iText.Kernel.Pdf.PdfDocument(writer);

            // Initialize document
            var document = new Document(pdfDoc, iText.Kernel.Geom.PageSize.A4)
                .SetFont(fontTexte).SetFontSize(10);

            // Values
            for (var i = 1000; i <= 2000; i += 100)
                document.Add(new Paragraph(i.ToString("C")));

            // Close document
            document.Close();

            //ms.Flush();
            ms.Position = 0;

            return ms;
        }

        public byte[] GetPDFBytesArray()
        {
            return GetPDFMemoryStream().ToArray();
        }
    }

EDIT 2 : I created a simple web app with the problem
Link to project

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

九八野马 2025-01-17 23:43:15

当使用“fr-BE”区域性时,此行:

1000.ToString("C")

计算结果为:

1.000,00 €

iText 似乎对“.”进行了一些处理。 (点)因为这两个文件都不正确。

7.2.1 似乎改变了字体的处理方式。 7.1.7 创建了一个简单的 WinAnsi 字体,而 7.2.1 创建了 Type0 字体。

7.1.7 PDF 文件中根本不写入点:

BT
/F1 10 Tf
36 787.93 Td
(1000,00 €)Tj
ET

7.2.1 写入<0000>对于 PDF 文件中的点 GID(而不是 <0073>)(我在字符串中添加空格以强调每个 GID):

BT
/F1 10 Tf
36 787.93 Td
<0093 0000 00a2 00a2 00a2 0080 00a2 00a2 0074 00e1>Tj
ET

When using the "fr-BE" culture this line:

1000.ToString("C")

evaluates to:

1.000,00 €

It seems that iText does some processing with the "." (dot) because neither files are correct.

Seems that 7.2.1 changed the way the fonts are handled. 7.1.7 created a simple WinAnsi font while 7.2.1 creates a Type0 font.

7.1.7 does not write at all the dot in the PDF file:

BT
/F1 10 Tf
36 787.93 Td
(1000,00 €)Tj
ET

7.2.1 writes <0000> for the dot GID (instead of <0073>) in the PDF file (spaces in string added by me to emphasize each GID):

BT
/F1 10 Tf
36 787.93 Td
<0093 0000 00a2 00a2 00a2 0080 00a2 00a2 0074 00e1>Tj
ET
请止步禁区 2025-01-17 23:43:15

我终于成功了。
在 7.2.x 版本中,iText 似乎使用 U+202F(窄无间断空格)作为千位分隔符,但以前的情况并非如此。

我的字体没有指定任何内容,因此它呈现为正方形。
我从 U+0020(即“空格”)复制/粘贴,不再有任何问题。

在 fr-BE 和 fr-FR 中,千位分隔符是空格而不是点。

var separator = new CultureInfo("fr-BE", false)
            .NumberFormat
            .CurrencyGroupSeparator;

Debug.WriteLine($"Currency Group Separator for fr-BE is {(int)separator[0]}");
Debug.WriteLine($"As HEX {((int)separator[0]).ToString("X")}");

// Currency Group Separator for fr-BE is 8239
//As HEX 202F

感谢大家抽出时间。

I finally managed to make it work.
It appears that iText use U+202F (NARROW NO-BREAK SPACE) as thousands separator in 7.2.x versions but it was not the case before.

My font didn't have something specified so it rendered a square.
I copy/paste from U+0020 which is "SPACE" and I don't have any problem anymore.

In fr-BE and fr-FR the thousands separator is a blank space and not an dot.

var separator = new CultureInfo("fr-BE", false)
            .NumberFormat
            .CurrencyGroupSeparator;

Debug.WriteLine(
quot;Currency Group Separator for fr-BE is {(int)separator[0]}");
Debug.WriteLine(
quot;As HEX {((int)separator[0]).ToString("X")}");

// Currency Group Separator for fr-BE is 8239
//As HEX 202F

Thanks anyone for your time.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文