在本文中我将JasperReport应用于某业务管理系统(WEB)的综合查询页面中,用于报表展示以及PDF和EXCEL文件的导出。
使用效果如下:
在项目中使用之前,需要限制做好jasper模板。比较方便的做法是使用ireport制作模板。
ireport界面如下,我们可以新建一个A4空白页面,或者使用ireport中准备好的模板。
class bean{
private String col1;
private Integer col2;
// getter, setter 略
}
在Fields中就得有对应的col1
, col2
而且数据类型也得一一对应比较好,不然可能出现转换错误。
4、需要结合动态数据的地方使用Text Field。并且编辑Field的表达式(在这里可以指定显示Filed还是Variable)。
5、点击Compile或者预览,就能生成.jasper文件啦。
制作报表肯定不能只列举每个商品的销售清单,如果要统计每个商户的销售情况,就得按照商户分组合计。有点类似SELECT SUM(XXX) FROM REPORT GROUP BY COMPANY
这样的效果。
流程如下:
1、在设置好Fields后,右键单击报表,选择Add Report Group。
在这里命名好分组名,选择GroupBy 的字段即可。
* 多字段分组,使用下面的expression。可以填写$F{fields1}+$F{fields2}
这样。
2、声明汇总字段
新建Variable
Calculation设置为Sum,选择相应的Group
VariableExpression 中选择需要计算的Field
在需要展示的Text Fields中设置表达式为该Variable即可。
~~~~不太会。不过主要用于实现类似EXCEL的纵向合并单元格。
ireport保存的模板文件后缀为jrxml。而jasper使用的模板文件后缀为jasper。jasper文件可以从ireport的编译结果中得到。这里可以在’工具 - 选项 - Compilation and excution’ 中,将 Compilation directory 指定到你想保存jasper文件的地方,这样在编译后,编译结果就能方便的拿到了。
截图如下:
<dependency>
<groupId>net.sf.jasperreportsgroupId>
<artifactId>jasperreportsartifactId>
<version>4.1.3version>
dependency>
同时再引入中文字体包iText, iText-Asia。
注意:在WEB-INF/classes中建立一个jasperreports.properties 中加入一条: net.sf.jasperreports.awt.ignore.missing.font=true
这样在中文字体找不到的时候可以自动调用默认字体而不是直接报错。
将.jasper文件放在web资源路径下。
在java代码中查询出数据列表List
将其填充到数据源中,然后套用模板即可。jasper的报表数据可以有好几种形式,这里只写通过HttpResponse输出的方法(HTML,PDF,EXCEL)。
java代码如下:
@RequestMapping(value = "/queryIncomeSumServlet", method = RequestMethod.POST)
public void queryIncomeSumHtml(HttpServletRequest request,
HttpServletResponse response) throws IOException {
//STEP 1 : 查询数据
List beans = myService.getData();
//STEP 2 : 指定数据源
JRDataSource datasource = new JRBeanCollectionDataSource(sales);
//STEP 3 : 指定模板文件
ServletContext context = request.getSession().getServletContext();
File reportFile = null;
reportFile = new File(context.getRealPath("/resources/jasperform/income_report.jasper"));
String exportFilePath = "tempPath";
/* STEP 4 : 输出报表
*不同输出方式,具体实现在后边注释*/
/*使用HTML输出,表现为页面直接显示报表*/
JasperHelper.showHtml(exportFilePath , reportFile.getPath(), request,
response, new HashMap(), datasource);
/*使用PDF输出,表现为出现PDF文件的下载对话框*/
JasperHelper.export("pdf", fileName, reportFile, request,
response, new HashMap(), datasource);
/*使用EXCEL输出,表现为出现EXCEL文件的下载对话框*/
JasperHelper.export("excel", fileName, reportFile, request,
response, new HashMap(), datasource);
}
执行错误的异常处理:
/*异常处理*/
/*
* 因为是使用response输出,所以程序异常就中断执行的话,输出的窗口就是空白的,这样用户也不知道是执行未完成还是没结果还是异常。所以怎么说最终输出都该有点东西。。。。这里就直接在response中print了。
* 该处理方法适用于HTML,PDF,EXCEL三种输出。效果均相同。
*/
try{
foo();
} catch(Exception e){
response.getWriter().println("执行错误");
response.getWriter().println("错误信息"+e.getMessage());
return
}
代码项目里就有。不知是哪位大神写的。
public class JasperHelper {
private static Logger logger = Logger.getLogger(JasperHelper.class);
public static final String PRINT_TYPE = "print";
public static final String PDF_TYPE = "pdf";
public static final String EXCEL_TYPE = "excel";
public static final String HTML_TYPE = "html";
public static final String WORD_TYPE = "word";
public static void prepareReport(JasperReport jasperReport, String type) {
logger.debug("The method======= prepareReport() start.......................");
/*
* 如果导出的是excel,则需要去掉周围的margin
*/
if ("excel".equals(type))
try {
Field margin = JRBaseReport.class
.getDeclaredField("leftMargin");
margin.setAccessible(true);
margin.setInt(jasperReport, 0);
margin = JRBaseReport.class.getDeclaredField("topMargin");
margin.setAccessible(true);
margin.setInt(jasperReport, 0);
margin = JRBaseReport.class.getDeclaredField("bottomMargin");
margin.setAccessible(true);
margin.setInt(jasperReport, 0);
Field pageHeight = JRBaseReport.class
.getDeclaredField("pageHeight");
pageHeight.setAccessible(true);
pageHeight.setInt(jasperReport, 2147483647);
} catch (Exception exception) {
}
}
/**
* 导出excel
*/
public static void exportExcel(JasperPrint jasperPrint,
String defaultFilename, HttpServletRequest request,
HttpServletResponse response) throws IOException, JRException {
/*
* 设置头信息
*/
response.setContentType("application/vnd.ms-excel");
String defaultname = null;
if (defaultFilename.trim() != null && defaultFilename != null) {
defaultname = defaultFilename + ".xls";
} else {
defaultname = "export.xls";
}
response.setHeader("Content-Disposition", "attachment; filename=\""
+ URLEncoder.encode(defaultname, "UTF-8") + "\"");
ServletOutputStream ouputStream = response.getOutputStream();
JRXlsExporter exporter = new JRXlsExporter();
exporter.setParameter(JRExporterParameter.JASPER_PRINT, jasperPrint);
exporter.setParameter(JRExporterParameter.OUTPUT_STREAM, ouputStream);
exporter.setParameter(
JRXlsExporterParameter.IS_REMOVE_EMPTY_SPACE_BETWEEN_ROWS,
Boolean.TRUE); // 删除记录最下面的空行
exporter.setParameter(JRXlsExporterParameter.IS_ONE_PAGE_PER_SHEET,
Boolean.FALSE);// 删除多余的ColumnHeader
//
exporter.setParameter(JRXlsExporterParameter.IS_WHITE_PAGE_BACKGROUND,
Boolean.FALSE);// 显示边框
exporter.exportReport();
ouputStream.flush();
ouputStream.close();
}
public static enum DocType {
PDF, HTML, XLS, XML, RTF
}
public static JRAbstractExporter getJRExporter(DocType docType) {
JRAbstractExporter exporter = null;
switch (docType) {
case PDF:
exporter = new JRPdfExporter();
break;
case HTML:
exporter = new JRHtmlExporter();
break;
case XLS:
exporter = new JExcelApiExporter();
break;
case XML:
exporter = new JRXmlExporter();
break;
case RTF:
exporter = new JRRtfExporter();
break;
}
return exporter;
}
/**
* 导出pdf,注意此处中文问题,
*
* 这里应该详细说:主要在ireport里变下就行了。看图
*
* 1)在ireport的classpath中加入iTextAsian.jar 2)在ireport画jrxml时,看ireport最左边有个属性栏。
*
* 下边的设置就在点字段的属性后出现。 pdf font name :STSong-Light ,pdf encoding :UniGB-UCS2-H
*/
private static void exportPdf(JasperPrint jasperPrint,
String defaultFilename, HttpServletRequest request,
HttpServletResponse response) throws IOException, JRException {
response.setContentType("application/pdf");
String defaultname = null;
if (defaultFilename.trim() != null && defaultFilename != null) {
defaultname = defaultFilename + ".pdf";
} else {
defaultname = "export.pdf";
}
String fileName = new String(defaultname.getBytes("GBK"), "ISO8859_1");
response.setHeader("Content-disposition", "attachment; filename="
+ fileName);
ServletOutputStream ouputStream = response.getOutputStream();
JasperExportManager.exportReportToPdfStream(jasperPrint, ouputStream);
ouputStream.flush();
ouputStream.close();
}
/**
* 导出html
*/
private static void exportHtml(JasperPrint jasperPrint,
String defaultFilename, HttpServletRequest request,
HttpServletResponse response) throws IOException, JRException {
response.setContentType("text/html");
ServletOutputStream ouputStream = response.getOutputStream();
JRHtmlExporter exporter = new JRHtmlExporter();
exporter.setParameter(JRHtmlExporterParameter.IS_USING_IMAGES_TO_ALIGN,
Boolean.FALSE);
exporter.setParameter(JRExporterParameter.JASPER_PRINT, jasperPrint);
exporter.setParameter(JRExporterParameter.CHARACTER_ENCODING, "UTF-8");
exporter.setParameter(JRExporterParameter.OUTPUT_STREAM, ouputStream);
exporter.exportReport();
ouputStream.flush();
ouputStream.close();
}
/**
* 导出word
*/
private static void exportWord(JasperPrint jasperPrint,
String defaultFilename, HttpServletRequest request,
HttpServletResponse response) throws JRException, IOException {
response.setContentType("application/msword;charset=utf-8");
String defaultname = null;
if (defaultFilename.trim() != null && defaultFilename != null) {
defaultname = defaultFilename + ".doc";
} else {
defaultname = "export.doc";
}
String fileName = new String(defaultname.getBytes("GBK"), "utf-8");
response.setHeader("Content-disposition", "attachment; filename="
+ fileName);
JRExporter exporter = new JRRtfExporter();
exporter.setParameter(JRExporterParameter.JASPER_PRINT, jasperPrint);
exporter.setParameter(JRExporterParameter.OUTPUT_STREAM,
response.getOutputStream());
exporter.exportReport();
}
/**
* 按照类型导出不同格式文件
*
* @param datas
* 数据
* @param type
* 文件类型
* @param is
* jasper文件的来源
* @param request
* @param response
* @param defaultFilename默认的导出文件的名称
*/
public static void export(String type, String defaultFilename, File is,
HttpServletRequest request, HttpServletResponse response,
Map parameters, Connection conn) {
try {
JasperReport jasperReport = (JasperReport) JRLoader.loadObject(is);
prepareReport(jasperReport, type);
JasperPrint jasperPrint = JasperFillManager.fillReport(
jasperReport, parameters, conn);
if (EXCEL_TYPE.equals(type)) {
exportExcel(jasperPrint, defaultFilename, request, response);
} else if (PDF_TYPE.equals(type)) {
exportPdf(jasperPrint, defaultFilename, request, response);
} else if (HTML_TYPE.equals(type)) {
exportHtml(jasperPrint, defaultFilename, request, response);
} else if (WORD_TYPE.equals(type)) {
exportWord(jasperPrint, defaultFilename, request, response);
}
} catch (Exception e) {
e.printStackTrace();
}
}
public static void export(String type, String defaultFilename, File is,
HttpServletRequest request, HttpServletResponse response,
Map parameters, JRDataSource conn) {
try {
JasperReport jasperReport = (JasperReport) JRLoader.loadObject(is);
prepareReport(jasperReport, type);
JasperPrint jasperPrint = JasperFillManager.fillReport(
jasperReport, parameters, conn);
if (EXCEL_TYPE.equals(type)) {
exportExcel(jasperPrint, defaultFilename, request, response);
} else if (PDF_TYPE.equals(type)) {
exportPdf(jasperPrint, defaultFilename, request, response);
} else if (HTML_TYPE.equals(type)) {
exportHtml(jasperPrint, defaultFilename, request, response);
} else if (WORD_TYPE.equals(type)) {
exportWord(jasperPrint, defaultFilename, request, response);
}
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 输出html静态页面,必须注入request和response
*
* @param jasperPath
* @param params
* @param sourceList
* @param imageUrl
* 报表文件使用的图片路径,比如 ../servlets/image?image=
* @throws JRException
* @throws IOException
* @throws ServletException
*/
public static void showHtml(String defaultFilename, String reportfile,
HttpServletRequest request, HttpServletResponse response, Map parameters,
JRDataSource conn) throws JRException, IOException {
request.setCharacterEncoding("utf-8");
response.setCharacterEncoding("utf-8");
response.setContentType("text/html");
JRAbstractExporter exporter = getJRExporter(DocType.HTML);
JasperPrint jasperPrint = JasperFillManager.fillReport(reportfile,
parameters, conn);
request.getSession().setAttribute(
ImageServlet.DEFAULT_JASPER_PRINT_SESSION_ATTRIBUTE,
jasperPrint);
PrintWriter out = response.getWriter();
exporter.setParameter(JRExporterParameter.JASPER_PRINT, jasperPrint);
exporter.setParameter(JRExporterParameter.OUTPUT_WRITER, out);
exporter.setParameter(
JRHtmlExporterParameter.IS_USING_IMAGES_TO_ALIGN,
Boolean.FALSE);
exporter.exportReport();
out.flush();
}
public static void showHtml(String defaultFilename, String reportfile,
HttpServletRequest request, HttpServletResponse response, Map parameters,
Connection conn) throws JRException, IOException {
request.setCharacterEncoding("utf-8");
response.setCharacterEncoding("utf-8");
response.setContentType("text/html");
JRAbstractExporter exporter = getJRExporter(DocType.HTML);
JasperPrint jasperPrint = JasperFillManager.fillReport(reportfile,
parameters, conn);
request.getSession().setAttribute(
ImageServlet.DEFAULT_JASPER_PRINT_SESSION_ATTRIBUTE,
jasperPrint);
PrintWriter out = response.getWriter();
exporter.setParameter(JRExporterParameter.JASPER_PRINT, jasperPrint);
exporter.setParameter(JRExporterParameter.OUTPUT_WRITER, out);
exporter.setParameter(
JRHtmlExporterParameter.IS_USING_IMAGES_TO_ALIGN,
Boolean.FALSE);
exporter.exportReport();
out.flush();
}
public static void showPdf(String defaultFilename, String reportfile,
HttpServletRequest request, HttpServletResponse response, Map parameters,
Connection conn) throws JRException, IOException {
request.setCharacterEncoding("utf-8");
response.setCharacterEncoding("utf-8");
response.setContentType("text/html");
response.setContentType("application/pdf");
JRAbstractExporter exporter = getJRExporter(DocType.PDF);
JasperPrint jasperPrint = JasperFillManager.fillReport(reportfile,
parameters, conn);
request.getSession().setAttribute(
ImageServlet.DEFAULT_JASPER_PRINT_SESSION_ATTRIBUTE,
jasperPrint);
PrintWriter out = response.getWriter();
exporter.setParameter(JRExporterParameter.JASPER_PRINT, jasperPrint);
exporter.setParameter(JRExporterParameter.OUTPUT_WRITER, out);
exporter.exportReport();
out.flush();
}
}