iReport全面排坑以及从0到1的应用(包括iReport启动闪退,Detail不显示,Table组件怎么传参,以及嵌入SpringBoot等)各步骤均有配图

1 篇文章 0 订阅
1 篇文章 0 订阅

        最近做项目需要用到iReport生产PDF报表期间遇到许多问题,包括Detail不显示、整合到SpringBoot中Table组件的传参问题等,网上找了许多资料全都千篇一律的复制粘贴,内容模棱两可,现将我开发期间遇到的各种问题以及iReport的各种应用方式放到此处做个记录,顺便为各位秃头的兄弟们提供个参考.

        为便于各位兄弟们排查问题,且不浪费大家的时间,先将我遇到的问题以及iReport的大坑及解决方式写在文章最前面,iReport相关使用方式及整合SpringBoot相关代码放到后面

以下内容仅供各位用作参考,若有错误之处欢迎指出探讨

一:iReport的大坑

1.1)关于启动闪退问题

原因:

        由于iReport已经停止维护目前只支持到JDK1.7,并且IReport配置文件里相关信息默认都是注掉的,所以就导致iReport会读取你环境变量里配置的JDK,如果环境变量的JDK超过1.7会导致iReport闪退

解决方式:

(1):下载JDK1.7并且安装(安装路径自己定义,保证自己能找到就好, 我的安装地址是D:\jdk7)

(2):打开iReport安装路径找到D:\iReport-4.5.0\etc路径下的ireport.conf文件将  #jdkhome 这条配置项取消注释并且将后面的路径改为自己JDK1.7的安装路径 重启iReport(自己安装JDK1.7重新配置环境变量也可以,但是IDEA和iReport来回切换比较麻烦)

 1.2):关于Detail部分不显示数据

        网上给的相关资料千篇一律都是修改When No Data参数  亲测无效

 原因:

        When No Data参数官方给的描述是当数据源中没有内容时显示什么 , 表面看着没问题 但是参数中提供的四个选项都是不显示

        No pages 不显示页面(默认)

        All Sections,No Detail 只有部分没有细节

        Blank Page 空白页

        No Data Section 不显示数据段

解决方式:

        右键Detail 然后再弹出菜单中选Add Another Detail Band 新增一个Detail模块就行,  避免读取Detail模块时只有一个Detail造成空循环 (不想显示空白的Detail模块 将此模块高度设为0就行)

 

二:java传值至iReport

基本使用都大同小异这里不再赘述,后面着重讲java怎么传值到iReport,以及Table组件如何接收java传来的值

基本使用有不明白的可以参考非常全面的IReport的使用教程_java_脚本之家

 2.1)java传值到iReport

(1):在Fields里定义一个变量,将其定义到文本域中

 (2):java实体类中定义一个相同的变量

 2.2):(重点)java传值给Table组件作为数据源(敲黑板敲黑板敲黑板)

思路:

首先将java数据传入iReport主数据源,即Parameters,  再将获取到的值传入定义好的Table组件的独立数据源中

(1):右键Parameters  添加parameter,  点击新增的参数, 在右侧属性处修改变量名 , 并且设置类型为java.util.list

 (2)从组件面板中拖动一个Table组件到页面中

 表头表脚,列头列脚按自己实际情况选择

 (3):完成后左边菜单栏会生成一个数据源 Table Dataset1 将他重命名为dataOrigin

 (4)在生成的数据源dataOrigin菜单下右键 添加parameter,  点击新增的参数, 在右侧属性处修改变量名为table1 类型为net.sf.jasperreports.engine.JRDataSource (此变量用于接收主数据源中tableData变量的值)

 (5):关联子数据源中table1与主数据源中tableData

方式1:

选中刚才新建的表格 右键选择Edit table detasourct  编辑数据源  将下图蓝色框中的值改为

new net.sf.jasperreports.engine.data.JRBeanCollectionDataSource($P{tableData})

 

 

方式二:

<datasetParameter name="table1">
							<datasetParameterExpression><![CDATA[new net.sf.jasperreports.engine.data.JRBeanCollectionDataSource($P{tableData})]]></datasetParameterExpression>
						</datasetParameter>
						<dataSourceExpression><![CDATA[new net.sf.jasperreports.engine.data.JRBeanCollectionDataSource($P{tableData})]]></dataSourceExpression>

 (6):配置完成后添加需要的Fields值

 (7) 表格中添加文字域及静态文本

(8):编译 

(9):编译后在创建项目时选择的项目路径下复制编译后的文件至java resource文件夹下

 (10):编写java代码并测试

<!-- pdf相关依赖 -->
        <dependency>
            <groupId>net.sf.jasperreports</groupId>
            <artifactId>jasperreports</artifactId>
            <version>5.1.0</version>
            <exclusions>
                <exclusion>
                    <groupId>com.lowagie</groupId>
                    <artifactId>itext</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

        <dependency>
            <groupId>com.itextpdf</groupId>
            <artifactId>itextpdf</artifactId>
            <version>5.5.11</version>
        </dependency>
        <dependency>
            <groupId>com.itextpdf</groupId>
            <artifactId>itext-pdfa</artifactId>
            <version>5.5.11</version>
        </dependency>
        <dependency>
            <groupId>com.itextpdf</groupId>
            <artifactId>itext-asian</artifactId>
            <version>5.2.0</version>
        </dependency>
        <dependency>
            <groupId>com.lowagie</groupId>
            <artifactId>itext</artifactId>
            <version>2.1.7</version>
        </dependency>

        <dependency>
            <groupId>org.codehaus.groovy</groupId>
            <artifactId>groovy-all</artifactId>
            <version>2.4.11</version>
        </dependency>

        <!-- 解决pdf中文字体显示问题 -->
        <dependency>
            <groupId>cn.lesper</groupId>
            <artifactId>iTextAsian</artifactId>
            <version>3.0</version>
        </dependency>
package com.example.demo.demos.pdf.entity;

import lombok.Data;

import java.util.List;

@Data
public class PDF {

    private String test;

    private List<Info> tableData;

    @Data
    public class Info{
        private String name;
        private String age;
    }
}
@RequestMapping("/test")
    public void doReport(HttpServletResponse response) throws UnsupportedEncodingException {
        PDF pdf = new PDF();
        pdf.setTest("test");

        PDF.Info info1 = new PDF().new Info();
        info1.setName("测试1");
        info1.setAge("20");
        PDF.Info info2 = new PDF().new Info();
        info2.setName("测试2");
        info2.setAge("40");
        List dets = new ArrayList();
        dets.add(info1);
        dets.add(info2);
        pdf.setTableData(dets);


        response.setCharacterEncoding("utf-8");
        response.setContentType("application/pdf");
        response.setHeader("content-disposition", "attachment;filename=" + URLEncoder.encode("test", "UTF-8") + ".pdf");

        try (OutputStream outputStream = response.getOutputStream()) {
            //指定jrxml文件
            File file = ResourceUtils.getFile("classpath:pdf/report1.jrxml");
            //编译jrxml
            JasperReport jasperReport = JasperCompileManager.compileReport(file.getPath());
            //转换数据
            Map<String, Object> stringObjectMap = BeanUtil.beanToMap(pdf);
            //报表填充时入参需要一个list
            List<Object> list = new ArrayList<>();
            list.add(stringObjectMap);
            //填充
            JRBeanCollectionDataSource jrBeanCollectionDataSource = new JRBeanCollectionDataSource(list);
            //生成报表   这里用的是传入已生成报表的方式未采用输入流的重载
            JasperPrint jasperPrint = JasperFillManager.fillReport(jasperReport, stringObjectMap, jrBeanCollectionDataSource);
            //响应
            JasperExportManager.exportReportToPdfStream(jasperPrint, response.getOutputStream());
        } catch (IOException | JRException e) {
            e.printStackTrace();
        }

    }

 三:完整项目代码

package com.example.demo.demos.pdf.entity;

import lombok.Data;
import lombok.extern.slf4j.Slf4j;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.List;
import java.util.Map;

@Data
public class PDFBean<T> {
    /**姓名*/
    private String injureName;
    /**年龄*/
    private String injureAge;
    /**性别*/
    private String injureSexName;
    /**电话*/
    private String phone;
    /**医院*/
    private String hospitalName;
    /**科室*/
    private String departmentName;
    /**住院天数*/
    private String hospitalStay;
    /**住院日期*/
    private String inHospitalDate;
    /**预估出院日期*/
    private String leaveHospitalDate;

    /**诊断信息*/
    List<DiagnoseInfo> diagnoseInfo;

    /**治疗方式*/
    private String treatmentWayName;

    /**伤残信息*/
    List<MaimInfo> maimInfo;
    /**其他信息*/
    List<RestsInfo> restsInfo;



    /**内部类 封装单个诊断信息*/
    @Data
    public class DiagnoseInfo{
        /** 诊断代码*/
        private String diagnoseCode;
        /** 诊断名称*/
        private String diagnoseName;
    }

    /**内部类 封装单个伤残信息*/
    @Data
    public class MaimInfo{
        /** ICD10代码*/
        private String icd10Code;
        /** ICD10名称*/
        private String icd10Name;
        /** 伤残编码*/
        private String disabilityPartCode10;
    }

    /** 内部类 其他信息  对应pdf中table3表格中的参数*/
    @Data
    public class RestsInfo{
        private String field1;
    }

    /**
     *
     * @param pdfBean pdf对象
     * @param methodName 方法名
     * @param data 数据源
     * @param <T>
     */
    public static <T> void insertTableInfo(PDFBean pdfBean, String methodName, T... data) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        Class<? extends PDFBean> pdfBeanClass = pdfBean.getClass();
        int num = 1;
        for (T t : data){
            Method getMethod = t.getClass().getMethod("get" + methodName);
            String invoke = (String) getMethod.invoke(t);
            Method steMethod = pdfBeanClass.getMethod("set" + methodName + num, String.class);
            steMethod.invoke(pdfBean, invoke);
            num++;
        }
    }

}
@RequestMapping("/preview")
    public void print(HttpServletResponse response) throws Exception {
        PDFBean data = getMaps();
        response.setCharacterEncoding("utf-8");
        response.setContentType("application/pdf");
        response.setHeader("content-disposition", "attachment;filename=" + URLEncoder.encode("伤残预鉴定报告", "UTF-8") + ".pdf");

        try (OutputStream outputStream = response.getOutputStream()) {
            //指定jrxml文件
            File file = ResourceUtils.getFile("classpath:pdf/invalidismEstimatPDF.jrxml");
            //编译jrxml
            JasperReport jasperReport = JasperCompileManager.compileReport(file.getPath());
            //转换数据
            Map<String, Object> stringObjectMap = BeanUtil.beanToMap(data);
            //报表填充时入参需要一个list
            List<Object> list = new ArrayList<>();
            list.add(stringObjectMap);
            //填充
            JRBeanCollectionDataSource jrBeanCollectionDataSource = new JRBeanCollectionDataSource(list);
            //生成报表   这里用的是传入已生成报表的方式未采用输入流的重载
            JasperPrint jasperPrint = JasperFillManager.fillReport(jasperReport, stringObjectMap, jrBeanCollectionDataSource);
            //响应
            JasperExportManager.exportReportToPdfStream(jasperPrint, response.getOutputStream());
        } catch (IOException | JRException e) {
            e.printStackTrace();
        }
    }
    private PDFBean getMaps() {
        PDFBean pdfBean = new PDFBean();
        //基本信息
        pdfBean.setInjureName("赵铁柱");
        pdfBean.setInjureSexName("男");
        pdfBean.setInjureAge("32");
        pdfBean.setPhone("13666666666");

        //就诊信息
        pdfBean.setHospitalName("北京市第一医院");
        pdfBean.setDepartmentName("外科");
        pdfBean.setHospitalStay("1天");
        pdfBean.setInHospitalDate(new Date()+"");
        pdfBean.setLeaveHospitalDate(new Date()+"");

        //诊断信息
        List<PDFBean.DiagnoseInfo> diagnoseInfo = new ArrayList<>();
        PDFBean.DiagnoseInfo diagnoseInfo1 = new PDFBean().new DiagnoseInfo();
        diagnoseInfo1.setDiagnoseCode("code11");
        diagnoseInfo1.setDiagnoseName("诊断名称11数据长度超出边框长度兼容性测试");
        PDFBean.DiagnoseInfo diagnoseInfo2 = new PDFBean().new DiagnoseInfo();
        diagnoseInfo2.setDiagnoseCode("code22");
        diagnoseInfo2.setDiagnoseName("诊断名称22");
        diagnoseInfo.add(diagnoseInfo1);
        diagnoseInfo.add(diagnoseInfo2);
        pdfBean.setDiagnoseInfo(diagnoseInfo);

        //治疗方式
        pdfBean.setTreatmentWayName("1.建议缝合\n2.建议嗷嗷阿斯顿\n3.建议发啊撒地方\n4.建议爱的方式的广告\n5.建议分的高分\n6.建议更好的发\n7.建议七五七二确认");

        //伤残信息
        List<PDFBean.MaimInfo> maimInfo = new ArrayList<>();
        PDFBean.MaimInfo maimInfo1 = new PDFBean().new MaimInfo();
        maimInfo1.setIcd10Code("ICD10Code1");
        maimInfo1.setIcd10Name("ICD10Name1");
        maimInfo1.setDisabilityPartCode10("伤残编码1数据长度超出边框长度兼容性测试");
        PDFBean.MaimInfo maimInfo2 = new PDFBean().new MaimInfo();
        maimInfo2.setIcd10Code("ICD10Code2");
        maimInfo2.setIcd10Name("ICD10Name2");
        maimInfo2.setDisabilityPartCode10("伤残编码2");
        maimInfo.add(maimInfo1);
        maimInfo.add(maimInfo2);
        pdfBean.setMaimInfo(maimInfo);

        //其他信息
        List<PDFBean.RestsInfo> restsInfo = new ArrayList<>();
        PDFBean.RestsInfo restsInfo1 = new PDFBean().new RestsInfo();
        restsInfo1.setField1("测试数据1");
        restsInfo.add(restsInfo1);
        pdfBean.setRestsInfo(restsInfo);

        return pdfBean;
    }

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值