Home > OS >  Generate PDF file with Arabic content (Spring boot with jasper or thymleaf)
Generate PDF file with Arabic content (Spring boot with jasper or thymleaf)

Time:11-21

A business feature that came out is to export invoice PDF files with arabic text. Stack we're using is: Spring boot 2.7.5

We're generating our PDFs using jasperreport:

    <dependency>
        <groupId>net.sf.jasperreports</groupId>
        <artifactId>jasperreports</artifactId>
        <version>${jasperreports.version}</version>
    </dependency>

The code is pretty simple:

Map<String, Object> jasperParameters = new HashMap<>();

    // Handling language
    ResourceBundle bundle =
            ResourceBundle.getBundle(
                    "localization/i18n",
                    new Locale("ar", "MA"));
    jasperParameters.put(JRParameter.REPORT_RESOURCE_BUNDLE, bundle);

    jasperParameters.put("currency", "MAD");
    jasperParameters.put("orderNumber", orderEntity.getReference());
    jasperParameters.put("orderDate", orderEntity.getCreatedDate().toString());
    jasperParameters.put("clientName", orderEntity.getClient().getName());
    jasperParameters.put("clientPhoneNumber", orderEntity.getClient().getPhoneNumber());

    InputStream template = getClass().getResourceAsStream("/templates/order.jrxml");

    List<OrderItemEntity> orderItemEntities = orderItemDaoService.findAll(OrderItemSpecification.withOrderId(
            orderEntity.getId()), Pageable.unpaged()).getContent();

    List<OrderInvoiceItem> orderItems = orderItemEntities.stream().map(orderItemMapper::entityToInvoiceItem)
            .toList();

    try {
        JasperReport jasperReport = JasperCompileManager.compileReport(template);
        JRBeanCollectionDataSource dataSource = new JRBeanCollectionDataSource(orderItems);
        jasperParameters.put("datasource", dataSource);
        JasperPrint jasperPrint =
                JasperFillManager.fillReport(jasperReport, jasperParameters, new JREmptyDataSource());
        byte[] pdf = JasperExportManager.exportReportToPdf(jasperPrint);
        String base64PDF = Base64.getEncoder().encodeToString(pdf);
        log.info("Your pdf file is: {}", base64PDF);
    } catch (JRException e) {
        log.warn(
                "Couldn't generate invoice based on Jasper report. More information about the error: {}",
                e.getMessage());
        throw new RuntimeException(
                "An error occurred when generating invoice with Jasper Report.", e);
    }

Unfortunately, our labels defined in the bundle are displayed as question marks. Looked for existing answers on the web, all were referring to fonts that should be loaded or installed on the server but nothing seems to work since I installed them on my laptop and nothing changed.

We tried to move to Thymeleaf using flying-saucer but this time arabic labels weren't displayed on the final PDF and during processing of the template the String value returned does hold the caracters correctly.

Any help will be appreciated.

CodePudding user response:

The default font family used from jaspersoft is SansSerif. This font family does not support Arabic characters, therefore the questionmarks as the characters can't be rendered.

You can use this noto font family which is open source from google. Pick the one .ttf file that you want and load it in jasper as you can see under this guide.

It should then display the arabic characters.

CodePudding user response:

As @Panagiotis said, you need to download appropriate font, you can download Arial font also. Place those font files (ttf) in the jasper's font's folder. (depends on os) /app/jasper/Templates/TemplateFonts/

Last step is, you need to select text field/static field from the Jasper's ui, something like Properties > PDF provide.

  • Related