与SpringMVC整合,整了两天,终于可以了。
参考资源:资源已上传,等审核过就可以参考下
关键问题记录下:
1: 依赖jar包
有些jar包在maven仓库还找不到,最后还是放到自己仓库里面。apache poi的包没导入,poi这个包主要是导出xls的格式有用到,但发现我导入之后,会报方法找不到,
最后解决方案是:如果导出的是xls格式的,都用xlsx了去处理,只有在最后写给浏览器是把文件后缀换为xls。
2:主要用到的几个工具类
=================controller调用方法================
@Autowired
private DataSource dataSource;
@RequestMapping("download")
@RequiresPermissions("sys:user:download")
public void download(HttpServletRequest request,HttpServletResponse response){
try {
//获取查询条件参数
Map
EntityWrapper
if(StringUtils.isNotBlank(ew.getSqlSegment())){
sqlParams.put("conditions",ew.getSqlSegment());
}
//获取下载参数
Map
//文件路径
String filePath=getJasperFilePath(request, reqMap.get("filePath"));
//是否下载
Boolean download=reqMap.get("download")!=null?Boolean.valueOf(String.valueOf(reqMap.get("download"))):true;
//报表类型
String type=String.valueOf(reqMap.get("type"));
//下载后的文件名
String downloadName=String.valueOf(reqMap.get("downloadName"));
//下载
ReportWebUtils.export(request, response, filePath, downloadName, type, download, sqlParams, dataSource);
} catch (Exception e) {
e.printStackTrace();
rendStr(response,"报表打印错误");
logger.error(Exceptions.getStackTraceAsString(e));
}
}
=========================================ReportWebUtils ======================
package com.mould.common.web;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.net.URLEncoder;
import java.sql.Connection;
import java.util.Map;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.sql.DataSource;
import org.springframework.jdbc.datasource.DataSourceUtils;
import com.mould.common.entity.ReportFileType;
import com.mould.common.utils.ReportUtils;
import com.mould.common.utils.StringUtils;
import net.sf.jasperreports.engine.JRException;
import net.sf.jasperreports.engine.JasperFillManager;
import net.sf.jasperreports.engine.JasperPrint;
/**
*
* @Description:jasperreports工具类
* @author linwp
* @time:2017年3月24日 下午9:57:45
*
*/
public class ReportWebUtils {
/**
* 导出报表
* @param request
* @param response
* @param filePath 文件路径名
* @param downFileName 下载的文件名
* @param type 格式 xls,xlsx,pdf,docx,html,xml,rtf
* @param isDownLoad 是否下载 true:下载 false:直接在浏览器打开
* @param params 参数
* @param dataSource 数据源
* @throws IOException
* @throws JRException
*/
public static void export(HttpServletRequest request,HttpServletResponse response, String filePath, String downFileName, String type,
Boolean isDownLoad, Map
Connection conn = DataSourceUtils.getConnection(dataSource);
try {
if (conn != null) {
JasperPrint jasperPrint = JasperFillManager.fillReport(filePath, params, conn);
DataSourceUtils.releaseConnection(conn, dataSource);
ReportFileType reportFileType = ReportWebUtils.getType(type);
ReportWebUtils.dealResponse(request,response, jasperPrint, downFileName, reportFileType, isDownLoad);
}
}finally {
if (conn != null) {
DataSourceUtils.releaseConnection(conn, dataSource);
}
}
}
/**
* 把报表处理后返回给浏览器
* @param response
* @param request
* @param jasperPrint 报表
* @param fileName 打开的文件名
* @param reportType 报表类型
* @param isDownLoad 是否下载
* @throws IOException
* @throws JRException
*/
public static void dealResponse(HttpServletRequest request,HttpServletResponse response, JasperPrint jasperPrint, String fileName,
ReportFileType reportType, Boolean isDownLoad) throws IOException, JRException {
ServletOutputStream sos = null;
try {
byte[] bytes = ReportWebUtils.getFileBytes(jasperPrint, reportType);
if ((bytes != null) && (bytes.length > 0)) {
String userAgent = request.getHeader("User-Agent");
boolean isIE = (userAgent != null) && (userAgent.toLowerCase().indexOf("msie") != -1);
response.reset();
response.setCharacterEncoding("UTF-8");
response.setContentType(reportType.getContentType());
response.setContentLength(bytes.length);
if (isIE) {
fileName = URLEncoder.encode(fileName, "UTF-8");
} else {
fileName = new String(fileName.getBytes("UTF-8"), "ISO8859-1");
}
response.setHeader("Content-Disposition", "inline;filename=" + fileName + "." + reportType.getExtension());
if (isDownLoad.booleanValue()) {
response.setHeader("Content-Disposition",
"attachment;filename=" + fileName + "." + reportType.getExtension());
}
sos = response.getOutputStream();
sos.write(bytes, 0, bytes.length);
sos.flush();
sos.close();
}
}finally {
if (sos != null) {
try {
sos.close();
} catch (IOException e) {
return ;
}
}
}
}
/**
* 根据字符串类型查找对应的ReportFileType
*
* @param type
* @return ReportFileType
*/
public static ReportFileType getType(String type) {
// 如果类型为空,返回pdf
if (StringUtils.isEmpty(type)) {
return ReportFileType.PDF;
}
// 匹配类型
if (type.toUpperCase().equals(ReportFileType.DOCX.getName())) {
return ReportFileType.DOCX;
} else if (type.toUpperCase().equals(ReportFileType.HTML.getName())) {
return ReportFileType.HTML;
} else if (type.toUpperCase().equals(ReportFileType.PDF.getName())) {
return ReportFileType.PDF;
} else if (type.toUpperCase().equals(ReportFileType.RTF.getName())) {
return ReportFileType.RTF;
} else if (type.toUpperCase().equals(ReportFileType.XLS.getName())) {
return ReportFileType.XLS;
} else if (type.toUpperCase().equals(ReportFileType.XLSX.getName())) {
return ReportFileType.XLSX;
} else if (type.toUpperCase().equals(ReportFileType.XML.getName())) {
return ReportFileType.XML;
}
// 如果都不匹配 返回PDF类型的
return ReportFileType.PDF;
}
/**
* 根据不同的ReportFileType 读取 JasperPrint 返回字节
*
* @param jasperPrint
* @param type
* ReportFileType类型
* @return
* @throws JRException
*/
public static byte[] getFileBytes(JasperPrint jasperPrint, ReportFileType type) throws JRException {
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
if (type.compareTo(ReportFileType.DOCX) == 0) {
ReportUtils.exportReportToDocxStream(jasperPrint, outputStream);
} else if (type.compareTo(ReportFileType.HTML) == 0) {
ReportUtils.exportReportToHtmlStream(jasperPrint, outputStream);
} else if (type.compareTo(ReportFileType.PDF) == 0) {
ReportUtils.exportReportToPdfStream(jasperPrint, outputStream);
} else if (type.compareTo(ReportFileType.RTF) == 0) {
ReportUtils.exportReportToRtfStream(jasperPrint, outputStream);
}
// 如果为xls的格式 要用xlsx的去读取,不然要么没引用poijar包报错,要么引用了找不到方法。
else if (type.compareTo(ReportFileType.XLS) == 0) {
// ReportUtils.exportReportToXlsStream(jasperPrint, outputStream);
ReportUtils.exportReportToXlsxStream(jasperPrint, outputStream);
} else if (type.compareTo(ReportFileType.XLSX) == 0) {
ReportUtils.exportReportToXlsxStream(jasperPrint, outputStream);
} else if (type.compareTo(ReportFileType.XML) == 0) {
ReportUtils.exportReportToXmlStream(jasperPrint, outputStream);
}
return outputStream.toByteArray();
}
}
========================================ReportFileType===============
package com.mould.common.entity;
import java.io.Serializable;
public enum ReportFileType implements Serializable{
PDF("pdf","application/pdf"),
XLS("xls","application/vnd.ms-excel"),
XLSX("xlsx","application/vnd.ms-excel"),
HTML("html","text/html"),
XML("xml","text/xml"),
RTF("rtf","application/rtf"),
DOCX("docx","application/msword");
private String extension;//文件后缀
private String contentType;//告诉浏览器类型
private ReportFileType(String extension,String contentType) {
this.extension = extension;
this.contentType=contentType;
}
public String getContentType() {
return contentType;
}
public void setContentType(String contentType) {
this.contentType = contentType;
}
public String getExtension() {
return extension;
}
public void setExtension(String extension) {
this.extension = extension;
}
public String getName() {
return this.name();
}
public int getIndex() {
return this.ordinal();
}
@Override
public String toString() {
return String.valueOf(this.getIndex());
}
}
========================================================ReportWebUtils=================
package com.mould.common.web;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.net.URLEncoder;
import java.sql.Connection;
import java.util.Map;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.sql.DataSource;
import org.springframework.jdbc.datasource.DataSourceUtils;
import com.mould.common.entity.ReportFileType;
import com.mould.common.utils.ReportUtils;
import com.mould.common.utils.StringUtils;
import net.sf.jasperreports.engine.JRException;
import net.sf.jasperreports.engine.JasperFillManager;
import net.sf.jasperreports.engine.JasperPrint;
/**
*
* @Description:jasperreports工具类
* @author linwp
* @time:2017年3月24日 下午9:57:45
*
*/
public class ReportWebUtils {
/**
* 导出报表
* @param request
* @param response
* @param filePath 文件路径名
* @param downFileName 下载的文件名
* @param type 格式 xls,xlsx,pdf,docx,html,xml,rtf
* @param isDownLoad 是否下载 true:下载 false:直接在浏览器打开
* @param params 参数
* @param dataSource 数据源
* @throws IOException
* @throws JRException
*/
public static void export(HttpServletRequest request,HttpServletResponse response, String filePath, String downFileName, String type,
Boolean isDownLoad, Map
Connection conn = DataSourceUtils.getConnection(dataSource);
try {
if (conn != null) {
JasperPrint jasperPrint = JasperFillManager.fillReport(filePath, params, conn);
DataSourceUtils.releaseConnection(conn, dataSource);
ReportFileType reportFileType = ReportWebUtils.getType(type);
ReportWebUtils.dealResponse(request,response, jasperPrint, downFileName, reportFileType, isDownLoad);
}
}finally {
if (conn != null) {
DataSourceUtils.releaseConnection(conn, dataSource);
}
}
}
/**
* 把报表处理后返回给浏览器
* @param response
* @param request
* @param jasperPrint 报表
* @param fileName 打开的文件名
* @param reportType 报表类型
* @param isDownLoad 是否下载
* @throws IOException
* @throws JRException
*/
public static void dealResponse(HttpServletRequest request,HttpServletResponse response, JasperPrint jasperPrint, String fileName,
ReportFileType reportType, Boolean isDownLoad) throws IOException, JRException {
ServletOutputStream sos = null;
try {
byte[] bytes = ReportWebUtils.getFileBytes(jasperPrint, reportType);
if ((bytes != null) && (bytes.length > 0)) {
String userAgent = request.getHeader("User-Agent");
boolean isIE = (userAgent != null) && (userAgent.toLowerCase().indexOf("msie") != -1);
response.reset();
response.setCharacterEncoding("UTF-8");
response.setContentType(reportType.getContentType());
response.setContentLength(bytes.length);
if (isIE) {
fileName = URLEncoder.encode(fileName, "UTF-8");
} else {
fileName = new String(fileName.getBytes("UTF-8"), "ISO8859-1");
}
response.setHeader("Content-Disposition", "inline;filename=" + fileName + "." + reportType.getExtension());
if (isDownLoad.booleanValue()) {
response.setHeader("Content-Disposition",
"attachment;filename=" + fileName + "." + reportType.getExtension());
}
sos = response.getOutputStream();
sos.write(bytes, 0, bytes.length);
sos.flush();
sos.close();
}
}finally {
if (sos != null) {
try {
sos.close();
} catch (IOException e) {
return ;
}
}
}
}
/**
* 根据字符串类型查找对应的ReportFileType
*
* @param type
* @return ReportFileType
*/
public static ReportFileType getType(String type) {
// 如果类型为空,返回pdf
if (StringUtils.isEmpty(type)) {
return ReportFileType.PDF;
}
// 匹配类型
if (type.toUpperCase().equals(ReportFileType.DOCX.getName())) {
return ReportFileType.DOCX;
} else if (type.toUpperCase().equals(ReportFileType.HTML.getName())) {
return ReportFileType.HTML;
} else if (type.toUpperCase().equals(ReportFileType.PDF.getName())) {
return ReportFileType.PDF;
} else if (type.toUpperCase().equals(ReportFileType.RTF.getName())) {
return ReportFileType.RTF;
} else if (type.toUpperCase().equals(ReportFileType.XLS.getName())) {
return ReportFileType.XLS;
} else if (type.toUpperCase().equals(ReportFileType.XLSX.getName())) {
return ReportFileType.XLSX;
} else if (type.toUpperCase().equals(ReportFileType.XML.getName())) {
return ReportFileType.XML;
}
// 如果都不匹配 返回PDF类型的
return ReportFileType.PDF;
}
/**
* 根据不同的ReportFileType 读取 JasperPrint 返回字节
*
* @param jasperPrint
* @param type
* ReportFileType类型
* @return
* @throws JRException
*/
public static byte[] getFileBytes(JasperPrint jasperPrint, ReportFileType type) throws JRException {
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
if (type.compareTo(ReportFileType.DOCX) == 0) {
ReportUtils.exportReportToDocxStream(jasperPrint, outputStream);
} else if (type.compareTo(ReportFileType.HTML) == 0) {
ReportUtils.exportReportToHtmlStream(jasperPrint, outputStream);
} else if (type.compareTo(ReportFileType.PDF) == 0) {
ReportUtils.exportReportToPdfStream(jasperPrint, outputStream);
} else if (type.compareTo(ReportFileType.RTF) == 0) {
ReportUtils.exportReportToRtfStream(jasperPrint, outputStream);
}
// 如果为xls的格式 要用xlsx的去读取,不然要么没引用poijar包报错,要么引用了找不到方法。
else if (type.compareTo(ReportFileType.XLS) == 0) {
// ReportUtils.exportReportToXlsStream(jasperPrint, outputStream);
ReportUtils.exportReportToXlsxStream(jasperPrint, outputStream);
} else if (type.compareTo(ReportFileType.XLSX) == 0) {
ReportUtils.exportReportToXlsxStream(jasperPrint, outputStream);
} else if (type.compareTo(ReportFileType.XML) == 0) {
ReportUtils.exportReportToXmlStream(jasperPrint, outputStream);
}
return outputStream.toByteArray();
}
}
注意:在ReportWebUtils通过dataSource获取连接后的connection ,最后在关闭的时候,要用spring的dataSourceUtils去关闭,如果只用conn.close()这种方法,dataSource的
active是没有关闭的,下一次如果在访问报表是,dataSource的activeCount的个数又加1了,当他到达你配置的maxActive时,整个系统就资源了。
界面代码============
因为界面可能传入的查询参数比较多,所以写了了form去打开,创建form是要把 $(document.body).append(tempForm); 加上,不然提交时提交不了的
});
//下载
$downloadBtn.click(function(){
BUI.Message.Confirm('确认要下载吗?',function(){
var params=getSearchParems("get");
params.filePath="sys/report1.jasper";
params.download="false";
params.type="PDF";
params.downloadName="用户列表";
addFormAndSub("${baseUrl}/sys/user/download",params);
},'question');
});
//创建form并提交
function addFormAndSub(action,params){
var tempForm=$("
3:报表在报表编辑器修改了,在页面上不起作用,是因为只在代码路径修改了,在发布到服务器的那个里面的文件没修改,暂时没找到一劳永逸的方法,都是手动替换报表文件