- JasperReports 教程
- JasperReports - 首页
- JasperReports - 开始
- JasperReports - 环境设置
- JasperReports - 生命周期
- JasperReports - 设计
- JasperReports - 编译设计
- JasperReports - 填充
- JasperReports - 查看和打印
- JasperReports - 导出
- JasperReports - 参数
- JasperReports - 数据源
- JasperReports - 字段
- JasperReports - 表达式
- JasperReports - 变量
- JasperReports - 节
- JasperReports - 分组
- JasperReports - 字体
- JasperReports - Unicode 支持
- JasperReports - 样式
- JasperReports - 脚本
- JasperReports - 创建子报表
- JasperReports - 创建图表
- JasperReports - 交叉表
- JasperReports - 国际化
- JasperReports 资源
- JasperReports - 快速指南
- JasperReports - 有用资源
- JasperReports - 讨论
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 https://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 窗口,如下面的屏幕所示:
在这里,我们可以看到显示的文本使用不同的语言。我们还看到这些语言分组在同一页上,并且混合在同一个文本元素中。