Ireport报表导出PDF Word Excel HTML格式
时间:2026-08-05 | 作者:冻月看渠 | 阅读:0JasperReports + POI 通用报表导出工具类
日常开发中,报表导出是高频需求。PDF、Word、Excel、HTML,每种格式都有对应的处理方式。如果单独为每种格式写一套逻辑,代码量会迅速膨胀,维护起来也麻烦。
这里提供一个基于 JasperReports 和 POI 的通用工具类。核心思路是:通过一个统一的入口方法,根据传入的类型参数自动路由到对应的导出逻辑,从而把重复的配置工作封装起来。
工具类核心代码
下面直接上代码。工具类 JasperUtils 包含了所有导出格式的实现。使用时只需调用 exportmain 方法,传入格式类型、jasper 模板文件名、数据列表以及导出文件名称即可。
注意:exportmain 有两个重载版本:一个支持分页导出(指定页码),另一个默认导出全部数据。
import ja va.io.File;
import ja va.io.FileInputStream;
import ja va.io.FileNotFoundException;
import ja va.io.IOException;
import ja va.io.InputStream;
import ja va.lang.reflect.Field;
import ja va.util.Collection;
import ja va.util.HashMap;
import ja va.util.List;
import ja va.util.Map;
import ja vax.servlet.ServletOutputStream;
import ja vax.servlet.http.HttpServletRequest;
import ja vax.servlet.http.HttpServletResponse;
import net.sf.jasperreports.engine.JRDataSource;
import net.sf.jasperreports.engine.JRException;
import net.sf.jasperreports.engine.JRExporter;
import net.sf.jasperreports.engine.JRExporterParameter;
import net.sf.jasperreports.engine.JasperExportManager;
import net.sf.jasperreports.engine.JasperFillManager;
import net.sf.jasperreports.engine.JasperPrint;
import net.sf.jasperreports.engine.JasperReport;
import net.sf.jasperreports.engine.base.JRBaseReport;
import net.sf.jasperreports.engine.data.JRBeanCollectionDataSource;
import net.sf.jasperreports.engine.export.JRHtmlExporter;
import net.sf.jasperreports.engine.export.JRHtmlExporterParameter;
import net.sf.jasperreports.engine.export.JRRtfExporter;
import net.sf.jasperreports.engine.export.JRXlsExporter;
import net.sf.jasperreports.engine.export.JRXlsExporterParameter;
import net.sf.jasperreports.engine.util.JRLoader;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.apache.struts2.ServletActionContext;
import com.opensymphony.xwork2.ActionContext;
@SuppressWarnings("unchecked")
public class JasperUtils {
private static Logger logger = Logger.getLogger(JasperUtils.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 {
logger.debug("执行导出excel The method======= exportExcel() start.......................");
/*
* 设置头信息
*/
response.setContentType("application/vnd.ms-excel");
String defaultname = null;
if (defaultFilename.trim() != null && defaultFilename != null) {
defaultname = defaultFilename + ".xls";
} else {
defaultname = "export.xls";
}
String fileName = new String(defaultname.getBytes("gbk"), "utf-8");
response.setHeader("Content-disposition", "attachment; filename=" + fileName);
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);
exporter.setParameter(JRXlsExporterParameter.IS_WHITE_PAGE_BACKGROUND, Boolean.FALSE);
exporter.exportReport();
ouputStream.flush();
ouputStream.close();
}
/**
* 导出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"), "utf-8");
response.setHeader("Content-disposition", "attachment; filename=" + fileName);
ServletOutputStream ouputStream = response.getOutputStream();
JasperExportManager.exportReportToPdfStream(jasperPrint, ouputStream);
ouputStream.flush();
ouputStream.close();
}
/**
* 导出html
*
* @param pageIndexStr
*/
private static void exportHtml(JasperPrint jasperPrint,
String defaultFilename, HttpServletRequest request,
HttpServletResponse response, String pageIndexStr)
throws IOException, JRException {
response.setContentType("text/html");
ServletOutputStream ouputStream = response.getOutputStream();
JRHtmlExporter exporter = new JRHtmlExporter();
// 得到当前页码
Integer pageIndex = getPageIndex(jasperPrint, request, pageIndexStr);
// 如果页码不为空 则设置分页页码
if (pageIndex != null) {
exporter.setParameter(JRExporterParameter.PAGE_INDEX, pageIndex);
}
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();
}
/**
*
* description:通过传进来的pageIndexStr 得到当前页码
* Date 2013-1-18 上午10:49:38
*
* @param @param jasperPrint
* @param @param request
* @param @param pageIndexStr
* @param @return
* @return Integer
*/
private static Integer getPageIndex(JasperPrint jasperPrint,
HttpServletRequest request, String pageIndexStr) {
// 如果pageIndexStr为空或空字符串则返回null
if (pageIndexStr == null || StringUtils.isBlank(pageIndexStr)) {
return null;
}
Integer pageIndex = 0;
int lastPageIndex = 0;
// 得到最后一页的 页码
if (jasperPrint.getPages() != null) {
lastPageIndex = jasperPrint.getPages().size() - 1;
}
// 如果字符串==lastPage 则反lastPageIndex的值赋给pageIndex 并返回pageIndex
if ("lastPage".equals(pageIndexStr)) {
pageIndex = lastPageIndex;
return pageIndex;
}
try {
pageIndex = Integer.parseInt(pageIndexStr);
// 从ireport 传来的PageIndex是从1开始,而JRExporterParameter.PAGE_INDEX是从0开始的
if (pageIndex > 0) {
pageIndex = pageIndex - 1;
}
} catch (Exception e) {
e.printStackTrace();
}
if (pageIndex < 0) {
pageIndex = 0;
}
if (pageIndex > lastPageIndex) {
pageIndex = lastPageIndex;
}
return pageIndex;
}
/**
* 导出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
* 默认的导出文件的名称
*/
private static void export(Collection datas, String type,
String defaultFilename, InputStream is, HttpServletRequest request,
HttpServletResponse response, String pageIndexStr) {
logger.debug("导出判断 The method======= export() start.......................");
try {
logger.info("is==" + is);
JasperReport jasperReport = (JasperReport) JRLoader.loadObject(is);
prepareReport(jasperReport, type);
JRDataSource ds = new JRBeanCollectionDataSource(datas, false);
Map parameters = new HashMap();
JasperPrint jasperPrint = JasperFillManager.fillReport(jasperReport, parameters, ds);
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, pageIndexStr);
} else if (WORD_TYPE.equals(type)) {
exportWord(jasperPrint, defaultFilename, request, response);
}
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 导出入口 (导出所有的数据 )
*
* @param exportType
* 导出文件的类型
* @param jaspername
* jasper文件的名字 如: xx.jasper
* @param lists
* 导出的数据
* @param request
* @param response
* @param defaultFilename
* 默认的导出文件的名称
*/
public static void exportmain(String exportType, String jaspername,
List lists, String defaultFilename) {
exportmain(exportType, jaspername, lists, defaultFilename, null);
}
/**
* 导出入口 (分页显示 导出传入的pageIndex 页的数据)
*
* @param exportType
* 导出文件的类型
* @param jaspername
* jasper文件的名字 如: xx.jasper
* @param lists
* 导出的数据
* @param request
* @param response
* @param defaultFilename
* 默认的导出文件的名称
* @param pageIndex
* 需要导出数据的页码 当pageIndex = null时导出所有数据
*/
@SuppressWarnings("deprecation")
public static void exportmain(String exportType, String jaspername,
List lists, String defaultFilename, String pageIndexStr) {
logger.debug("进入导出The method======= exportmain() start.......................");
ActionContext ct = ActionContext.getContext();
HttpServletRequest request = (HttpServletRequest) ct.get(ServletActionContext.HTTP_REQUEST);
HttpServletResponse response = ServletActionContext.getResponse();
String filenurl = request.getRealPath("/view/situation/jasper/" + jaspername);
File file = new File(filenurl);
InputStream is = null;
try {
is = new FileInputStream(file);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
export(lists, exportType, defaultFilename, is, request, response, pageIndexStr);
}
}
PDF 中文导出配置
关于导出 PDF 时中文显示的问题,这里补充说明。主要靠 JasperReports 的字体设置:
- 在 iReport 的 classpath 中加入
iTextAsian.jar - 在字段属性中,将
pdf font name设为STSong-Light - 将
pdf encoding设为UniGB-UCS2-H
这样中文就能正常渲染了。
Excel 导出优化
Excel 导出时,工具类会自动移除页边距,并设置为一页一张 sheet 的紧凑模式。
HTML 分页导出
HTML 导出支持分页,可以通过传入页码参数来控制输出哪一页。
整体设计思路
整体思路是围绕 JasperPrint 对象,根据不同的格式选择不同的 JRExporter 实现,再加上 HTTP 响应头的设置,就可以在 Web 应用中直接提供文件下载。
代码中已经做了 prepareReport 的预处理。例如 Excel 模式下去掉 margin,避免导出后出现多余空白。
使用方法
使用的时候,从 exportmain 方法传入参数即可。它内部会读取指定的 .jasper 模板文件,填充数据,最后调用对应的导出方法。
如果需要分页导出,只需在 pageIndexStr 参数里传页码字符串(支持 "lastPage" 表示最后一页),非常方便。
免责声明:文中图文均来自网络,如有侵权请联系删除,心愿游戏发布此文仅为传递信息,不代表心愿游戏认同其观点或证实其描述。
相关文章
更多-
- MiniWord:一款适合 .NET 项目的免费开源 Word 模板库
- 时间:2026-08-25
-
- C# 如何从 URL 下载 Word 文档:用 Spire.Doc 打通下载与处理链路
- 时间:2026-08-24
-
- Word首页页眉删除方法详解
- 时间:2026-08-23
-
- Word 2019开发工具选项卡添加步骤详解
- 时间:2026-08-23
-
- Word文档插入代数几何图形操作指南
- 时间:2026-08-23
-
- Word文档底图设置与删除方法详解
- 时间:2026-08-23
-
- Word文档如何统一页面大小与连接上下页
- 时间:2026-08-23
-
- Word页码连续数字及奇偶页不同位置设置技巧
- 时间:2026-08-23
精选合集
更多大家都在玩
大家都在看
更多-
- 糖尿病完全不能吃糖吗
- 时间:2026-09-15
-
- 蚂蚁庄园小课堂2026年9月16日最新题目答案
- 时间:2026-09-15
-
- 小鸡答题今天的答案是什么2026年9月16日
- 时间:2026-09-15
-
- 蚂蚁庄园每日答题答案2026年9月16日
- 时间:2026-09-15
-
- 以下哪种粮食是酿造绍兴黄酒的主要原料 蚂蚁庄园今日答案9月16日
- 时间:2026-09-15
-
- 劝学名句“及时当勉励,岁月不待人”出自哪位诗人 蚂蚁庄园今日答案9.16
- 时间:2026-09-15
-
- 蚂蚁庄园今天答题答案2026年9月16日
- 时间:2026-09-15
-
- 蚂蚁庄园答题今日答案2026年9月16日
- 时间:2026-09-15
