JasperReports入门教程(二):中文打印
JasperReports入门教程(二):中文打印
背景
在上一篇中我们介绍了JasperReport的基本入门,也展示了一个报表。但是我们的示例都是使用的英文,如果我们把需要打印的数据改为中文会怎么样?下面我们就测试一下
HashMap<String, Object> parameters = new HashMap<String, Object>();
parameters.put("name", "小明");
预览的pdf界面会发现原来打印name的地方不显示任何数据了
为什么会出现这个问题呢?我们查找net.sf.jasperreports的jar包源码发现它并不包含中文的字体库。那么就好办了,我们只需要加上中文字体库就可以了。
给JasperReport Studio工具增加字体
1.我们可以在本地电脑的 C:\Windows\Fonts下找到你想要的字体文件,也可以使用我提供的字体文件微软雅黑
msyh.ttf文件下载,提取码: bvmn
2.在JasperReport Studio工具的Window -> Preferences-> font 中add一个微软雅黑的字体
3.修改模板中需要显示中文的元素的字体为微软雅黑
给JasperReport增加扩展的字体资源文件
1.在resources资源文件下增加fonts.xml和msyh.ttf字体文件
- fonts.xml配置微软雅黑的字体
<?xml version="1.0" encoding="UTF-8"?>
<fontFamilies>
<fontFamily name="微软雅黑">
<normal>jaspers/fonts/msyh.ttf</normal>
<bold>jaspers/fonts/msyh.ttf</bold>
<italic>jaspers/fonts/msyh.ttf</italic>
<boldItalic>jaspers/fonts/msyh.ttf</boldItalic>
<pdfEncoding>Identity-H</pdfEncoding>
<pdfEmbedded>true</pdfEmbedded>
<exportFonts>
<export key="net.sf.jasperreports.html">'微软雅黑', Arial, Helvetica, sans-serif</export>
<export key="net.sf.jasperreports.xhtml">'微软雅黑', Arial, Helvetica, sans-serif</export>
</exportFonts>
</fontFamily>
</fontFamilies>
2.在resources资源文件下增加读取扩展字体的配置文件 jasperreports_extension.properties
- jasperreports_extension.properties文件配置如下
net.sf.jasperreports.extension.registry.factory.simple.font.families=net.sf.jasperreports.engine.fonts.SimpleFontExtensionsRegistryFactory
net.sf.jasperreports.extension.simple.font.families.dejavu=jaspers/fonts/fonts.xml
配置好的代码结构如下
3.访问地址 http://localhost:8080/test/jasper?type=pdf 可以看到中文打印出来了
实现原理
下面我们来分析下为什么需要按照上面来配置。因为JasperReport的jar包并未提供微软雅黑的字体的支持,所以我们需要通过提供的字体扩展的接口把我们需要的微软雅黑的字体在程序运行时可以读取到。
其中核心的类就是SimpleFontExtensionsRegistryFactory
,我们查看下这个类的源码
public class SimpleFontExtensionsRegistryFactory implements ExtensionsRegistryFactory
{
public final static String SIMPLE_FONT_FAMILIES_PROPERTY_PREFIX =
DefaultExtensionsRegistry.PROPERTY_REGISTRY_PREFIX + "simple.font.families.";
public final static String PROPERTY_SIMPLE_FONT_FAMILIES_REGISTRY_FACTORY =
DefaultExtensionsRegistry.PROPERTY_REGISTRY_FACTORY_PREFIX + "simple.font.families";
@Override
public ExtensionsRegistry createRegistry(String registryId, JRPropertiesMap properties)
{
List<PropertySuffix> fontFamiliesProperties = JRPropertiesUtil.getProperties(properties, SIMPLE_FONT_FAMILIES_PROPERTY_PREFIX);
List<String> fontFamiliesLocations = new ArrayList<String>();
for (Iterator<PropertySuffix> it = fontFamiliesProperties.iterator(); it.hasNext();)
{
PropertySuffix fontFamiliesProp = it.next();
//String fontFamiliesName = fontFamiliesProp.getSuffix();
String fontFamiliesLocation = fontFamiliesProp.getValue();
//fontFamiliesLocations.addAll(SimpleFontExtensionHelper.getInstance().loadFontFamilies(fontFamiliesLocation));
fontFamiliesLocations.add(fontFamiliesLocation);
}
return new FontExtensionsRegistry(fontFamiliesLocations);
}
}
这个类比较简单只有一个方法,这个createRegistry
方法就是读取配置文件中net.sf.jasperreports.extension.simple.font.families
开头的配置项的字体文件。
那么追溯这个createRegistry
方法在什么地方使用的,可以追溯到类DefaultExtensionsRegistry
中的instantiateRegistry
方法
查看这个方法可以发现它是加载实现了ExtensionsRegistryFactory
接口的某一个类,并且调用instantiateRegistry
方法来读取的配置项,这里就是上面提到的SimpleFontExtensionsRegistryFactory
类。
继续向上追溯到类DefaultExtensionsRegistry
中的loadRegistries
方法,这个方法是加载所有的通过扩展注册进来配置,当然也包括通过扩展注册的字体。
这个方法的代码行较多,我就不贴出来了,那么我们关注下这个方法其中一行代码
List<ClassLoaderResource> extensionResources = loadExtensionPropertyResources();
这行代码是获取所有需要加载的配置文件资源,通过代码我们可以发现它最终是加载所有名称是jasperreports_extension.properties
的文件,然后解析文件中的配置项并注册到JasperReport中
protected List<ClassLoaderResource> loadExtensionPropertyResources()
{
return JRLoader.getClassLoaderResources(EXTENSION_RESOURCE_NAME);
}
/**
* The name of property file resources that are used to load JasperReports
* extensions.
*/
public final static String EXTENSION_RESOURCE_NAME = "jasperreports_extension.properties";
到这里我们应该理解上面配置文件jasperreports_extension.properties中的配置项的意义。
##这行配置项是说明需要使用哪个注册工厂类来解析下面的配置项
net.sf.jasperreports.extension.registry.factory.simple.font.families=net.sf.jasperreports.engine.fonts.SimpleFontExtensionsRegistryFactory
##这行配置是配置了需要加载的字体文件的位置,配合上面的```SimpleFontExtensionsRegistryFactory```类来加载字体文件。
net.sf.jasperreports.extension.simple.font.families.dejavu=jaspers/fonts/fonts.xml
结束语
因为方便后续教程的演示,我们把公用的代码包括中文字体的支持都提起到一个公共的模块common,其他模块只引用即可使用,这样可以更好的专注本章节的代码。
JasperReports入门教程(二):中文打印的更多相关文章
- JasperReports入门教程(三):Paramters,Fields和Detail基本组件介绍
JasperReports入门教程(三):Paramter,Field和Detail基本组件介绍 前言 前两篇博客带领大家进行了入门,做出了第一个例子.也解决了中文打印的问题.大家跟着例子也做出了de ...
- JasperReports入门教程(四):多数据源
JasperReports入门教程(四):多数据源 背景 在报表使用中,一个页面需要打印多个表格,每个表格分别使用不同的数据源是很常见的一个需求.假如我们现在有一个需求如下:需要在一个报表同时打印所有 ...
- JasperReports入门教程(一):快速入门
JasperReports入门教程(一):快速入门 背景 现在公司的项目需要实现一个可以配置的报表,以便快速的适应客户的需求变化.后来在网上查资料发现可以使用JasperReports + Jaspe ...
- 无废话ExtJs 入门教程二十一[继承:Extend]
无废话ExtJs 入门教程二十一[继承:Extend] extjs技术交流,欢迎加群(201926085) 在开发中,我们在使用视图组件时,经常要设置宽度,高度,标题等属性.而这些属性可以通过“继承” ...
- 无废话ExtJs 入门教程二十[数据交互:AJAX]
无废话ExtJs 入门教程二十[数据交互:AJAX] extjs技术交流,欢迎加群(521711109) 1.代码如下: 1 <!DOCTYPE html PUBLIC "-//W3C ...
- 无废话ExtJs 入门教程二[Hello World]
无废话ExtJs 入门教程二[Hello World] extjs技术交流,欢迎加群(201926085) 我们在学校里学习任何一门语言都是从"Hello World"开始,这里我 ...
- mongodb入门教程二
title: mongodb入门教程二 date: 2016-04-07 10:33:02 tags: --- 上一篇文章说了mongodb最基本的东西,这边博文就在深入一点,说一下mongo的一些高 ...
- SpringBoot入门教程(二)CentOS部署SpringBoot项目从0到1
在之前的博文<详解intellij idea搭建SpringBoot>介绍了idea搭建SpringBoot的详细过程, 并在<CentOS安装Tomcat>中介绍了Tomca ...
- PySide——Python图形化界面入门教程(二)
PySide——Python图形化界面入门教程(二) ——交互Widget和布局容器 ——Interactive Widgets and Layout Containers 翻译自:http://py ...
随机推荐
- Python turtle库的应用——蛇
turtle库介绍 1.Turtle中的turtle.setup()函数用于启动一个图形窗口,它有四个参数 turtle.setup(width, height, startx, starty) 分别 ...
- MATLAB 动图绘制、保存
动图有gif格式和视频的avi格式. 1.sin(x)动图 clear all h = animatedline;%动画线 axis([0 4*pi -1 1]) box on x = linspac ...
- Activiti任务分配
分配任务负责人 一.固定分配 在进行业务流程建模时指定固定的任务负责人 在properties 视图中,填写Assignee 项为任务负责人. 注意: 由于固定分配方式,任务只管一步一步执行任务,执行 ...
- Python第三方包之pretty-errors
Python第三方包之pretty-errors 发现了一个第三方好用的python包,这个包可以让我们在面对冗长的错误时候能够一眼看到重点 安装方式 pip install pretty-error ...
- html中的字幕滚动marquee属性
该标签不是HTML3.2的一部分,并且只支持MSIE3以后内核,所以如果你使用非IE内核浏览器(如:Netscape)可能无法看到下面一些很有意思的效果,该标签是个容器标签. 语法: <marq ...
- Activiti7新的API介绍
一.Activiti7 的组成部分 Activiti Core 作为Activiti 的核心部分,Activiti Cloud 主要是利用云服务来实现分布式业务流程开发. 二.Activiti 新的 ...
- Scala学习系列(一)——Scala为什么是大数据第一高薪语言
为什么是Scala 虽然在大数据领域Java的使用更普及,Python也有后来居上的势头,但Scala一直有着不可动摇的地位.我们熟悉的Spark,Kafka,Flink都是由Scala完成了其核心代 ...
- PTA数据结构与算法题目集(中文) 7-15
PTA数据结构与算法题目集(中文) 7-15 7-15 QQ帐户的申请与登陆 (25 分) 实现QQ新帐户申请和老帐户登陆的简化版功能.最大挑战是:据说现在的QQ号码已经有10位数了. 输入格式 ...
- java类文件结构笔记
注:新的博客地址 - https://zhengw-tech.com/archives/ 我们都知道java实现跨平台靠的是虚拟机技术,将源文件编译成与操作系统无关的,只有虚拟机能识别并执行的字节码文 ...
- P1198 [JSOI2008]最大数(线段树基础)
P1198 [JSOI2008]最大数 题目描述 现在请求你维护一个数列,要求提供以下两种操作: 1. 查询操作. 语法:Q L 功能:查询当前数列中末尾L个数中的最大的数,并输出这个数的值. 限制: ...