Unicode 支援



在 JasperReports 中,處理文字需要一些專用工具來處理字元表示和文字格式屬性。任何文字都可以被視為具有特定表示結構的字元序列。文字外觀包括佈局(和段落)和字型設定。但在大多數情況下,文字佈局保持不變,字型設定在不同語言環境中執行報表時可能會發生變化。

我們知道,不同的語言需要不同的字元集來表示特定的字元。因此,處理文字意味著處理字型。但是,關於如何在 JasperReports 中使用字型的詳細討論可在章節報表字型中找到。

給定報表中關於文字內容的一個主要功能是使其國際化的可能性。這意味著,我們可以在不同的本地化環境中執行報表,使用不同的語言和其他本地化設定,而無需任何硬編碼修改。當報表旨在國際化時,字元編碼是一個重要的功能。

字元編碼

字元是最小的書寫單位,它傳達有意義的資訊。這是一個抽象的概念,字元沒有視覺外觀。“大寫拉丁字母 A”與“小寫拉丁字母 a”以及“大寫西裡爾字母 A”和“大寫希臘字母 Alpha”是不同的字元。

字元的視覺表示稱為字形。一組字形稱為字型。“大寫拉丁字母 A”、“大寫西裡爾字母 A”和“大寫希臘字母 Alpha”可能具有相同的字形,但它們是不同的字元。同時,“大寫拉丁字母 A”的字形在 Times New Roman、Gill Sans 和 Poetica chancery italic 中看起來可能大相徑庭,但它們仍然代表相同的字元。

可用字元集稱為字元集。給定字元在字元集中的位置(索引)稱為其程式碼位置或程式碼點。在給定字元集中以數字方式表示程式碼點的方法稱為字元編碼

編碼通常以八位位元組表示。八位位元組是由八個二進位制數字組成的一組,即八個 1 和 0。八位位元組可以表示 0 到 255 之間的數值範圍,或者使用十六進位制表示法表示 0x00 到 0xFF 之間的數值範圍。

Unicode

Unicode 是一個字元集,其中包含世界上大多數語言中使用的字元。它可以容納數百萬個字元,並且已經包含數十萬個字元。Unicode 分為 64K 個字元的“平面”。在大多數情況下,唯一使用的平面是第一個平面,稱為基本多語言平面或 BMP。

UTF-8 是推薦的編碼。它使用可變數量的八位位元組來表示不同的字元。

在 JRXML 檔案中,編碼屬性在標題中指定。它在報表編譯時用於解碼 XML 內容。例如,如果報表僅包含法語單詞和 ç、é、â 等字元,則 ISO-8859-1(又名 Latin-1)編碼就足夠了。

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

如上所示,理想情況下,我們可以選擇適合最小字元集的編碼,該編碼可以正確表示文件中的所有字元。但是,對於多語言文件(即包含用多種語言拼寫的單詞的文件),應該選擇適合最小字元集的編碼,即使這些字元屬於不同的語言,也能夠正確表示文件中的所有字元。能夠處理多語言文件的字元編碼之一是UTF-8,它被 JasperReports 用作預設編碼值。

在國際化過程中,文字通常儲存在資源包檔案中,而不是儲存在文件中。因此,有些情況下 JRXML 本身看起來完全相容 ASCII,但執行時生成的報表確實包含無法使用 ASCII 讀取的文字。因此,對於某種型別的文件匯出格式(例如 CSV、HTML、XHTML、XML 和文字),也必須知道生成的文件的編碼。不同的語言由不同的字元編碼支援。因此,每次我們需要在本地化環境中執行報表時。此外,我們必須知道,哪種字元編碼最適合生成的文件語言。在這種情況下,JRXML 檔案本身中定義的編碼屬性可能不再有用。

為了解決此類問題,我們可以使用稱為net.sf.jasperreports.export.character.encoding的匯出自定義屬性。此匯出自定義屬性預設為 UTF-8,並且存在於 JasperReports 中。

此預設值設定在default.jasperreports.properties檔案中。對於匯出時的更具體的選項,CHARACTER_ENCODING 匯出引數也可使用。

示例

為了演示在 Jasperreports 中使用 Unicode 支援,讓我們編寫新的報表模板 (jasper_report_template.jrxml)。將其儲存到 C:\tools\jasperreports-5.0.1\test 目錄。在這裡,我們將使用 Unicode 字元 (\uXXXX) 以不同的語言顯示文字。任何使用 UTF-8 編碼的字元都可以僅使用其 4 位十六進位制程式碼來表示。例如,希臘字母 Γ 可以寫成 \u0393。當遇到這樣的表示法時,引擎會呼叫字元集中的相應字元表示,並且只會打印出該特定字元。JRXML 的內容如下:

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

在上文中,我們可以看到 UTF-8 編碼的存在。本地化的 Unicode 文字片段也儲存在文件引數中。

填充並生成報表的 Java 程式碼如下。讓我們將此檔案JasperUnicodeReportFill.java儲存到 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();
      }

   }
}

在填充報表時,我們使用JREmptyDataSource的例項來模擬其中只有一個記錄的資料來源,但此單記錄中的所有欄位均為null

報表生成

我們將使用常規的 ANT 構建過程來編譯和執行上述檔案。build.xml 檔案(儲存在 C:\tools\jasperreports-5.0.1\test 目錄下)的內容如下所示。

匯入檔案 - baseBuild.xml 從章節環境設定中獲取,應該與 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>

接下來,讓我們開啟命令列視窗並轉到放置 build.xml 的目錄。最後,執行命令ant -Dmain-class=com.tutorialspoint.JasperUnicodeReportFill(viewFullReport 是預設目標)如下:

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

上述編譯的結果是開啟一個 JasperViewer 視窗,如下面的螢幕所示:

Jasper Report Unicode Example

在這裡,我們可以看到顯示的文字使用不同的語言。我們還看到這些語言分組在同一頁上,並且混合在同一個文字元素中。

廣告
© . All rights reserved.