Hỗ trợ Unicode

Trong JasperReports, làm việc với văn bản cần một số công cụ chuyên dụng để xử lý cả biểu diễn ký tự và thuộc tính định dạng văn bản. Bất kỳ văn bản nào cũng có thể được coi là một chuỗi ký tự với một cấu trúc biểu diễn cụ thể. Giao diện văn bản bao gồm cả bố cục (và đoạn văn) và cài đặt phông chữ. Nhưng trong hầu hết các trường hợp, bố cục văn bản vẫn bất biến, cài đặt phông chữ có thể thay đổi khi chạy báo cáo ở các Miền khác nhau.

Chúng tôi biết rằng các ngôn ngữ khác nhau cần các bộ ký tự khác nhau đối với các ký tự cụ thể. Do đó, làm việc với văn bản có nghĩa là làm việc với phông chữ. Tuy nhiên, thảo luận chi tiết về cách sử dụng phông chữ trong JasperReports có sẵn trong chương Phông chữ Báo cáo .

Một trong những đặc điểm chính liên quan đến nội dung văn bản trong một báo cáo nhất định là khả năng quốc tế hóa nó. Điều đó có nghĩa là, chúng tôi có thể chạy báo cáo trong các môi trường bản địa hóa khác nhau, sử dụng các ngôn ngữ khác nhau và các cài đặt bản địa hóa khác mà không cần bất kỳ sửa đổi mã cứng nào. Mã hóa ký tự là một tính năng quan trọng khi báo cáo được dự định quốc tế hóa.

Mã hóa ký tự

Một ký tự là đơn vị chữ viết nhỏ nhất truyền đạt một thông tin có ý nghĩa. Đó là một khái niệm trừu tượng, một nhân vật không có hình dáng bên ngoài. "Chữ hoa Latinh A" là một ký tự khác với "chữ Latinh viết thường a" và từ "chữ hoa Cyrillic A" và "chữ hoa Alpha của tiếng Hy Lạp".

Hình ảnh đại diện của một nhân vật được gọi là glyph. Một bộ glyph nhất định được gọi làfont. "Chữ hoa Latinh A", "chữ hoa Cyrillic A" và "chữ hoa chữ cái Hy Lạp Alpha" có thể có các nét chữ giống hệt nhau, nhưng chúng là các ký tự khác nhau. Đồng thời, các nét chữ cho "chữ Latinh A viết hoa" có thể trông rất khác trong chữ nghiêng Times New Roman, Gill Sans và Poetica chancery, nhưng chúng vẫn đại diện cho cùng một ký tự.

Tập hợp các nhân vật có sẵn được gọi là tập hợp các nhân vật . Vị trí (chỉ mục) của một nhân vật nhất định trong một tiết mục được gọi là vị trí mã hoặc điểm mã của nó. Phương pháp biểu thị số điểm mã trong một kho lưu trữ nhất định được gọi làcharacter encoding.

Mã hóa thường được biểu thị dưới dạng các octet. Một octet là một nhóm gồm tám chữ số nhị phân, tức là tám chữ số đơn vị và số không. Một octet có thể biểu thị một dải số từ 0 đến 255 hoặc từ 0x00 đến 0xFF, để sử dụng ký hiệu thập lục phân.

Unicode

Unicode là một kho ký tự chứa hầu hết các ký tự được sử dụng trong các ngôn ngữ trên thế giới. Nó có thể chứa hàng triệu ký tự và đã chứa hàng trăm nghìn ký tự. Unicode được chia thành các "mặt phẳng" gồm 64K ký tự. Loại duy nhất được sử dụng trong hầu hết các trường hợp là mặt phẳng đầu tiên, được gọi là mặt phẳng đa ngôn ngữ cơ bản, hoặc BMP.

UTF-8 là kiểu mã hóa được khuyến nghị. Nó sử dụng một số octet thay đổi để biểu diễn các ký tự khác nhau.

Trong tệp JRXML, thuộc tính mã hóa được chỉ định trong tiêu đề. Nó được sử dụng tại thời điểm biên dịch báo cáo để giải mã nội dung XML. Ví dụ: nếu báo cáo chỉ chứa các từ tiếng Pháp và các ký tự như ç, é, â, thì mã hóa ISO-8859-1 (hay còn gọi là Latin-1) là đủ -

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

Như đã thấy ở trên, lý tưởng nhất là chúng ta có thể chọn kiểu mã hóa phù hợp với bộ ký tự tối thiểu, có thể thể hiện chính xác tất cả các ký tự trong tài liệu. Nhưng trong trường hợp tài liệu Đa ngôn ngữ (tức là tài liệu có chứa các từ được đánh vần bằng nhiều ngôn ngữ), người ta nên chọn cách mã hóa phù hợp với bộ ký tự tối thiểu, có thể thể hiện chính xác tất cả các ký tự trong tài liệu, ngay cả khi chúng thuộc các ngôn ngữ khác nhau. Một trong những mã hóa ký tự có thể xử lý các tài liệu đa ngôn ngữ làUTF-8, được sử dụng làm giá trị mã hóa mặc định bởi JasperReports.

Các văn bản thường được giữ trong các tệp gói tài nguyên hơn là trong tài liệu trong quá trình quốc tế hóa. Vì vậy, có những trường hợp bản thân JRXML trông hoàn toàn tương thích với ASCII, nhưng các báo cáo được tạo trong thời gian chạy có chứa văn bản không thể đọc được bằng ASCII. Do đó, đối với một loại định dạng xuất tài liệu nhất định (chẳng hạn như CSV, HTML, XHTML, XML và văn bản) người ta cũng phải biết mã hóa cho tài liệu được tạo. Các ngôn ngữ khác nhau được hỗ trợ bởi các bảng mã ký tự khác nhau. Vì vậy, mỗi lần, chúng tôi cần chạy báo cáo trong môi trường được bản địa hóa. Hơn nữa, chúng ta phải biết, đó là cách mã hóa ký tự thích hợp nhất cho ngôn ngữ tài liệu được tạo. Trong trường hợp này, thuộc tính mã hóa được xác định trong tệp JRXML có thể không hữu ích nữa.

Để giải quyết loại vấn đề này, chúng tôi có thể sử dụng thuộc tính khách hàng xuất khẩu được gọi là net.sf.jasperreports.export.character.encoding . Thuộc tính tùy chỉnh xuất này được mặc định là UTF-8 và có trong JasperReports.

Giá trị mặc định này được đặt trong tệp default.jasperreports.properties . Đối với các tùy chọn cụ thể hơn tại thời điểm xuất, thông số xuất CHARACTER_ENCODING cũng có sẵn.

Thí dụ

Để chứng minh việc sử dụng hỗ trợ unicode trong Jasperreports, hãy viết mẫu báo cáo mới (jasper_report_template.jrxml). Save it to C:\tools\jasperreports-5.0.1\testdanh mục. Tại đây, chúng tôi sẽ hiển thị văn bản bằng các ngôn ngữ khác nhau bằng các ký tự Unicode (\ uXXXX). Bất kỳ ký tự nào được mã hóa bằng UTF-8 chỉ có thể được biểu diễn bằng mã thập lục phân 4 chữ số của nó. Ví dụ: chữ cái Hy Lạp Γ có thể được viết là \ u0393. Khi gặp phải ký hiệu như vậy, công cụ sẽ gọi biểu diễn ký tự thích hợp trong bộ ký tự và chỉ ký tự cụ thể đó mới được in ra. Nội dung của JRXML như sau:

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

Trong tệp trên, chúng ta có thể thấy sự hiện diện của bảng mã UTF-8. Ngoài ra, các đoạn văn bản Unicode đã bản địa hóa được lưu trữ trong các tham số tài liệu.

Mã java để điền và tạo báo cáo như bên dưới. Hãy lưu tệp nàyJasperUnicodeReportFill.java vào thư mục 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();
      }

   }
}

Ở đây chúng tôi sử dụng một phiên bản của JREmptyDataSource khi điền các báo cáo để mô phỏng nguồn dữ liệu có một bản ghi trong đó, nhưng với tất cả các trường trong bản ghi này là trống .

Tạo báo cáo

Chúng tôi sẽ biên dịch và thực thi tệp trên bằng quy trình xây dựng ANT thông thường của chúng tôi. Nội dung của tệp build.xml (được lưu trong thư mục C: \ tools \ jasperreports-5.0.1 \ test) như bên dưới.

Tệp nhập - baseBuild.xml được chọn từ chương Thiết lập môi trường và phải được đặt trong cùng thư mục với 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>

Tiếp theo, hãy mở cửa sổ dòng lệnh và đi đến thư mục nơi build.xml được đặt. Cuối cùng, thực hiện lệnhant -Dmain-class=com.tutorialspoint.JasperUnicodeReportFill (viewFullReport là mục tiêu mặc định) như sau:

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

Kết quả của quá trình biên dịch ở trên, một cửa sổ JasperViewer mở ra như được hiển thị trong màn hình dưới đây:

Ở đây, chúng ta có thể thấy rằng văn bản được hiển thị bằng các ngôn ngữ khác nhau. Ngoài ra, chúng tôi thấy rằng các ngôn ngữ được nhóm lại với nhau trên cùng một trang và cũng được trộn vào cùng một phần tử văn bản.