【PDF报表】java中的PDF报表使用

http://www.itcast.cn

常用PDF制作

  • iText PDF:iText是著名的开放项目,是用于生成PDF文档的一个java类库。通过iText不仅可以生成PDF或rtf 的文档,而且可以将XML、Html文件转化为PDF文件。
  • Openoffice:openoffice是开源软件且能在windows和linux平台下运行,可以灵活的将word或者Excel转化 为PDF文档。
  • Jasper Report:是一个强大、灵活的报表生成工具,能够展示丰富的页面内容,并将之转换成PDF

JasperReport

生命周期

  • 设计阶段(Design):所谓的报表设计就是创建一些模板,模板包含了报表的布局与设计,包括执行计算的 复杂公式、可选的从数据源获取数据的查询语句、以及其它的一些信息。模板设计完成之后,我们将模板保 存为JRXML文件(JR代表JasperReports),其实就是一个XML文件。
  • 执行阶段(Execution):使用以JRXML文件编译为可执行的二进制文件(即.Jasper文件)结合数据进行执 行,填充报表数据
  • 输出阶段(Export):数据填充结束,可以指定输出为多种形式的报表

原理

在这里插入图片描述

  • JRXML:报表填充模板,本质是一个XML. JasperReport已经封装了一个dtd,只要按照规定的格式写这个xml文件,那么jasperReport就可以将其解析 最终生成报表,但是jasperReport所解析的不是我们常见的.xml文件,而是.jrxml文件,其实跟xml是一样 的,只是后缀不一样。
  • Jasper:由JRXML模板编译生成的二进制文件,用于代码填充数据。 解析完成后JasperReport就开始编译.jrxml文件,将其编译成.jasper文件,因为JasperReport只可以 对.jasper文件进行填充数据和转换,这步操作就跟我们java中将java文件编译成class文件是一样的
  • Jrprint:当用数据填充完Jasper后生成的文件,用于输出报表。 这一步才是JasperReport的核心所在,它会根据你在xml里面写好的查询语句来查询指定是数据库,也可以控 制在后台编写查询语句,参数,数据库。在报表填充完后,会再生成一个.jrprint格式的文件(读取jasper文 件进行填充,然后生成一个jrprint文件)
  • Exporter:决定要输出的报表为何种格式,报表输出的管理类。
  • Jasperreport可以输出多种格式的报表文件,常见的有Html,PDF,xls等

模板制作工具:Jaspersoft Studio

.jrxml文件

<?xml version="1.0" encoding="UTF-8"?>
<!-- Created with Jaspersoft Studio version 6.5.0.final using JasperReports Library version 6.5.0  -->
<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="test01" pageWidth="595" pageHeight="842" columnWidth="555" leftMargin="20" rightMargin="20" topMargin="20" bottomMargin="20" uuid="b7211d1c-a575-48f1-b253-9c63f5f41307">
	<property name="com.jaspersoft.studio.data.defaultdataadapter" value="One Empty Record"/>
	<queryString>
		<![CDATA[]]>
	</queryString>
	<background>
		<band splitType="Stretch"/>
	</background>
	<pageHeader>
		<band height="96" splitType="Stretch">
			<image>
				<reportElement x="-20" y="-20" width="180" height="50" uuid="93b99d68-82d6-4d23-a6f8-6594b9c1af3e"/>
				<imageExpression><![CDATA["	https://img0.bdstatic.com/img/image/wise/3%E8%B6%B3%E7%90%83%E5%AE%9D%E8%B4%9D.jpg"]]></imageExpression>
			</image>
			<line>
				<reportElement x="-20" y="30" width="591" height="5" uuid="69ffb590-4919-481e-922e-577ae367e59e"/>
			</line>
		</band>
	</pageHeader>
	<detail>
		<band height="80" splitType="Stretch">
			<staticText>
				<reportElement x="230" y="50" width="100" height="30" uuid="104d722d-99b1-44f5-b3fb-582f78411ab5"/>
				<textElement>
					<font fontName="华文宋体"/>
				</textElement>
				<text><![CDATA[Jaspersoft好强大]]></text>
			</staticText>
		</band>
	</detail>
	<pageFooter>
		<band height="75" splitType="Stretch">
			<staticText>
				<reportElement x="230" y="20" width="100" height="30" uuid="6863d3c6-774e-4f7c-adda-5f1bc6148c78"/>
				<textElement>
					<font fontName="华文宋体"/>
				</textElement>
				<text><![CDATA[xxx出品]]></text>
			</staticText>
		</band>
	</pageFooter>
</jasperReport>

生命周期

package cn.itcast.jr;

import net.sf.jasperreports.engine.JREmptyDataSource;
import net.sf.jasperreports.engine.JasperCompileManager;
import net.sf.jasperreports.engine.JasperFillManager;
import net.sf.jasperreports.view.JasperViewer;

import java.util.HashMap;

public class PDFTest {

    public static void main(String[] args) {
        showPdf();
    }

    public static void createJasper(){
        try{
            String path = "C:\\Users\\资源\\test01.jrxml";
            JasperCompileManager.compileReportToFile(path);
        }catch(Exception e){
            e.printStackTrace();
        }
    }

    public static void createJrprint(){
        try{
            String path = "C:\\Users\\资源\\test01.jasper";
            //通过空参数和空数据源进行填充
            JasperFillManager.fillReportToFile(path,new HashMap(),new JREmptyDataSource());
        }catch(Exception e){
            e.printStackTrace();
        }
    }

    public static void showPdf(){
        try{
            String path = "C:\\Users\\资源\\test01.jrprint";
            JasperViewer.viewReport(path,false);
        }catch(Exception e){
            e.printStackTrace();
        }
    }
}

springboot工程使用

  • 依赖
<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.0.5.RELEASE</version>
    <relativePath/>
</parent>
<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-thymeleaf</artifactId>
    </dependency>
    <dependency>
        <groupId>net.sf.jasperreports</groupId>
        <artifactId>jasperreports</artifactId>
        <version>6.5.0</version>
    </dependency>
    <dependency>
        <groupId>org.olap4j</groupId>
        <artifactId>olap4j</artifactId>
        <version>1.2.0</version>
    </dependency>
    <dependency>
        <groupId>com.lowagie</groupId>
        <artifactId>itext</artifactId>
        <version>2.1.7</version>
    </dependency>
    <dependency>
        <groupId>org.apache.poi</groupId>
        <artifactId>poi</artifactId>
        <version>4.0.1</version>
    </dependency>
    <dependency>
        <groupId>org.apache.poi</groupId>
        <artifactId>poi-ooxml</artifactId>
        <version>4.0.1</version>
    </dependency>
    <dependency>
        <groupId>org.apache.poi</groupId>
        <artifactId>poi-ooxml-schemas</artifactId>
        <version>4.0.1</version>
    </dependency>
</dependencies>
  • 配置文件:application.yml
server:
 port: 8181
spring:
 application:
   name: jasper-demo #指定服务名
 resources:
   static-locations: classpath:/templates/
 datasource:
   driver-class-name: com.mysql.jdbc.Driver
   url: jdbc:mysql://localhost:3306/ihrm?useUnicode=true&characterEncoding=utf8
   username: root
   password: root
  • 准备.jasper文件:test001.jasper

  • 测试controller

@RestController
public class JasperController {
    @GetMapping("/testJasper")
    public void createHtml(HttpServletResponse response, HttpServletRequest
request)throws Exception{
        //引入jasper文件。由JRXML模板编译生成的二进制文件,用于代码填充数据
        Resource resource = new ClassPathResource("templates/test01.jasper");
        //加载jasper文件创建inputStream
        FileInputStream isRef = new FileInputStream(resource.getFile());
        ServletOutputStream sosRef = response.getOutputStream();
        try {
            //创建JasperPrint对象
            JasperPrint jasperPrint = JasperFillManager.fillReport(isRef, new HashMap<>(),new JREmptyDataSource());
            //写入pdf数据
            JasperExportManager.exportReportToPdfStream(jasperPrint,sosRef);
       } finally {
            sosRef.flush();
            sosRef.close();
       }
   }
}

中文乱码问题:

  • 配置文件: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
  • 指定中文配置文件fonts.xml
<?xml version="1.0" encoding="UTF-8"?>
<fontFamilies>
    <!--<fontFamily name="Lobster Two">-->
    <!--<normal>lobstertwo/LobsterTwo-Regular.otf</normal>-->
    <!--<bold>lobstertwo/LobsterTwo-Bold.otf</bold>-->
    <!--<italic>lobstertwo/LobsterTwo-Italic.otf</italic>-->
    <!--<boldItalic>lobstertwo/LobsterTwo-BoldItalic.otf</boldItalic>-->
    <!--<pdfEncoding>Identity-H</pdfEncoding>-->
    <!--<pdfEmbedded>true</pdfEmbedded>-->
    <!--<!–-->
    <!--<exportFonts>-->
    <!--<export key="net.sf.jasperreports.html">'Lobster Two', 'Times New Roman', 
Times, serif</export>-->
    <!--</exportFonts>-->
    <!--–>-->
    <!--</fontFamily>-->
    <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, sansserif</export>
            <export key="net.sf.jasperreports.xhtml">'华文宋体', Arial, Helvetica, sansserif</export>
        </exportFonts>
        <!--
        <locales>
            <locale>en_US</locale>
            <locale>de_DE</locale>
        </locales>
        -->
    </fontFamily>
</fontFamilies>
  • 引入对应字体库:stsong.TTF

数据填充

进行数据填充需要在设计相应的.jasper模板时进行相关设置。

主要的就是.jasper模板的制作。

parameters(参数)数据填充

/**
 *  基于parameters以Map的形式填充数据
 */
@GetMapping("/testJasper2")
public void createPdf(HttpServletRequest request, HttpServletResponse response) throws IOException {
    //1.引入jasper文件
    Resource resource = new ClassPathResource("templates/testParam.jasper");
    FileInputStream fis = new FileInputStream(resource.getFile());


    //2.创建JasperPrint,向jasper文件中填充数据
    ServletOutputStream os = response.getOutputStream();
    try {
        Map parameters = new HashMap<>();
        //设置参数 参数的key = 模板中使用的parameters参数的name
        parameters.put("username","张三");
        parameters.put("mobile","120");
        parameters.put("dept","讲师");
        parameters.put("company","传智播客");

        JasperPrint print = JasperFillManager.fillReport(fis,parameters,new JREmptyDataSource());
        JasperExportManager.exportReportToPdfStream(print,os);
    } catch (JRException e) {
        e.printStackTrace();
    }finally {
        os.flush();
    }
}

数据源数据填充

  • 模板制作:数据源填充设置

在这里插入图片描述

/**
 *  基于JDBC数据源的形式填充数据
 */
//测试JDBC连接数据源
@GetMapping("/testJasper03")
public void createPdf(HttpServletRequest request, HttpServletResponse response) 
    throws Exception {
    //1.引入jasper文件
    Resource resource = new ClassPathResource("templates/testConn.jasper");
    FileInputStream fis = new FileInputStream(resource.getFile());
    //2.创建JasperPrint,向jasper文件中填充数据
    ServletOutputStream os = response.getOutputStream();
    try {
        /**
             * 1.jasper文件流
             * 2.参数列表
             * 3.数据库连接
             */
        HashMap parameters = new HashMap();
        JasperPrint print = JasperFillManager.fillReport(fis,parameters,getConnection());
        //3.将JasperPrint已PDF的形式输出
        JasperExportManager.exportReportToPdfStream(print,os);
        response.setContentType("application/pdf");
    } catch (JRException e) {
        e.printStackTrace();
    }finally {
        os.flush();
    }
}
//创建数据库Connection
public Connection getConnection() throws Exception {
    String url = "jdbc:mysql://localhost/ihrm";
    Class.forName("com.mysql.jdbc.Driver");
    Connection conn = DriverManager.getConnection(url, "root", "root");
    return conn;
}
  • 制作模板动态构造sql进行查询
    • 创建参数
    • sql动态传参
    • 代码中:通过parameters传递参数进去。

在这里插入图片描述

javaBean数据源填充

  • 模板中需手动创建field,然后进行排版。
/**
 *  基于javaBean数据源的形式填充数据
 */
@GetMapping("/testJasper4")
public void createPdf(HttpServletRequest request, HttpServletResponse response) throws Exception {
    //1.引入jasper文件
    Resource resource = new ClassPathResource("templates/testBean.jasper");
    FileInputStream fis = new FileInputStream(resource.getFile());

    //2.创建JasperPrint,向jasper文件中填充数据
    ServletOutputStream os = response.getOutputStream();
    try {
        Map parameters = new HashMap<>();
        //构建javaBean的数据源
        //1.获取到对象的list集合
        List<User> userList = getUserList();
        //2.通过list集合创建javaBean的数据源对象
        JRBeanCollectionDataSource ds = new JRBeanCollectionDataSource(userList);
        JasperPrint print = JasperFillManager.fillReport(fis,parameters,ds);
        JasperExportManager.exportReportToPdfStream(print,os);
    } catch (JRException e) {
        e.printStackTrace();
    }finally {
        os.flush();
    }
}

public List<User> getUserList() {
    List<User> list = new ArrayList<>();
    for(int i=0;i<10;i++) {
        User user = new User(i+"", "用户"+i, "test","讲师", "1380000000"+i);
        list.add(user);
    }
    return list;
}

分组报表

  • 制作模板时设置分组:选择根据某字段进行分组,后续会根据传入的数据进行分组展示

在这里插入图片描述

/**
 *  分组报表
 */
@GetMapping("/testJasper5")
public void createPdf(HttpServletRequest request, HttpServletResponse response) throws Exception {
    //1.引入jasper文件
    Resource resource = new ClassPathResource("templates/testGroup.jasper");
    FileInputStream fis = new FileInputStream(resource.getFile());

    //2.创建JasperPrint,向jasper文件中填充数据
    ServletOutputStream os = response.getOutputStream();
    try {
        Map parameters = new HashMap<>();
        //构建javaBean的数据源
        //1.获取到对象的list集合
        List<User> userList = getUserList();
        //2.通过list集合创建javaBean的数据源对象
        JRBeanCollectionDataSource ds = new JRBeanCollectionDataSource(userList);
        JasperPrint print = JasperFillManager.fillReport(fis,parameters,ds);
        JasperExportManager.exportReportToPdfStream(print,os);
    } catch (JRException e) {
        e.printStackTrace();
    }finally {
        os.flush();
    }
}
public List<User> getUserList() {
    List<User> list = new ArrayList<>();
    for(int i=0;i<10;i++) {
        User user = new User(i+"", "itcast"+i, "test1","讲师", "1380000000"+i);
        list.add(user);
    }
    for(int i=0;i<5;i++) {
        User user = new User(i+"", "itheima"+i, "test2","讲师", "1380000000"+i);
        list.add(user);
    }
    return list;
}

在这里插入图片描述

  • 计数、页面等可通过内置函数与内置field进行设置。主要还是模板的设计。

Chart图表

/**
 *  charts图形报表
 */
@GetMapping("/testJasper6")
public void createPdf(HttpServletRequest request, HttpServletResponse response) throws Exception {
    //1.引入jasper文件
    Resource resource = new ClassPathResource("templates/testCharts.jasper");
    FileInputStream fis = new FileInputStream(resource.getFile());

    //2.创建JasperPrint,向jasper文件中填充数据
    ServletOutputStream os = response.getOutputStream();
    try {
        Map parameters = new HashMap<>();
        //构建javaBean的数据源
        //1.获取到对象的list集合
        List<UserCount> userList = getUserCountList();
        //2.通过list集合创建javaBean的数据源对象
        JRBeanCollectionDataSource ds = new JRBeanCollectionDataSource(userList);
        JasperPrint print = JasperFillManager.fillReport(fis,parameters,ds);
        JasperExportManager.exportReportToPdfStream(print,os);
    } catch (JRException e) {
        e.printStackTrace();
    }finally {
        os.flush();
    }
}

public List<UserCount> getUserCountList() {
    List<UserCount> list = new ArrayList<>();

    UserCount uc1 = new UserCount("传智播客",1000l);
    UserCount uc2 = new UserCount("黑马程序员",1000l);
    UserCount uc3 = new UserCount("baidu",1000l);
    list.add(uc1);
    list.add(uc2);
    list.add(uc3);
    return list;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值