Home > Back-end >  Wrong rendering of thousands separator with custom font in itext
Wrong rendering of thousands separator with custom font in itext

Time:03-05

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($"{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

CodePudding user response:

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

CodePudding user response:

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($"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

Thanks anyone for your time.

  • Related