Supporto Unicode

In JasperReports, lavorare con i testi necessita di alcuni strumenti dedicati per elaborare sia le rappresentazioni dei caratteri che le proprietà di formattazione del testo. Qualsiasi testo può essere considerato come una sequenza di caratteri con una particolare struttura di rappresentazione. L'aspetto del testo consiste sia nel layout (e paragrafo) che nelle impostazioni dei caratteri. Tuttavia, sebbene nella maggior parte dei casi il layout del testo rimanga invariante, le impostazioni dei caratteri potrebbero cambiare durante l'esecuzione del report in diverse impostazioni internazionali.

Sappiamo che lingue diverse richiedono set di caratteri diversi rispetto alla rappresentazione di caratteri specifici. Pertanto, lavorare con i testi significa lavorare con i caratteri. Tuttavia, una discussione dettagliata su come utilizzare i caratteri in JasperReports è disponibile nel capitolo Caratteri report .

Una delle caratteristiche principali che riguardano il contenuto del testo in un dato rapporto è la possibilità di internazionalizzarlo. Significa che possiamo eseguire il rapporto in diversi ambienti localizzati, utilizzando lingue diverse e altre impostazioni di localizzazione senza alcuna modifica hardcoded. La codifica dei caratteri è una caratteristica importante quando un report deve essere internazionalizzato.

Codifica dei caratteri

Un carattere è la più piccola unità di scrittura che trasmette un'informazione significativa. È un concetto astratto, un personaggio non ha un aspetto visivo. "A latina maiuscola" è un carattere diverso da "a latina minuscola" e da "A cirillico maiuscolo" e "alfa greco maiuscolo".

Una rappresentazione visiva di un personaggio è nota come a glyph. Un certo insieme di glifi è chiamato afont. "A latina maiuscola", "A cirillico maiuscolo" e "alfa greco maiuscolo" possono avere glifi identici, ma sono caratteri diversi. Allo stesso tempo, i glifi per "A latina maiuscola" possono avere un aspetto molto diverso in Times New Roman, Gill Sans e cancelleria Poetica in corsivo, ma rappresentano comunque lo stesso carattere.

L'insieme di caratteri disponibili è chiamato repertorio di personaggi . La posizione (indice) di un dato carattere all'interno di un repertorio è nota come posizione del codice o punto di codice. Il metodo per rappresentare numericamente un punto di codice all'interno di un dato repertorio è chiamatocharacter encoding.

Le codifiche sono normalmente espresse in termini di ottetti. Un ottetto è un gruppo di otto cifre binarie, ovvero otto unità e zeri. Un ottetto può esprimere un intervallo numerico compreso tra 0 e 255 o tra 0x00 e 0xFF, per utilizzare la notazione esadecimale.

Unicode

Un Unicode è un repertorio di caratteri che contiene la maggior parte dei caratteri utilizzati nelle lingue del mondo. Può ospitare milioni di caratteri e ne contiene già centinaia di migliaia. Unicode è diviso in "piani" di 64.000 caratteri. L'unico utilizzato nella maggior parte delle circostanze è il primo aereo, noto come piano multilingue di base o BMP.

UTF-8 è la codifica consigliata. Utilizza un numero variabile di ottetti per rappresentare caratteri diversi.

In un file JRXML, l'attributo di codifica è specificato nell'intestazione. Viene utilizzato al momento della compilazione del report per decodificare il contenuto XML. Ad esempio, se il rapporto contiene solo parole francesi e caratteri come ç, é, â, la codifica ISO-8859-1 (anche nota come Latin-1) è sufficiente -

<?xml version = "1.0" encoding = "ISO-8859-1"?>

Come visto sopra, idealmente possiamo scegliere la codifica adatta al set di caratteri minimo, che può rappresentare correttamente tutti i caratteri nel documento. Ma nel caso di documenti multilingua (cioè documenti contenenti parole scritte in più lingue), si dovrebbe scegliere la codifica adatta al set di caratteri minimo, in grado di rappresentare correttamente tutti i caratteri del documento, anche se appartengono a lingue diverse. Una delle codifiche dei caratteri in grado di gestire documenti multilingue è ilUTF-8, utilizzato come valore di codifica predefinito da JasperReports.

I testi vengono solitamente conservati in file di bundle di risorse piuttosto che all'interno del documento durante l'internazionalizzazione. Quindi, ci sono casi in cui lo stesso JRXML sembra completamente compatibile con ASCII, ma i rapporti generati in fase di esecuzione contengono testi illeggibili con ASCII. Di conseguenza, per un certo tipo di formati di esportazione di documenti (come CSV, HTML, XHTML, XML e testo) è necessario conoscere anche la codifica per il documento generato. Lingue diverse sono supportate da codifiche di caratteri diverse. Quindi, ogni volta, dobbiamo eseguire un rapporto in un ambiente localizzato. Inoltre, dobbiamo sapere qual è la codifica dei caratteri più appropriata per il linguaggio del documento generato. In questo caso, la proprietà di codifica definita nel file JRXML stesso potrebbe non essere più utile.

Per risolvere questo tipo di problemi, possiamo utilizzare una proprietà di esportazione del cliente nota come net.sf.jasperreports.export.character.encoding . Questa proprietà personalizzata di esportazione è di default UTF-8 ed è presente in JasperReports.

Questo valore predefinito è impostato nel file default.jasperreports.properties . Per opzioni più specifiche al momento dell'esportazione, è disponibile anche il parametro di esportazione CHARACTER_ENCODING.

Esempio

Per dimostrare l'utilizzo del supporto Unicode in Jasperreports, scriviamo un nuovo modello di report (jasper_report_template.jrxml). Save it to C:\tools\jasperreports-5.0.1\testdirectory. Qui, visualizzeremo un testo in diverse lingue utilizzando i caratteri Unicode (\ uXXXX). Qualsiasi carattere codificato con UTF-8 può essere rappresentato utilizzando solo il suo codice esadecimale a 4 cifre. Ad esempio, la lettera greca Γ può essere scritta come \ u0393. Quando viene rilevata una tale notazione, il motore richiede la rappresentazione del carattere appropriata nel set di caratteri e verrà stampato solo quel carattere particolare. I contenuti di JRXML sono i seguenti:

<?xml version = "1.0" encoding = "UTF-8"?>

<jasperReport xmlns = "http://jasperreports.sourceforge.net/jasperreports"
   xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation = "http://jasperreports.sourceforge.net/jasperreports
   http://jasperreports.sourceforge.net/xsd/jasperreport.xsd"
   name = "jasper_report_template" language = "groovy" pageWidth = "595"
   pageHeight = "842" columnWidth = "555" leftMargin = "20" rightMargin = "20"
   topMargin = "20" bottomMargin = "20">

   <parameter name = "GreekText" class = "java.lang.String" isForPrompting = "false">
      <defaultValueExpression><![CDATA["\u0394\u03B5\u03BD "+
         "\u03BA\u03B1\u03C4\u03B1\u03BB\u03B1\u03B2\u03B1\u03AF"+
         "\u03BD\u03C9 \u0395\u03BB\u03BB\u03B7\u03BD\u03B9\u03BA\u03AC"]]>
      </defaultValueExpression>
   </parameter>
   
   <parameter name = "CyrillicText" class = "java.lang.String" isForPrompting = "false">
      <defaultValueExpression><![CDATA["\u042F \u043D\u0435 "+
         "\u043C\u043E\u0433\u0443 \u043F\u043E\u043D\u044F\u0442\u044C "+
         "\u0433\u0440\u0435\u0447\u0435\u0441\u043A\u0438\u0439"]]>
      </defaultValueExpression>
   </parameter>

   <parameter name = "ArabicText" class = "java.lang.String" isForPrompting = "false">
      <defaultValueExpression><![CDATA["\u0627\u0646\u0646\u0649 \u0644\u0627 "+
         "\u0627\u0641\u0647\u0645 \u0627\u0644\u0644\u063A\u0629 "+
         "\u0627\u0644\u0639\u0631\u0628\u064A\u0629"]]>
      </defaultValueExpression>
   </parameter>
   
   <parameter name = "HebrewText" class = "java.lang.String" isForPrompting = "false">
      <defaultValueExpression><![CDATA["\u05D0\u05E0\u05D9 \u05DC\u05D0 "+
         "\u05DE\u05D1\u05D9\u05DF \u05E2\u05D1\u05E8\u05D9\u05EA"]]>
      </defaultValueExpression>
   </parameter>
   
   <title>
      <band height = "782">
         
         <textField>
            <reportElement x = "0" y = "50" width = "200" height = "60"/>
            
            <textElement>
               <font fontName = "DejaVu Sans" size = "14"/>
            </textElement>
            
            <textFieldExpression class = "java.lang.String">
               <![CDATA[$P{GreekText} + "\n" + $P{CyrillicText}]]>
            </textFieldExpression>
         </textField>
         
         <staticText>
            <reportElement x = "210" y = "50" width = "340" height = "60"/>
            <textElement/>
            
            <text>
               <![CDATA["GreekText and CyrillicText"]]>
            </text>
         </staticText>
         
         <textField>
            <reportElement x = "0" y = "120" width = "200" height = "60"/>
            
            <textElement>
               <font fontName = "DejaVu Sans" size = "14" isBold = "true"/>
            </textElement>
            
            <textFieldExpression class = "java.lang.String">
               <![CDATA[$P{GreekText} + "\n" + $P{CyrillicText}]]>
            </textFieldExpression>
				
         </textField>
         
         <staticText>
            <reportElement x = "210" y = "120" width = "340" height = "60"/>
            <textElement/>
            <text><![CDATA["GreekText and CyrillicText"]]></text>
         </staticText>
         
         <textField>
            <reportElement x = "0" y = "190" width = "200" height = "60"/>
            
            <textElement>
               <font fontName = "DejaVu Sans" size = "14" isItalic = "true" 
                  isUnderline = "true"/>
            </textElement>
            
            <textFieldExpression class = "java.lang.String">
               <![CDATA[$P{GreekText} + "\n" + $P{CyrillicText}]]>
            </textFieldExpression>
				
         </textField>
         
         <staticText>
            <reportElement x = "210" y = "190" width = "340" height = "60"/>
            <textElement/>
            <text><![CDATA["GreekText and CyrillicText"]]></text>
         </staticText>
         
         <textField>
            <reportElement x = "0" y = "260" width = "200" height = "60"/>
            
            <textElement>
               <font fontName = "DejaVu Sans" size = "14" isBold = "true" 
                  isItalic = "true" isUnderline = "true"/>
            </textElement>
            
            <textFieldExpression class = "java.lang.String">
               <![CDATA[$P{GreekText} + "\n" + $P{CyrillicText}]]>
            </textFieldExpression>
				
         </textField>
         
         <staticText>
            <reportElement x = "210" y = "260" width = "340" height = "60"/>
            <textElement/>
            <text><![CDATA["GreekText and CyrillicText"]]></text>
         </staticText>

         <textField>
            <reportElement x = "0" y = "330" width = "200" height = "60"/>
            
            <textElement textAlignment = "Right">
               <font fontName="DejaVu Sans" size = "22"/>
            </textElement>
            
            <textFieldExpression class = "java.lang.String">
               <![CDATA[$P{ArabicText}]]>
            </textFieldExpression>
				
         </textField>
         
         <textField>
            <reportElement x = "210" y = "330" width = "340" height = "60"/>
            
            <textElement textAlignment = "Right">
               <font fontName = "DejaVu Sans" size = "22"/>
            </textElement>
            
            <textFieldExpression class = "java.lang.String">
               <![CDATA[$P{HebrewText}]]>
            </textFieldExpression>
				
         </textField>
      
      </band>
   </title>
	
</jasperReport>

Nel file sopra, possiamo vedere la presenza della codifica UTF-8. Anche le parti di testo Unicode localizzate vengono memorizzate nei parametri del documento.

Il codice java per compilare e generare il report è il seguente. Salviamo questo fileJasperUnicodeReportFill.java nella directory C: \ tools \ jasperreports-5.0.1 \ test \ src \ com \ tutorialspoint.

package com.tutorialspoint;

import net.sf.jasperreports.engine.JREmptyDataSource;
import net.sf.jasperreports.engine.JRException;
import net.sf.jasperreports.engine.JasperFillManager;

public class JasperUnicodeReportFill {
   public static void main(String[] args) {
      String sourceFileName ="C://tools/jasperreports-5.0.1/test/" + 
         "jasper_report_template.jasper";

      try {
         JasperFillManager.fillReportToFile(sourceFileName, null, 
            new JREmptyDataSource());
      } catch (JRException e) {
         // TODO Auto-generated catch block
         e.printStackTrace();
      }

   }
}

Qui usiamo un'istanza di JREmptyDataSource durante la compilazione dei report per simulare un'origine dati con un record al suo interno, ma con tutti i campi in questo singolo record nulli .

Generazione di report

Compileremo ed eseguiremo il file sopra utilizzando il nostro normale processo di compilazione ANT. I contenuti del file build.xml (salvato nella directory C: \ tools \ jasperreports-5.0.1 \ test) sono i seguenti.

Il file di importazione - baseBuild.xml viene prelevato dal capitolo Configurazione dell'ambiente e dovrebbe essere posizionato nella stessa directory di build.xml.

<?xml version = "1.0" encoding = "UTF-8"?>
<project name = "JasperReportTest" default = "viewFillReport" basedir = ".">
   <import file = "baseBuild.xml" />
   
   <target name = "viewFillReport" depends = "compile,compilereportdesing,run"
      description = "Launches the report viewer to preview the report 
      stored in the .JRprint file.">
      
      <java classname = "net.sf.jasperreports.view.JasperViewer" fork = "true">
         <arg value = "-F${file.name}.JRprint" />
         <classpath refid = "classpath" />
      </java>
		
   </target>
   
   <target name = "compilereportdesing" description = "Compiles the JXML file and
      produces the .jasper file.">
      
      <taskdef name = "jrc" classname = "net.sf.jasperreports.ant.JRAntCompileTask">
         <classpath refid = "classpath" />
      </taskdef>
      
      <jrc destdir = ".">
         <src>
            <fileset dir = ".">
               <include name = "*.jrxml" />
            </fileset>
         </src>
         <classpath refid = "classpath" />
      </jrc>

   </target>
	
</project>

Quindi, apriamo la finestra della riga di comando e andiamo alla directory in cui si trova build.xml. Infine, esegui il comandoant -Dmain-class=com.tutorialspoint.JasperUnicodeReportFill (viewFullReport è la destinazione predefinita) come segue:

C:\tools\jasperreports-5.0.1\test>ant  -Dmain-class=com.tutorialspoint.JasperUnicodeReportFill
Buildfile: C:\tools\jasperreports-5.0.1\test\build.xml

clean-sample:
   [delete] Deleting directory C:\tools\jasperreports-5.0.1\test\classes
   [delete] Deleting: C:\tools\jasperreports-5.0.1\test\jasper_report_template.jasper
   [delete] Deleting: C:\tools\jasperreports-5.0.1\test\jasper_report_template.jrprint

compile:
   [mkdir] Created dir: C:\tools\jasperreports-5.0.1\test\classes
   [javac] C:\tools\jasperreports-5.0.1\test\baseBuild.xml:28:
   warning: 'includeantruntime' was not set, defaulting t
   [javac] Compiling 1 source file to C:\tools\jasperreports-5.0.1\test\classes

compilereportdesing:
   [jrc] Compiling 1 report design files.
   [jrc] log4j:WARN No appenders could be found for logger
   (net.sf.jasperreports.engine.xml.JRXmlDigesterFactory).
   [jrc] log4j:WARN Please initialize the log4j system properly.
   [jrc] log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.
   [jrc] File : C:\tools\jasperreports-5.0.1\test\jasper_report_template.jrxml ... OK.

run:
   [echo] Runnin class : com.tutorialspoint.JasperUnicodeReportFill
   [java] log4j:WARN No appenders could be found for logger
   (net.sf.jasperreports.extensions.ExtensionsEnvironment).
   [java] log4j:WARN Please initialize the log4j system properly.

viewFillReport:
   [java] log4j:WARN No appenders could be found for logger
   (net.sf.jasperreports.extensions.ExtensionsEnvironment).
   [java] log4j:WARN Please initialize the log4j system properly.

BUILD SUCCESSFUL
Total time: 4 minutes 1 second

Come risultato della compilazione di cui sopra, si apre una finestra di JasperViewer come mostrato nella schermata sotto riportata -

Qui possiamo vedere che il testo visualizzato è in diverse lingue. Inoltre vediamo che le lingue sono raggruppate insieme sulla stessa pagina e anche mescolate nello stesso elemento di testo.