web导出pdf(可以在本地生成)
package com.sinosig.sl.slcc.base.utils;
import java.io.OutputStream;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletResponse;
import net.sf.jasperreports.engine.JRDataSource;
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;
public class PDFUtil {
private static String jrxmlSourcePath = "C:/Users/Administrator.MICROSOFT/Desktop/report3.jrxml";
private static String jasperFilePath = "C:/Users/Administrator.MICROSOFT/Desktop/report1.jasper";
public static void exportPDF(HttpServletResponse response,Map<String,Object> parameterMap ,List<Object> list) throws Exception{
// String classpath=PDFUtil.class.getResource("/").toString().substring(6);
// String jrxmlSourcePath=classpath+"report3.jrxml";
// String jasperFilePath=classpath+"report3.jasper";
// 将jrxml编译生成a.jasper
JasperCompileManager.compileReportToFile(jrxmlSourcePath, jasperFilePath);
//配置入参
List<Object> listInfo = Arrays.asList(list.toArray());
JRDataSource datasource= new JRBeanCollectionDataSource(listInfo);
//重点就是这个方法三个参数
//第一个jasperFilePath是jasper文件的路径
//第二个参数parameterMap是一个map 这个map主要是放的对象里面的其他对象比如list等
//第三个参数主要是最外层的对象的list的转换成的JRDataSource 下面进行详细讲解
JasperPrint jasperPrint = JasperFillManager.fillReport(jasperFilePath, parameterMap,datasource);
// ByteArrayOutputStream baos = new ByteArrayOutputStream();
OutputStream os=response.getOutputStream();
// 如果是web导出的话这段代码直接复制 如果是pdf本地生成的话就把response 的os换成baos
JasperExportManager.exportReportToPdfStream(jasperPrint,os);
// byte[] bytes = baos.toByteArray();
// // 4.确定写出文件的位置
// File file = new File("C:/Users/Administrator.MICROSOFT/Desktop/report1.pdf");
// FileOutputStream fos = new FileOutputStream(file);
// fos.write(bytes);
// fos.flush();
// fos.close();
// System.out.println("----------------over--------------");
}
}
这个东西重点就是三个参数和irepor生成模板的对应关系
JasperPrint jasperPrint = JasperFillManager.fillReport(jasperFilePath, parameterMap,datasource);
上面这个方法是要参数的入口 主要说后面两个参数
在说参数之前我先说一个javabean
学生类
public class Student {
private String stuNo;
private String stuSex;
private String stuName;
private String stuAge;
}
班级类
public class StuClass {
private String ClsName;
private String ClsNo;
private List<Student> students;
}
班级类中有个学生的list
以上只是一个例子
我们把班级类当做最外层 那么之前说的第三个参数datasource 就是这样写
List<Object> list =new ArrayList<Object>();
StuClass stuclass=new StuClass();
/**
*各种set值
*/
list.add(stuclass);
把list传到pdfUtils中
然后看代码可以知道
List<Object> listInfo = Arrays.asList(list.toArray());
JRDataSource datasource= new JRBeanCollectionDataSource(listInfo);
至此datasource就是第三个参数 这个第三个参数是ireport中的detail块的循环假设 ireport中detail1放了一个参数clsName 而第三个参数的list里面有两个对象那么detail1会循环两次
下面说第二个参数
map里面放的students的list代码如下
List<Student> list =new ArrayList<Student>();
Student student=new Student();
list.add(student);
JRDataSource data= new JRBeanCollectionDataSource(list);
parameterMap.put("stuInfo", data);
将这个参数传进pdfUtils 这就是第二个参数 这个参数对应ireport中的list组件 list组件会根据他来循环。
最后说ireport中的操作
ireport的每个list都要配置数据源 就以上要获取班级类中的学生list的话需要这样设置数据源
sub dataset 是将student这个javabean设置为javabbean的
get(“stuInfo”)就是map中的put的值
主要想讲的是 外层对象放到第三个参数 通过ireport的detail来循环
外层对象中的list或者对象 放到第二个参数 通过ireport中的list组件来循环 并且他的list需要设置数据源 以javabean设置为数据源
注意:
ireport如果用javabean作为数据源 需要将实体类的calss文件添加到ireport里面
如果windows可以但是linux出现了换行吃字的问题 最终的我的解决办法是安装字体在linux上 当时搞了三天
对于导出的pdf要有水印 的话 有个bind叫background 里面放上图片就好了。
但是一般不写绝对路径 写相对路径 方法是把图片的 image expression属性写成java传来的值
1.首先在ireport中添加一个Paramater 我这里取名为logoPath如图
2.将image的image expression属性写成$P{logoPath}
3.通过代码传进参数