Marvin's Blog

Hi, My friend. Welcome to my space

0%

JasperReport 全攻略

JasperReport生态

IReport、JasperStudio是jasper的辅助视觉设计工具,不用它也能设计Jasper报表(编码jrxml)。

5.5之前这个工具叫ireport,5.5之后随着JasperStudio的出生,IReport就被完全替代了。

IReport支持jdk最高版本为1.7,在不修改系统环境变量的前提下,可以配置IReport根目录中etc目录下的ireport.conf,将jdkhome注释打开并配置jdk1.7版本位置。

1
2
3
4
5
<dependency>
<groupId>org.codehaus.groovy</groupId>
<artifactId>groovy-all</artifactId>
<version>2.4.7</version>
</dependency>

Groovy是Java虚拟机的敏捷和动态语言,以Java语言的优势为基础,添加了从Python、Ruby和Smalltalk等语言中借鉴的特性。提供流行的编程语言特性,学习成本几乎为零。提供静态类型检查的能力,并静态地编译成java字节码,以获得健壮性和性能,与所有现有的Java类和库无缝集成,可以在任何可以使用java的地方使用它。通过其强大的处理原语、OO能力和Ant DSL使编写shell和构建脚本变得容易。

Report -> Language -> java选择语言为java后无需引入groovy,IReport可以设置全局语言模式,JasperStudio暂未发现。

JasperReport基本使用

  1. 使用可视化工具制作.jrxml报表模板

  2. Java工程引入jasperreports(Language设置为java,若为groovy也要引入)

    1
    2
    3
    4
    5
    <dependency>
    <groupId>net.sf.jasperreports</groupId>
    <artifactId>jasperreports</artifactId>
    <version>5.6.0</version>
    </dependency>
  3. 编码导出

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    //指定模板文件位置
    String jrxml = "C:\\Users\\Administrator\\JaspersoftWorkspace\\MyReports\\test.jrxml";
    //设定报表所需要的外部参数内容
    Map parameters = new HashMap();
    parameters.put("company", "XXXXX有限公司");
    //编译模板文件
    JasperReport jasperReport = JasperCompileManager.compileReport(jrxml);
    //填充数据,生成文件输出流
    JasperPrint jasperPrint = JasperFillManager.fillReport(jasperReport, parameters, new JREmptyDataSource());
    //导出PDF文件
    JasperExportManager.exportReportToPdfFile(jasperPrint, "D:/test/report/" + jasperReport.getName() + ".pdf");

    其中JasperReport对象也可以由视图工具中编译好的.jasper文件加载

    1
    2
    3
    4
    //直接加载视图工具中编译好的.jasper文件
    String jasper = ReportPDF.class.getResource("/").getPath() + "template/test.jasper";
    InputStream inputStream = new FileInputStream(new File(jasper));
    JasperReport _jasperReport = (JasperReport) JRLoader.loadObject(inputStream);
  4. 疑难杂症

    1
    2
    3
    <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="test" pageWidth="686" pageHeight="397" orientation="Landscape" 
    whenNoDataType="AllSectionsNoDetail" columnWidth="646" leftMargin="20" rightMargin="20" topMargin="20" bottomMargin="20" uuid="1d450a83-6e0f-4885-a0f1-979eaf18bf08">
    </jasperReport>

    填充数据fillReport(JasperReport report, Map parameters, JRDataSource datasource)datasource为可选参数。若无new JREmptyDataSource(),且模板文件中无whenNoDataType="AllSectionsNoDetail",则导出的文件内容为空白

    其中IReport工具中该选项为属性 -> More -> When No Data,JasperStudio为Properties -> Report -> When No Data Type

JasperReport导出中文

.jrxml模板文件中,所有涉及中文的element,需要设置如下

1
2
3
<textElement>
<font pdfFontName="STSong-Light" pdfEncoding="UniGB-UCS2-H" isPdfEmbedded="true"/>
</textElement>

以上配置在JasperStudio中操作为Properties -> Advanced -> PDF

  • PDF Embedded = true
  • PDF Encoding = UniGB-UCS2-H (Chinese Simplified)
  • PDF Font Name = STSong-Light

在Java工程中编码前,需要引入以下jar
输出文件时

1
2
3
4
5
6
7
<dependency>
<groupId>com.lowagie</groupId>
<artifactId>itext-asian</artifactId>
<version>2.1.7</version>
<scope>system</scope>
<systemPath>${basedir}/src/main/res/lib/iTextAsian.jar</systemPath>
</dependency>

输出流时

1
2
3
4
5
6
7
<dependency>
<groupId>com.lowagie</groupId>
<artifactId>itext</artifactId>
<version>2.1.7.js4</version>
<scope>system</scope>
<systemPath>${basedir}/src/main/res/lib/itext-2.1.7.js4.jar</systemPath>
</dependency>

JasperReport自定义字体

  • JasperStudio中安装字体

    Window -> Preperences -> Jaspersoft Studio -> Fonts -> Add From Path选择字体文件位置导入,导入成功之后选中字体点击EditPDF Encoding选择Identity-H (Unicode with horizontal writing)并勾选Embed this font in PDF document

  • 完成上一步之后,在字体编辑界面点击Export导出zip压缩文件

  • 文本元素字体设置为自定义的字体,此时是文本元素的常规字体设置,并非导出中文中提及的PDF Font Name

  • 将从JasperStudio中导出的zip/jar文件解压并复制到Java工程中的resources下即可完成自定义字体

总结:通过上述步骤实操得知

  • Java工程Classpath下需要有名为jasperreports_extension.properties的配置文件

    该配置文件内容如下:

    1
    2
    net.sf.jasperreports.extension.registry.factory.fonts=net.sf.jasperreports.engine.fonts.SimpleFontExtensionsRegistryFactory
    net.sf.jasperreports.extension.simple.font.families.ireportfamily1611215772940=fonts/fontsfamily1611215772940.xml
  • 其中fontsfamily1611215772940.xml即为字体实际配置

    编辑此配置,并在指定位置放置字体文件,即可省略JasperStudio中的字体安装/导出操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<?xml version="1.0" encoding="UTF-8"?>
<fontFamilies>
<fontFamily name="阿里巴巴普惠体 R">
<normal><![CDATA[fonts/阿里巴巴普惠体R/Alibaba-PuHuiTi-Regular.ttf]]></normal>
<pdfEncoding><![CDATA[Identity-H]]></pdfEncoding>
<pdfEmbedded><![CDATA[true]]></pdfEmbedded>
<exportFonts/>
</fontFamily>
<fontFamily name="Mono">
<normal><![CDATA[fonts/JetBrains/JetBrainsMono-Regular.ttf]]></normal>
<pdfEncoding><![CDATA[Identity-H]]></pdfEncoding>
<pdfEmbedded><![CDATA[true]]></pdfEmbedded>
<exportFonts/>
</fontFamily>
</fontFamilies>

JasperReport变量

  • Parameters

    JasperStudio中该配置位于Outline中,此面板显示设置方式为Window > Show View > Other > General > Outlinehele -> search可以查找到此设置方式)

    右键此项选择Create Parameter可以新建参数,参数可用于单次出现的可变数据,如公司名称、表单名称、、、

  • Fields

    右键此项选择Create Fedld可以新建字段,字段可用于重复多次的列表数据,置于模板Detail详情区域。

JasperReport图像

  • 新建参数Properties -> Object -> Name = img & Class = java.io.InputStream

    1
    <parameter name="img" class="java.io.InputStream"/>
  • 插入图像Image -> Expression = $P{img}

    1
    2
    3
    4
    <image>
    <reportElement x="0" y="0" width="100" height="100" uuid="8b2bbc27-43a6-49f6-a79a-e8417ad20d8f"/>
    <imageExpression><![CDATA[$P{img}]]></imageExpression>
    </image>
  • 编码时参数中添加图片输出流

    1
    2
    String img = "D:/Test/zxing.png";
    parameters.put("img", new FileInputStream(new File(img)));
  • 导出完成

JasperReport条码

Java工程填充条码时需要导入以下两组插件

1
2
3
4
5
6
7
8
9
10
11
<dependency>
<groupId>net.sf.barcode4j</groupId>
<artifactId>barcode4j</artifactId>
<version>2.1</version>
</dependency>
<dependency>
<groupId>org.apache.xmlgraphics</groupId>
<artifactId>batik-bridge</artifactId>
<version>1.11</version>
</dependency>

  • 条形码放大

    Module Width = 2.0

    Quiet Zone = 2.0

    Vertical Quiet Zone = 2.0

  • 条形码上层放置文本内容设置背景色后还需取消勾选Transparent

  • 二维码设置Margin = 0 px可以清除白色空白区域

JasperReport导出JavaBean列表

重点:列表数据循环加载的关键在于Fields变量文本所在区域移除空白区域(双击区域),且模板文件中该区域留有空闲高度。例:文件可用高度为300px,Page HeaderPage Footer总高度为100px(除Detail区域再无其它区域),若Fields变量文本高度为20px,则每页可循环10组列表数据。

  • 模板工具添加Fields变量(变量名称与Bean对象属性名称一致)

  • 模板Detail区域插入Fields(根据需求设置样式及边框)

  • 编码添加数据并导出

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    List<User> list = new ArrayList<>();
    for (int i = 1; i <= 10; i++) {
    //注意:JavaBean的属性名称和模版的Fileds的名称一致的
    list.add(new User().setName("张三-" + i).setAge(10 + i).setSex(i));
    }
    String jrxml = "C:\\Users\\Administrator\\JaspersoftWorkspace\\MyReports\\userList.jrxml";
    JRBeanCollectionDataSource dataSource = new JRBeanCollectionDataSource(list);
    JasperReport jasperReport = JasperCompileManager.compileReport(jrxml);
    JasperPrint jasperPrint = JasperFillManager.fillReport(jasperReport, new HashMap<>(), dataSource);
    //导出PDF文件
    JasperExportManager.exportReportToPdfFile(jasperPrint, "D:/test/report/" + jasperReport.getName() + ".pdf");

JasperReport结合数据库连接导出数据

  • 添加Data Adapters

    Repository Explorer -> Data Adapters中右键选择Create Data Adapter,在弹出框中选择Database JDBC Connection后,进行常规JDBC配置(命名:DemoData)。需要在Driver Classpath中添加对应的数据库连接驱动

    该配置或许不支持useSSL,JDBC URL配置常规路径既可jdbc:mysql://localhost/database。测试连接正常后继续往下操作

  • Outline中右键模板文件选择Dataset And Query ...,在弹出框中配置数据库查询。

    首先在数据库图标右侧选择上一步配置好的数据库连接,然后在右侧输入区域填入查询语句,点击Read Fields按钮。若无特殊情况,到此即可,也可以根据实际情况编辑字段列表。

  • Fields添加字段

  • Detail区域插入字段

  • 编码导出(在线预览PDF模式)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    String path = "C:\\Users\\Administrator\\JaspersoftWorkspace\\MyReports\\userData.jrxml";
    //1.编译
    JasperReport jasperReport = JasperCompileManager.compileReport(path);
    //2.构建Print对象,用于让模块结合数据
    //第三个参数:如果是JDBC数据源,应该设置Connection对象
    Connection connection = dataSource.getConnection();
    JasperPrint jasperPrint = JasperFillManager.fillReport(jasperReport, new HashMap<>(), connection);
    //3.PDF输出流
    response.setContentType("application/pdf");
    response.setHeader("Content-Disposition", "inline;");
    final OutputStream outputStream = response.getOutputStream();
    JasperExportManager.exportReportToPdfStream(jasperPrint, outputStream);
    //关闭连接和输出流
    connection.close();
    outputStream.close();

JasperReport制作表格

之前两节所涉及的集合数据均为普通的Text Field元素组成,表格制作方式与上面所述完全不同。

  • 结合数据源制作表格(数据源使用上文设置好的连接DemoData

    1. Outline面板右键选择Dataset And Query ...或者Properties面板点击Edit query, filter and sort options,在弹出框的右边编辑区域填入SQL查询语句,Read Fidlds获取字段(可省略)。

    2. 拖入Table组件,弹出框选择Create a Table using a new dataset新建dataset,名称自定义,选择Create new dataset from a connection or Data Source继续,Data Adapter选择DemoData,编辑区填入SQL查询语句,选择字段(必要),Group By(可选)。后续设置按需求,直至结束。

    3. Java编码只需传入数据库connection即可。

      JasperPrint jasperPrint = JasperFillManager.fillReport(jasperReport, new HashMap<>(), connection);

  • 基于JavaBean集合数据制作表格(较为繁琐)

    1. 新建datasetData Source选择One Empty Record - Empty rows后结束。

    2. dataset中的Fields按需建立与JavaBean对象同名的属性名称。

    3. Outline面板模板文件中的Fields中建立名为dataList的字段(该名称后续需要用到),Class填入net.sf.jasperreports.engine.data.JRBeanCollectionDataSource

      1
      <field name="users" class="net.sf.jasperreports.engine.data.JRBeanCollectionDataSource"/>
    4. 拖入Table组件,在弹出框选择Create a Table using an existing dataset并选择刚刚建立的dataset名称,Connection选择Use a JRDatasource expression后在编辑区填入$F{dataList}(上一步建立的字段名,后续仍会用到),后续操作与结合数据源制作方式类似。

    5. Java编码

      1. 新建类TableDataSource,其中JRBeanCollectionDataSource类型的属性名称与之前必须一致dataList

        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        13
        14
        15
        public class TableDataSource {

        private JRBeanCollectionDataSource dataList;

        public JRBeanCollectionDataSource getDataList() {
        return dataList;
        }

        public TableDataSource setDataList(JRBeanCollectionDataSource dataList) {
        this.dataList = dataList;
        return this;
        }

        //其它属性值以及get()、set()、、、
        }
      2. 封装数据,此时分三步封装

        • 封装底层结果集

          1
          2
          3
          4
          5
          6
          7
          List<User> users = new ArrayList<>();
          for (int i = 1; i <= 10; i++) {
          users.add(new User().setName("Name-" + i).setAge(10 + i).setSex(i));
          }

          TableDataSource tableDataSource = new TableDataSource();
          tableDataSource.setDataList(new JRBeanCollectionDataSource(users));
        • 封装用于后续操作的Collection对象

          1
          2
          List<TableDataSource> list = new ArrayList<>();
          list.add(tableDataSource);
        • 封装模板数据源

          1
          JRBeanCollectionDataSource dataSource = new JRBeanCollectionDataSource(list);
      3. 结合模板导出

        1
        2
        3
        4
        5
        6
        7
        String jrxml = "C:\\Users\\Administrator\\JaspersoftWorkspace\\MyReports\\" + sourceName + ".jrxml";
        //编译
        JasperReport jasperReport = JasperCompileManager.compileReport(jrxml);
        //填充
        JasperPrint jasperPrint = JasperFillManager.fillReport(jasperReport, new HashMap(), dataSource);
        //导出PDF文件
        JasperExportManager.exportReportToPdfFile(jasperPrint, "D:/test/report/" + jasperReport.getName() + ".pdf");

JasperReport其它配置

  • 本文所涉及到的配置未提及IReport时,均为JasperStudio的配置。

  • 内容溢出时自动换行(前提是文本区域高度足够),勾选Properties -> Appearance -> Detail Overflows

    .jrxml中配置如下isPrintWhenDetailOverflows="true"

    1
    2
    3
    4
    5
    6
    7
    <staticText>
    <reportElement x="307" y="51" width="100" height="30" isPrintWhenDetailOverflows="true" uuid="f299c63b-b25d-44c4-8a23-210eed43f6d2"/>
    <textElement>
    <font pdfFontName="STSong-Light" pdfEncoding="UniGB-UCS2-H" isPdfEmbedded="true"/>
    </textElement>
    <text><![CDATA[Static Text]]></text>
    </staticText>

致谢

自定义字体解决方案出自: 博客园 Andy_alone

表格制作出自: CSDN ゛Smlie。

其它资料部分出自: 博客园 该昵称无法识别