最近做项目需要用到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;
}
今天的文章星耀单排怎么这么坑_星耀单排怎么这么坑分享到此就结束了,感谢您的阅读。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/82877.html