Unicode-Unterstützung

In JasperReports benötigt die Arbeit mit Texten einige spezielle Tools, um sowohl die Zeichendarstellungen als auch die Textformatierungseigenschaften zu verarbeiten. Jeder Text kann als Zeichenfolge mit einer bestimmten Darstellungsstruktur betrachtet werden. Die Texterscheinung besteht sowohl aus Layout- (und Absatz-) als auch aus Schriftarteinstellungen. Während das Textlayout in den meisten Fällen unverändert bleibt, können sich die Schriftarteinstellungen ändern, wenn der Bericht in verschiedenen Gebietsschemas ausgeführt wird.

Wir wissen, dass verschiedene Sprachen unterschiedliche Zeichensätze in Bezug auf die Darstellung bestimmter Zeichen benötigen. Arbeiten mit Texten bedeutet daher, mit Schriftarten zu arbeiten. Eine ausführliche Beschreibung der Verwendung von Schriftarten in JasperReports finden Sie jedoch im Kapitel Berichtsschriftarten .

Eines der Hauptmerkmale in Bezug auf den Textinhalt in einem bestimmten Bericht ist die Möglichkeit, ihn zu internationalisieren. Dies bedeutet, dass wir den Bericht in verschiedenen lokalisierten Umgebungen ausführen können, wobei verschiedene Sprachen und andere Lokalisierungseinstellungen ohne fest codierte Änderungen verwendet werden. Die Zeichenkodierung ist ein wichtiges Merkmal, wenn ein Bericht internationalisiert werden soll.

Zeichenkodierung

Ein Zeichen ist die kleinste Schreibeinheit, die eine aussagekräftige Information vermittelt. Es ist ein abstraktes Konzept, eine Figur hat kein visuelles Erscheinungsbild. "Großbuchstaben Latein A" ist ein anderes Zeichen als "Kleinbuchstaben Latein A" und "Großbuchstaben Kyrillisch A" und "Großbuchstaben Griechisch Alpha".

Eine visuelle Darstellung eines Charakters ist bekannt als glyph. Ein bestimmter Satz von Glyphen wird als a bezeichnetfont. "Großbuchstaben Latein A", "Großbuchstaben Kyrillisch A" und "Großbuchstaben Griechisch Alpha" haben möglicherweise identische Glyphen, aber sie sind unterschiedliche Zeichen. Gleichzeitig können die Glyphen für "Großbuchstaben Latein A" in Times New Roman, Gill Sans und Poetica kursiv sehr unterschiedlich aussehen, aber sie repräsentieren immer noch den gleichen Charakter.

Der Satz verfügbarer Zeichen wird als Zeichenrepertoire bezeichnet . Die Position (Index) eines bestimmten Zeichens innerhalb eines Repertoires wird als Codeposition oder Codepunkt bezeichnet. Die Methode zur numerischen Darstellung eines Codepunkts innerhalb eines bestimmten Repertoires wird als bezeichnetcharacter encoding.

Codierungen werden normalerweise in Oktetten ausgedrückt. Ein Oktett ist eine Gruppe von acht Binärziffern, dh acht Einsen und Nullen. Ein Oktett kann einen numerischen Bereich zwischen 0 und 255 oder zwischen 0x00 und 0xFF ausdrücken, um die hexadezimale Notation zu verwenden.

Unicode

Ein Unicode ist ein Zeichenrepertoire, das die meisten in den Sprachen der Welt verwendeten Zeichen enthält. Es kann Millionen von Zeichen aufnehmen und enthält bereits Hunderttausende. Unicode ist in "Ebenen" mit 64 KB Zeichen unterteilt. Die einzige, die in den meisten Fällen verwendet wird, ist die erste Ebene, die als mehrsprachige Grundebene oder BMP bezeichnet wird.

UTF-8 ist die empfohlene Codierung. Es wird eine variable Anzahl von Oktetten verwendet, um verschiedene Zeichen darzustellen.

In einer JRXML-Datei wird das Codierungsattribut im Header angegeben. Es wird zur Berichtserstellungszeit verwendet, um den XML-Inhalt zu dekodieren. Wenn der Bericht beispielsweise nur französische Wörter und Zeichen wie ç, é, â enthält, ist die ISO-8859-1-Codierung (auch bekannt als Latin-1) ausreichend.

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

Wie oben gezeigt, können wir im Idealfall die Codierungsanpassung an den minimalen Zeichensatz auswählen, der alle Zeichen im Dokument korrekt darstellen kann. Bei mehrsprachigen Dokumenten (dh Dokumenten, die Wörter enthalten, die in mehreren Sprachen geschrieben sind) sollte die Codierung ausgewählt werden, die an den minimalen Zeichensatz angepasst ist und in der Lage ist, alle Zeichen im Dokument korrekt darzustellen, auch wenn sie zu verschiedenen Sprachen gehören. Eine der Zeichencodierungen, die mehrsprachige Dokumente verarbeiten können, ist dieUTF-8, wird von JasperReports als Standardcodierungswert verwendet.

Die Texte werden normalerweise während der Internationalisierung in Ressourcenpaketdateien und nicht im Dokument gespeichert. Es gibt also Fälle, in denen JRXML selbst vollständig ASCII-kompatibel aussieht, aber zur Laufzeit generierte Berichte Texte enthalten, die mit ASCII nicht lesbar sind. Daher muss für eine bestimmte Art von Dokumentexportformaten (wie CSV, HTML, XHTML, XML und Text) auch die Codierung für das generierte Dokument bekannt sein. Unterschiedliche Sprachen werden durch unterschiedliche Zeichenkodierungen unterstützt. Daher müssen wir jedes Mal einen Bericht in einer lokalisierten Umgebung ausführen. Außerdem müssen wir wissen, welche Zeichenkodierung für die generierte Dokumentensprache am besten geeignet ist. In diesem Fall ist die in der JRXML-Datei selbst definierte Codierungseigenschaft möglicherweise nicht mehr nützlich.

Um diese Art von Problemen zu lösen, können wir eine Export-Kundeneigenschaft verwenden, die als net.sf.jasperreports.export.character.encoding bekannt ist . Diese benutzerdefinierte Export-Eigenschaft ist standardmäßig UTF-8 und in JasperReports vorhanden.

Dieser Standardwert wird in der Datei default.jasperreports.properties festgelegt . Für spezifischere Optionen zum Zeitpunkt des Exports steht auch der Exportparameter CHARACTER_ENCODING zur Verfügung.

Beispiel

Um die Verwendung der Unicode-Unterstützung in Jasperreports zu demonstrieren, schreiben wir eine neue Berichtsvorlage (jasper_report_template.jrxml). Save it to C:\tools\jasperreports-5.0.1\testVerzeichnis. Hier zeigen wir einen Text in verschiedenen Sprachen mit den Unicode-Zeichen (\ uXXXX) an. Jedes mit UTF-8 codierte Zeichen kann nur mit seinem 4-stelligen Hexadezimalcode dargestellt werden. Zum Beispiel kann der griechische Buchstabe Γ als \ u0393 geschrieben werden. Wenn eine solche Notation auftritt, fordert die Engine die entsprechende Zeichendarstellung im Zeichensatz an, und nur dieses bestimmte Zeichen wird ausgedruckt. Der Inhalt der JRXML ist wie folgt:

<?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>

In der obigen Datei können wir das Vorhandensein der UTF-8-Codierung sehen. Auch die lokalisierten Unicode-Textteile werden in Dokumentparametern gespeichert.

Der Java-Code zum Ausfüllen und Generieren des Berichts lautet wie folgt. Speichern wir diese DateiJasperUnicodeReportFill.java in das Verzeichnis 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();
      }

   }
}

Hier verwenden wir eine Instanz von JREmptyDataSource beim Füllen von Berichten, um eine Datenquelle mit einem Datensatz zu simulieren, wobei jedoch alle Felder in diesem einzelnen Datensatz null sind .

Berichterstellung

Wir werden die obige Datei mit unserem regulären ANT-Erstellungsprozess kompilieren und ausführen. Der Inhalt der Datei build.xml (gespeichert im Verzeichnis C: \ tools \ jasperreports-5.0.1 \ test) ist wie folgt.

Die Importdatei - baseBuild.xml wird aus dem Kapitel Umgebungs-Setup ausgewählt und sollte im selben Verzeichnis wie die build.xml abgelegt werden.

<?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>

Öffnen Sie als Nächstes das Befehlszeilenfenster und wechseln Sie in das Verzeichnis, in dem build.xml abgelegt ist. Führen Sie abschließend den Befehl ausant -Dmain-class=com.tutorialspoint.JasperUnicodeReportFill (viewFullReport ist das Standardziel) wie folgt:

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

Als Ergebnis der obigen Kompilierung wird ein JasperViewer-Fenster geöffnet, wie im folgenden Bildschirm gezeigt -

Hier können wir sehen, dass der angezeigte Text in verschiedenen Sprachen vorliegt. Wir sehen auch, dass die Sprachen auf derselben Seite zusammengefasst und auch in dasselbe Textelement gemischt sind.