Java中常见PDF报表生成方式(iText、JasperReports、解决不输出中文的方法)

常见PDF报表生成方式(iText、JasperReports、解决不输出中文的方法)

1、iText

iText是著名的开放源码的站点sourceforge一个项目,是用于生成PDF文档的一个java类库。通过iText不仅可以生成PDF或rtf的文档,而且可以将XML、Html文件转化为PDF文件。 iText的安装非常方便,下载iText.jar文件后,只需要在系统的CLASSPATH中加入iText.jar的路径,在程序中就可以使用iText类库了。

maven坐标:

<dependency>
  <groupId>com.lowagie</groupId>
  <artifactId>itext</artifactId>
  <version>2.1.7</version>
</dependency>

创建项目演示

package com.zcl.app;

import com.lowagie.text.DocumentException;
import com.lowagie.text.Paragraph;
import com.lowagie.text.pdf.PdfWriter;
import com.lowagie.text.Document;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;

/**
 * 项目名称:health_parent
 * 描述:测试itext
 *
 * @author zhong
 * @date 2022-06-29 20:37
 */
public class ITextTest {
    
    
    public static void main(String[] args) {
    
    
        try {
    
    
            // 获取文档对象
            Document document = new Document();
            // 写出文档到指定的目录
            PdfWriter.getInstance(document, new FileOutputStream("D:\\test.pdf"));
            // 打开文档
            document.open();
            // 给文档里面添加数据内容
            document.add(new Paragraph("hello itext"));
            // 关闭流
            document.close();
        } catch (FileNotFoundException e) {
    
    
            e.printStackTrace();
        } catch (DocumentException e) {
    
    
            e.printStackTrace();
        }
    }
}

第一步,先引入核心maven坐标,需要注意的是Document的包不要引错了
运行main方法如果没有报错就是执行成功了,然后手动打开pdf文件里里面就会有代码上面写入的内容,如果需要设计pdf文件的各种样式需要经过很多的繁琐代码,后期的开发基本不会使用到这个生成PDF的。

2、JasperReports

JasperReports是一个强大、灵活的报表生成工具,能够展示丰富的页面内容,并将之转换成PDF,HTML,或者XML格式。该库完全由Java写成,可以用于在各种Java应用程序,包括J2EE,Web应用程序中生成动态内容。一般情况下,JasperReports会结合Jaspersoft Studio(模板设计器)使用导出PDF报表。

maven坐标:

<dependency>
  <groupId>net.sf.jasperreports</groupId>
  <artifactId>jasperreports</artifactId>
  <version>6.8.0</version>
</dependency>

值得注意的是,使用该maven坐标时可能会出现itext2.1.7.js依赖冲突问题导致无法使用,可以排除再引入如下代码

<dependency>
    <groupId>net.sf.jasperreports</groupId>
    <artifactId>jasperreports</artifactId>
    <version>6.10.0</version>
    <exclusions>
        <exclusion>
            <groupId>com.lowagie</groupId>
            <artifactId>itext</artifactId>
        </exclusion>
    </exclusions>
</dependency>
<dependency>
  <groupId>com.lowagie</groupId>
  <artifactId>itext</artifactId>
  <version>2.1.7</version>
</dependency>

2.1、快速入门

创建demo.jrxml文件设计PDF的模板

在后面会使用软件来完成PDF的模板设计和代码生成,这里只需要复制使用即可

<?xml version="1.0" encoding="UTF-8"?>
<!-- Created with Jaspersoft Studio version 6.9.0.final using JasperReports Library version 6.9.0-cb8f9004be492ccc537180b49c026951f4220bf3  -->
<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="demo" pageWidth="595" pageHeight="842" columnWidth="555" leftMargin="20" rightMargin="20" topMargin="20" bottomMargin="20" uuid="e3403475-74c8-4358-a0fa-fb5b703b1abe">
	<property name="com.jaspersoft.studio.data.defaultdataadapter" value="One Empty Record"/>
	<parameter name="company" class="java.lang.String"/>
	<parameter name="reportDate" class="java.lang.String"/>
	<queryString>
		<![CDATA[]]>
	</queryString>
	<field name="name" class="java.lang.String"/>
	<field name="address" class="java.lang.String"/>
	<field name="email" class="java.lang.String"/>
	<background>
		<band splitType="Stretch"/>
	</background>
	<title>
		<band height="90" splitType="Stretch">
			<staticText>
				<reportElement x="210" y="20" width="200" height="40" uuid="2e246083-05c6-4dbd-9059-f7fe986d139e"/>
				<textElement>
					<font fontName="华文宋体" size="20"/>
				</textElement>
				<text><![CDATA[JasperReports Test]]></text>
			</staticText>
			<textField>
				<reportElement x="468" y="50" width="100" height="30" uuid="14ac6dd3-7c52-457e-95b5-b8c2eebaae1b"/>
				<textFieldExpression><![CDATA[$P{reportDate}]]></textFieldExpression>
			</textField>
		</band>
	</title>
	<detail>
		<band height="37" splitType="Stretch">
			<textField>
				<reportElement x="60" y="4" width="100" height="30" uuid="9fd8ea6a-722d-4c35-a4dc-74f3ed490709"/>
				<textFieldExpression><![CDATA[$F{name}]]></textFieldExpression>
			</textField>
			<textField>
				<reportElement x="227" y="4" width="100" height="30" uuid="d2926cd3-c477-4801-98a6-8d9d7f43adec"/>
				<textFieldExpression><![CDATA[$F{address}]]></textFieldExpression>
			</textField>
			<textField>
				<reportElement x="400" y="4" width="100" height="30" uuid="e7a64e8c-7c91-4c3a-9e1f-f9861353fd79"/>
				<textFieldExpression><![CDATA[$F{email}]]></textFieldExpression>
			</textField>
		</band>
	</detail>
	<pageFooter>
		<band height="37" splitType="Stretch">
			<textField>
				<reportElement x="230" y="5" width="100" height="30" uuid="0eaaff53-787f-4d02-a940-4fd8f249ad95"/>
				<textElement textAlignment="Center"/>
				<textFieldExpression><![CDATA[$P{company}]]></textFieldExpression>
			</textField>
		</band>
	</pageFooter>
</jasperReport>

创建单元测试环境

import net.sf.jasperreports.engine.JasperCompileManager;
import net.sf.jasperreports.engine.JasperExportManager;
import net.sf.jasperreports.engine.JasperFillManager;
import net.sf.jasperreports.engine.JasperPrint;
import net.sf.jasperreports.engine.data.JRBeanCollectionDataSource;
import org.junit.Test;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 项目名称:health_parent
 * 描述:使用模板导出PDF
 *
 * @author zhong
 * @date 2022-06-29 22:50
 */
public class TestDemo1 {
    
    
    @Test
    public void testJasperReports() throws Exception {
    
    
        // 定义模板的位置
        String jrxmlPath =
                "F:\\Java项目案例(手动完成)\\传智健康项目\\itcast_health\\health_parent\\jasperReportsDemo\\src\\main\\resources\\demo.jrxml";
        // 生成编译文件的位置
        String jasperPath =
                "F:\\Java项目案例(手动完成)\\传智健康项目\\itcast_health\\health_parent\\jasperReportsDemo\\src\\main\\resources\\demo.jasper";

        //编译模板
        JasperCompileManager.compileReportToFile(jrxmlPath, jasperPath);

        //构造数据
        Map paramters = new HashMap();
        paramters.put("reportDate", "2022-6-29");
        paramters.put("company", "itcast");
        List<Map> list = new ArrayList();
        Map map1 = new HashMap();
        map1.put("name", "xiaoming");
        map1.put("address", "beijing");
        map1.put("email", "[email protected]");
        Map map2 = new HashMap();
        map2.put("name", "xiaoli");
        map2.put("address", "nanjing");
        map2.put("email", "[email protected]");
        list.add(map1);
        list.add(map2);

        //填充数据
        JasperPrint jasperPrint =
                JasperFillManager.fillReport(jasperPath,
                        paramters,
                        new JRBeanCollectionDataSource(list));

        //输出文件
        String pdfPath = "D:\\test.pdf";
        JasperExportManager.exportReportToPdfFile(jasperPrint, pdfPath);
    }
}

找到输出的文件路径打开查看,格式如下
在这里插入图片描述

2.3、JasperReports原理

在这里插入图片描述

  • JRXML:报表填充模板,本质是一个xml文件
  • Jasper:由JRXML模板编译成的二进制文件,用于代码填充数据
  • Jrprint:当用数据填充完Jasper后生成的对象,用于输出报表
  • Exporter:报表输出的管理类,可以指定要输出的报表为何种格式
  • PDF/HTML/XML:报表形式

2.4、JasperReports开发流程

使用JasperReports导出pdf报表,开发流程如下:

  1. 制作报表模板
  2. 模板编译
  3. 构造数据
  4. 填充数据
  5. 输出文件

3、模板设计器Jaspersoft Studio

Jaspersoft Studio是一个图形化的报表设计工具,可以非常方便的设计出PDF报表模板文件(其实就是一个xml文件),再结合JasperReports使用,就可以渲染出PDF文件。
下载地址:https://community.jaspersoft.com/community-download
在这里插入图片描述

点击Download进入到选择下载版本的页面
下载需要注册账号和登录
在这里插入图片描述
下载完成之后直接双击程序进行下一步的安装即可(可以根据需求修改安装路径)

打开软件的首页
在快速入门案例里面导入的demo.jrxml模板文件就是通过这个软件来完成设计的,下面将重点讲解和介绍该软件的使用
注意:该软件使用的java开发的,所以本机电脑上必须要有jdk1.8版本以上的才可以运行起来
在这里插入图片描述

3.1创建工程

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

项目的创建带有一些包文件如下
在这里插入图片描述

3.2、创建工程模板

右键项目的名称选择模板样式
在这里插入图片描述
选择模板
在这里插入图片描述

给模板起名
在这里插入图片描述
创建模板页面介绍
右键可以将不需要的默认面板删除
在这里插入图片描述
其中Detail区域可以添加多个,其他区域只能有一个。

3.3、将元素应用到模板中

1、Image元素的设置
在这里插入图片描述
选择图片的基本属性
在这里插入图片描述

将图片拖拽进来后可以将其就行放大和缩小以及移动的位置都可以通过可视化来完成,查看图片的源码如下:

<title>
	<band height="90" splitType="Stretch">
		<image>
			<reportElement x="0" y="0" width="140" height="90" uuid="b84c1ee3-8fb7-42c8-91f6-64876c740231"/>
			<imageExpression><![CDATA["https://img-home.csdnimg.cn/images/20201124032511.png"]]></imageExpression>
		</image>
	</band>
</title>

其实我们上面创建的demo1.jrxml模板文件,本质上就是一个xml文件,只不过我们不需要自己编写xml文件的内容,而是通过Jaspersoft Studio这个设计器软件进行可视化设计即可。

2、Static Text元素

Static Text元素就是静态文本元素,用于在PDF文件上展示静态文本信息:
与image的手法一样都是左键点击拖拽到指定的位置就可以了

在这里插入图片描述
查看源码生成的代码
在这里插入图片描述

3、Current Date时间元素

Current Date元素用于在报表中输出当前系统日期,将改元素拖动到Title区域:

选择时间的格式或者自定义时间格式
在这里插入图片描述

还可以设置字体的大小,点击预览的时候可以直接看到是否需要的结果

3.4、动态数据填充

在这里插入图片描述
Parameters通常用来展示单个数据,Fields通常用来展示需要循环的列表数据。
1、Parameters

在Parameters上点击右键,创建一个Parameter参数:

在这里插入图片描述

修改属性和名称(需要保存生效)
在这里插入图片描述

使用的步骤也是一样的,选择动态数据拖拽到指定的区域然后修改基本属性(字体大小样式剧中等)就可以了

执行预览的界面输入动态的数据就会展示出来了,如下图
在这里插入图片描述

注意:由于我们是在Jaspersoft Studio软件中进行预览,所以需要通过上面的输入框动态为Parameter赋值,在后期项目使用时,需要我们在Java程序中动态为Parameter赋值进行数据填充。

2、Fields

使用Fields方式进行数据填充,既可以使用jdbc数据源方式也可以使用JavaBean数据源方式。

2.1、jdbc数据源数据填充

第一步:在Repository Explorer面板中,在Data Adapters点击右键,创建一个数据适配器
在这里插入图片描述
第二步:选择Database JDBC Connection
在这里插入图片描述
第三步:选择mysql数据库,并完善jdbc连接信息
在这里插入图片描述

为了能够在Jaspersoft Studio中预览到数据库中的数据,需要加入MySQL的驱动包
该jar驱动包在java程序中经常使用到找一下就可以了,没有就搜索下载一个,如果没有指定驱动包就无法完成数据库的连接
在这里插入图片描述
第四步:在Outline视图中,右键点击工程名,选择Database and Query菜单
在这里插入图片描述
第五步:在弹出的对话框中选择刚刚创建的JDBC数据库连接选项
在这里插入图片描述
第六步:在弹出对话框中Language选择sql,在右侧区域输入SQL语句并点击Read Fields按钮
在这里插入图片描述
第七步:在Outline视图中的Fields下可以看到t_setmeal表中相关字段信息,拖动某个字段到设计区的Detail区域并调整位置
当拖拽字段进入内容区的时候就会有两内容,Detail1中的就是动态数据而ColumnHeader上的name则可以看作是动态数据的表头,可以修改的静态文本
在这里插入图片描述

可以看到,在拖动Fields到设计区时,同时会产生两个元素,一个是静态文本,一个是动态元素。静态文本相当于表格的表头,可以根据需要修改文本内容。最终设计完的效果如下:
在这里插入图片描述
注意:动态的数据是放在Detali1区域的,静态的表头是必须放在Column Header上否则就会出现重复的表同信息
第八步:使用Preview预览视图进行预览
在这里插入图片描述

2.2、JavaBean数据源数据填充

第一步:创建字段
在这里插入图片描述
修改名称和类型
在这里插入图片描述

第二步:拖拽进入内容区修改标题即可
在软件中自定义的字段预览时的数据是未空的,需要后期通过java代码来完成数据的填充才可以完成展示

3、表格边框的设置

选择字段选择边框完成设置
在这里插入图片描述

注意:如果预览的有空隙就需要调整他的上下距离贴合即可
在这里插入图片描述

4、在项目中输出PDF报表(查询数据库的字段输出)

说明:在这个测试项目中主要还是使用上面设计的demo1.jrxml模板就行java的代码数据填充

导入项目的必备依赖
在上面的设计模板中也有导入mysql的驱动,但是我们java代码中如果入需要查询到数据的话也是需要来完成驱动的导入的

<dependencies>
  <dependency>
      <groupId>net.sf.jasperreports</groupId>
      <artifactId>jasperreports</artifactId>
      <version>6.10.0</version>
      <exclusions>
          <exclusion>
              <groupId>com.lowagie</groupId>
              <artifactId>itext</artifactId>
          </exclusion>
      </exclusions>
  </dependency>
  <dependency>
      <groupId>com.lowagie</groupId>
      <artifactId>itext</artifactId>
      <version>2.1.7</version>
  </dependency>
  <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.12</version>
      <scope>test</scope>
  </dependency>
  <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <version>5.1.47</version>
  </dependency>
</dependencies>

4.1、将模板demo1.jrxml文件复制到java的项目中
该模板是在设计软件上可以连接mysql动态查询数据填充的而不是javabean的填充数据模板

4.2、创建测试方法

/**
 * 动态连接数据填充
 * @throws Exception
 */
@Test
public void testReport_MySQL() throws Exception {
    
    
    // 获取连接数据库的信息
    Class.forName("com.mysql.jdbc.Driver");
    Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/health", "root", "1234");
    // 定义模板的位置
    String jrxmlPath =
            "F:\\Java项目案例(手动完成)\\传智健康项目\\itcast_health\\health_parent\\jasperReportsDemo\\src\\main\\resources\\demo1.jrxml";
    // 生成编译文件的位置
    String jasperPath =
            "F:\\Java项目案例(手动完成)\\传智健康项目\\itcast_health\\health_parent\\jasperReportsDemo\\src\\main\\resources\\demo1.jasper";

    // 编译模板(文件位置,生成位置)
    JasperCompileManager.compileReportToFile(jrxmlPath,jasperPath);

    // 构造数据,与模板的一致就行填充
    Map map = new HashMap();
    map.put("company","java查询数据库数据填充");

    // 填充数据查询(因为在模板设计中就已经编写好了sql语句,所以直接给数据库的连接对象即可自动查询获取)
    // (编译后的文件,填充的字段1,连接数据库的信息)
    JasperPrint jasperPrint = JasperFillManager.fillReport(jasperPath, map, connection);

    // 输出文件
    String pdfPath = "D:\\test.pdf";
    JasperExportManager.exportReportToPdfFile(jasperPrint,pdfPath);

}

解决输出步显示中文方法
1、需要在模板设计前将所有的中文数据的字体都改为华文宋体
2、导入下面的补丁到resources文件下
在这里插入图片描述
fonts.xml文件如下

<?xml version="1.0" encoding="UTF-8"?>
<fontFamilies>
    <fontFamily name="华文宋体">
        <normal>stsong/stsong.ttf</normal>
        <bold>stsong/stsong.ttf</bold>
        <italic>stsong/stsong.ttf</italic>
        <boldItalic>stsong/stsong.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>

stsong.ttf文件如下
需要网上下载
在这里插入图片描述

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.lobstertwo=stsong/fonts.xml

5、在项目中输出PDF报表(使用javaBean填充数据)

在快速入门案例中使用的就是javaBean的方法填充数据的,可以参考上面的内容

猜你喜欢

转载自blog.csdn.net/baidu_39378193/article/details/125529045
今日推荐