Unicode支持(Unicode Support)
在JasperReports中,处理文本需要一些专用工具来处理字符表示和文本格式化属性。 可以将任何文本视为具有特定表示结构的字符序列。 文本外观包括布局(和段落)和字体设置。 但在大多数情况下,文本布局保持不变,在不同的语言环境中运行报表时,字体设置可能会更改。
我们知道不同的语言在特定的字符表示方面需要不同的字符集。 因此,使用文本意味着使用字体。 但是,有关如何在JasperReports中使用字体的详细讨论,请参见Report Fonts一章。
关于给定报告中文本内容的主要特征之一是将其国际化的可能性。 这意味着,我们可以在不同的本地化环境中运行报告,使用不同的语言和其他本地化设置,而无需任何硬编码修改。 当报告要国际化时,字符编码是一个重要特征。
字符编码
字符是传达有意义信息的最小写作单位。 它是一个抽象的概念,一个角色没有视觉外观。 “大写拉丁语A”是与“小写拉丁语a”和“大写西里尔语A”和“大写希腊语阿尔法语”不同的字符。
角色的直观表示称为glyph 。 某组字形称为font 。 “大写拉丁语A”,“大写西里尔语A”和“大写希腊字母”可能具有相同的字形,但它们是不同的字符。 与此同时,“大写拉丁字母A”的字形在Times New Roman,Gill Sans和Poetica斜体斜体中看起来非常不同,但它们仍然代表相同的字符。
可用字符集称为character repertoire 。 曲目中给定字符的位置(索引)称为其代码位置或代码点。 在给定指令集内数字表示代码点的方法称为character encoding 。
编码通常以八位字节表示。 八位字节是一组八个二进制数字,即八个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导出参数也可用。
例子 (Example)
为了演示在Jasperreports中使用unicode支持,让我们编写新的报告模板(jasper_report_template.jrxml)。 Save it to 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\JasperUnicodeReportFill.java -5.0.1\test\src\com\xnip目录。
package cn.xnip;
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 。
报表生成 (Report Generation)
我们将使用常规的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=cn.xnip.JasperUnicodeReportFill (viewFullReport是默认目标),如下所示 -
C:\tools\jasperreports-5.0.1\test>ant -Dmain-class=cn.xnip.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 : cn.xnip.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窗口打开,如下面的屏幕所示 -
在这里,我们可以看到显示的文本是不同的语言。 我们还看到语言在同一页面上组合在一起,并且也混合到同一文本元素中。