sunyj 9 лет назад
Родитель
Сommit
8226536763

+ 33 - 18
src/main/java/com/uas/report/controller/PrintController.java

@@ -12,6 +12,7 @@ import org.apache.commons.lang.ArrayUtils;
 import org.apache.log4j.Logger;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Controller;
+import org.springframework.util.CollectionUtils;
 import org.springframework.util.StringUtils;
 import org.springframework.web.bind.annotation.RequestMapping;
 
@@ -34,23 +35,24 @@ public class PrintController {
 	private PrintService printService;
 
 	/**
-	 * 打印报表
+	 * 导出报表
 	 * 
 	 * @param userName
 	 *            不为null;当前账套用户名
 	 * @param reportName
-	 *            不为null;需要打印的报表的名称,不带任何后缀(如打印采购单,即为"Purchase")
+	 *            不为null;需要导出的报表的名称,不带任何后缀(如导出采购单,即为"Purchase")
 	 * @param whereCondition
 	 *            可为null;where之后的条件(包括where)
 	 * @param otherParameters
 	 *            若模板已指定需要的参数,则不可为null;其他参数,区别于whereCondition,报表某些字段的值取决于这些参数
 	 * @param exportFileType
-	 *            报表打印的格式,默认为pdf
+	 *            报表导出的格式,默认为pdf
+	 * @param request
 	 * @param response
 	 * @return
 	 */
-	@RequestMapping
-	public String print(String userName, String reportName, String whereCondition, Map<String, Object> otherParameters,
+	@RequestMapping("/export")
+	public String export(String userName, String reportName, String whereCondition, Map<String, Object> otherParameters,
 			String exportFileType, HttpServletRequest request, HttpServletResponse response) {
 		String message = "";
 		if (StringUtils.isEmpty(userName)) {
@@ -66,14 +68,14 @@ public class PrintController {
 			return "error.jsp";
 		}
 
-		logger.info("开始打印报表: " + reportName);
+		logger.info("开始导出报表: " + reportName);
 		if (StringUtils.isEmpty(exportFileType)) {
 			exportFileType = "pdf";
 		}
 
-		byte[] data = printService.print(userName, reportName, whereCondition, otherParameters, exportFileType);
+		byte[] data = printService.export(userName, reportName, whereCondition, otherParameters, exportFileType);
 		if (ArrayUtils.isEmpty(data)) {
-			message = "报表 " + reportName + " 打印失败!";
+			message = "报表 " + reportName + " 导出失败!";
 			logger.error(message);
 			request.setAttribute("message", message);
 			return "error.jsp";
@@ -89,13 +91,13 @@ public class PrintController {
 			logger.error("浏览器重复请求!");
 		}
 
-		message = "报表 " + reportName + " 打印完成!";
+		message = "报表 " + reportName + " 导出完成!";
 		logger.info(message);
 		return null;
 	}
 
 	/**
-	 * 测试打印
+	 * 测试导出
 	 * 
 	 * @param response
 	 * @return
@@ -112,26 +114,30 @@ public class PrintController {
 		Map<String, Object> otherParameters = new HashMap<>();
 		otherParameters.put("OTHER_PARAMETER_TEST", "天气真好!");
 		String exportFileType = "xls";
-		return print(userName, reportName, whereCondition, otherParameters, exportFileType, request, response);
+		return export(userName, reportName, whereCondition, otherParameters, exportFileType, request, response);
 	}
 
 	/**
-	 * 打印报表预览
+	 * 报表预览
 	 * 
 	 * @param userName
 	 *            不为null;当前账套用户名
 	 * @param reportName
-	 *            不为null;需要打印的报表的名称,不带任何后缀(如打印采购单,即为"Purchase")
+	 *            不为null;需要预览的报表的名称,不带任何后缀(如预览采购单,即为"Purchase")
 	 * @param whereCondition
 	 *            可为null;where之后的条件(包括where)
 	 * @param otherParameters
 	 *            若模板已指定需要的参数,则不可为null;其他参数,区别于whereCondition,报表某些字段的值取决于这些参数
+	 * @param pageIndex
+	 *            分页展示,当前页码,从0开始
 	 * @param request
+	 * @param response
 	 * @return
 	 */
 	@RequestMapping(value = "/getData")
 	public String getData(String userName, String reportName, String whereCondition,
-			Map<String, Object> otherParameters, HttpServletRequest request, HttpServletResponse response) {
+			Map<String, Object> otherParameters, Integer pageIndex, HttpServletRequest request,
+			HttpServletResponse response) {
 		String message = "";
 		if (StringUtils.isEmpty(userName)) {
 			message = "未传入当前账套用户名!";
@@ -146,15 +152,24 @@ public class PrintController {
 			return "error.jsp";
 		}
 
-		logger.info("开始打印报表: " + reportName);
-		String exportFileType = "pdf";
-		byte[] data = printService.print(userName, reportName, whereCondition, otherParameters, exportFileType);
+		logger.info("开始预览报表: " + reportName);
+		Map<String, Object> result = printService.preview(userName, reportName, whereCondition, otherParameters,
+				pageIndex);
+		byte[] data = null;
+		Integer pageSize = null;
+		if (!CollectionUtils.isEmpty(result)) {
+			data = (byte[]) result.get("data");
+			pageSize = (Integer) result.get("pageSize");
+		}
 		if (ArrayUtils.isEmpty(data)) {
 			message = "报表 " + reportName + " 预览失败!";
 			logger.error(message);
 			request.setAttribute("message", message);
 			return "error.jsp";
 		}
+		if (pageSize != null) {
+			request.setAttribute("pageSize", pageSize);
+		}
 
 		try {
 			response.setContentType("application/pdf");
@@ -168,6 +183,6 @@ public class PrintController {
 
 		message = "报表 " + reportName + " 预览完成!";
 		logger.info(message);
-		return null;
+		return "preview.jsp";
 	}
 }

+ 23 - 5
src/main/java/com/uas/report/service/PrintService.java

@@ -11,20 +11,38 @@ import java.util.Map;
 public interface PrintService {
 
 	/**
-	 * 打印报表
+	 * 导出报表
 	 * 
 	 * @param userName
 	 *            不为null;当前账套用户名
 	 * @param reportName
-	 *            不为null;需要打印的报表的名称,不带任何后缀(如打印采购单,即为"Purchase")
+	 *            不为null;需要导出的报表的名称,不带任何后缀(如导出采购单,即为"Purchase")
 	 * @param whereCondition
 	 *            可为null;where之后的条件(包括where)
 	 * @param otherParameters
 	 *            若模板已指定需要的参数,则不可为null;其他参数,区别于whereCondition,报表某些字段的值取决于这些参数
 	 * @param exportFileType
-	 *            报表打印的格式,默认为pdf
-	 * @return 打印的文件的字节数组
+	 *            报表导出的格式,默认为pdf
+	 * @return 导出的文件的字节数组
 	 */
-	public byte[] print(String userName, String reportName, String whereCondition, Map<String, Object> otherParameters,
+	public byte[] export(String userName, String reportName, String whereCondition, Map<String, Object> otherParameters,
 			String exportFileType);
+
+	/**
+	 * 预览报表
+	 * 
+	 * @param userName
+	 *            不为null;当前账套用户名
+	 * @param reportName
+	 *            不为null;需要预览的报表的名称,不带任何后缀(如预览采购单,即为"Purchase")
+	 * @param whereCondition
+	 *            可为null;where之后的条件(包括where)
+	 * @param otherParameters
+	 *            若模板已指定需要的参数,则不可为null;其他参数,区别于whereCondition,报表某些字段的值取决于这些参数
+	 * @param pageIndex
+	 *            分页展示,当前页码,从0开始
+	 * @return 报表数据"data": byte[];总页数"pageSize": Integer
+	 */
+	public Map<String, Object> preview(String userName, String reportName, String whereCondition,
+			Map<String, Object> otherParameters, Integer pageIndex);
 }

+ 109 - 5
src/main/java/com/uas/report/service/impl/PrintServiceImpl.java

@@ -31,12 +31,14 @@ import net.sf.jasperreports.engine.JasperExportManager;
 import net.sf.jasperreports.engine.JasperFillManager;
 import net.sf.jasperreports.engine.JasperPrint;
 import net.sf.jasperreports.engine.design.JasperDesign;
+import net.sf.jasperreports.engine.export.JRPdfExporter;
 import net.sf.jasperreports.engine.export.JRXlsExporter;
 import net.sf.jasperreports.engine.xml.JRXmlLoader;
 import net.sf.jasperreports.export.ExporterInput;
 import net.sf.jasperreports.export.OutputStreamExporterOutput;
 import net.sf.jasperreports.export.SimpleExporterInput;
 import net.sf.jasperreports.export.SimpleOutputStreamExporterOutput;
+import net.sf.jasperreports.export.SimplePdfReportConfiguration;
 
 /**
  * 报表打印
@@ -50,7 +52,7 @@ public class PrintServiceImpl implements PrintService {
 	private static Logger logger = Logger.getLogger(PrintService.class);
 
 	@Override
-	public byte[] print(String userName, String reportName, String whereCondition, Map<String, Object> otherParameters,
+	public byte[] export(String userName, String reportName, String whereCondition, Map<String, Object> otherParameters,
 			String exportFileType) {
 		if (StringUtils.isEmpty(userName) || StringUtils.isEmpty(reportName)) {
 			return null;
@@ -107,6 +109,7 @@ public class PrintServiceImpl implements PrintService {
 			if (dataSource == null) {
 				return null;
 			}
+
 			connection = dataSource.getConnection();
 
 			// 从数据库获取数据填充报表
@@ -135,6 +138,107 @@ public class PrintServiceImpl implements PrintService {
 		return null;
 	}
 
+	@Override
+	public Map<String, Object> preview(String userName, String reportName, String whereCondition,
+			Map<String, Object> otherParameters, Integer pageIndex) {
+		if (StringUtils.isEmpty(userName) || StringUtils.isEmpty(reportName)) {
+			return null;
+		}
+
+		// 报表路径为报表根路径REPORT_DIR + 当前账套用户名userName
+		String reportDir = new StringBuilder(ReportConstants.REPORT_DIR).append(userName).append(File.separator)
+				.toString();
+
+		String jrxmlFilePath = new StringBuilder(reportDir).append("jrxml").append(File.separator).append(reportName)
+				.append(".jrxml").toString();
+		File jrxmlFile = new File(jrxmlFilePath);
+		// 报表模板不存在
+		if (!jrxmlFile.exists()) {
+			logger.error("未发现模板文件: " + jrxmlFile.getPath());
+			return null;
+		}
+
+		String jasperFilePath = jrxmlFile.getPath().replace(".jrxml", ".jasper");
+		// 报表模板编译后的文件
+		File jasperFile = new File(jasperFilePath);
+		try {
+			// 报表模板未编译过
+			if (!jasperFile.exists()) {
+				logger.info("正在编译报表模板...");
+				JasperDesign jasperDesign = JRXmlLoader.load(jrxmlFile);
+				JasperCompileManager.compileReportToFile(jasperDesign, jasperFilePath);
+			} else {
+				// 如果在编译之后,报表模板有更改过 ,重新编译
+				if (jrxmlFile.lastModified() > jasperFile.lastModified()) {
+					logger.info("正在重新编译报表模板...");
+					JasperDesign jasperDesign = JRXmlLoader.load(jrxmlFile);
+					JasperCompileManager.compileReportToFile(jasperDesign, jasperFilePath);
+				}
+			}
+		} catch (JRException e) {
+			e.printStackTrace();
+		}
+
+		// 向报表模板传递参数:报表路径、where条件、其他参数
+		Map<String, Object> parameters = new HashMap<>();
+		parameters.put(ReportConstants.PARAMETER_REPORT_DIR, reportDir);
+		if (!StringUtils.isEmpty(whereCondition)) {
+			parameters.put(ReportConstants.PARAMETER_WHERE_CONDITION, whereCondition);
+		}
+		if (!CollectionUtils.isEmpty(otherParameters)) {
+			parameters.putAll(otherParameters);
+		}
+
+		Connection connection = null;
+		try {
+			// 获取数据源
+			DataSource dataSource = getDataSource(userName);
+			if (dataSource == null) {
+				return null;
+			}
+
+			connection = dataSource.getConnection();
+			Map<String, Object> result = new HashMap<>();
+
+			// 从数据库获取数据填充报表
+			JasperPrint jasperPrint = JasperFillManager.fillReport(jasperFilePath, parameters, connection);
+			ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+
+			JRPdfExporter exporter = new JRPdfExporter();
+			if (pageIndex != null && pageIndex >= 0 && pageIndex < jasperPrint.getPages().size()) {
+				SimplePdfReportConfiguration configuration = new SimplePdfReportConfiguration();
+				configuration.setPageIndex(pageIndex);
+				exporter.setConfiguration(configuration);
+			}
+			ExporterInput exporterInput = new SimpleExporterInput(jasperPrint);
+			exporter.setExporterInput(exporterInput);
+			OutputStreamExporterOutput exporterOutput = new SimpleOutputStreamExporterOutput(outputStream);
+			exporter.setExporterOutput(exporterOutput);
+			exporter.exportReport();
+
+			byte[] data = outputStream.toByteArray();
+			outputStream.close();
+			result.put("data", data);
+			result.put("pageSize", jasperPrint.getPages().size());
+			return result;
+		} catch (SQLException e) {
+			logger.error("数据库连接错误!");
+		} catch (JRException e) {
+			e.printStackTrace();
+		} catch (IOException e) {
+			e.printStackTrace();
+		} finally {
+			if (connection != null) {
+				try {
+					connection.close();
+				} catch (SQLException e) {
+					e.printStackTrace();
+				}
+			}
+		}
+		return null;
+	}
+
 	/**
 	 * 根据当前账套用户名,从主数据库master表获取账套数据库配置信息,作为报表模板的数据源
 	 * 
@@ -212,7 +316,7 @@ public class PrintServiceImpl implements PrintService {
 	 * @param jasperPrint
 	 * @param exportFileType
 	 * @param outputStream
-	 * @return 报表是否成功打印
+	 * @return 报表是否成功导出
 	 */
 	private boolean exportReport(JasperPrint jasperPrint, String exportFileType, OutputStream outputStream) {
 		try {
@@ -221,7 +325,7 @@ public class PrintServiceImpl implements PrintService {
 			} else if (exportFileType.equals("xls")) {
 				exportReportToXls(jasperPrint, outputStream);
 			} else {
-				logger.error("不支持" + exportFileType + "格式!");
+				logger.error("不支持导出为 " + exportFileType + "格式!");
 				return false;
 			}
 		} catch (JRException e) {
@@ -232,7 +336,7 @@ public class PrintServiceImpl implements PrintService {
 	}
 
 	/**
-	 * 以pdf的格式打印报表
+	 * 以pdf的格式导出报表
 	 * 
 	 * @param jasperPrint
 	 * @param outputStream
@@ -243,7 +347,7 @@ public class PrintServiceImpl implements PrintService {
 	}
 
 	/**
-	 * 以xls的格式打印报表
+	 * 以xls的格式导出报表
 	 * 
 	 * @param jasperPrint
 	 * @param outputStream

+ 46 - 2
src/main/webapp/WEB-INF/views/preview.jsp

@@ -17,6 +17,11 @@
 	String reportName = request.getParameter("reportName");
 	String whereCondition = request.getParameter("whereCondition");
 	String otherParameters = request.getParameter("otherParameters");
+	Integer pageIndex = Integer.valueOf(request.getParameter("pageIndex"));
+
+	Integer pageSize = (Integer) request.getAttribute("pageSize");
+	System.out.println(pageIndex + "/" + pageSize);
+
 	//byte[] data = (byte[]) request.getAttribute("data");
 %>
 </head>
@@ -54,20 +59,59 @@
 			}
 			urlStringBuilder.append("otherParameters=").append(otherParameters);
 		}
+		if (!StringUtils.isEmpty(pageIndex)) {
+			if (needAnd) {
+				urlStringBuilder.append("&");
+			} else {
+				urlStringBuilder.append("?");
+			}
+			urlStringBuilder.append("pageIndex=").append(pageIndex);
+		}
 	%>
 
 	<form
-		action="<%=urlStringBuilder.toString().replace("getData", "")%>&exportFileType=pdf"
+		action="<%=urlStringBuilder.toString().replace("getData", "export")%>&exportFileType=pdf"
 		method="post">
 		<input stype="cursor:pointer" type="submit" value="export as pdf">
 	</form>
 
 	<form
-		action="<%=urlStringBuilder.toString().replace("getData", "")%>&exportFileType=xls"
+		action="<%=urlStringBuilder.toString().replace("getData", "export")%>&exportFileType=xls"
 		method="post">
 		<input stype="cursor:pointer" type="submit" value="export as xls">
 	</form>
 
+	<%
+		if (pageIndex != 0) {
+	%>
+
+	<form
+		action="<%=urlStringBuilder.toString().replace("print/getData", "preview")
+						.replace("pageIndex=" + pageIndex, "pageIndex=" + (pageIndex - 1))%>"
+		method="post">
+		<input stype="cursor:pointer" type="submit" value="prev">
+	</form>
+	<%
+		}
+		if (pageSize == null || pageIndex < pageSize - 1) {
+	%>
+	<form
+		action="<%=urlStringBuilder.toString().replace("print/getData", "preview")
+						.replace("pageIndex=" + pageIndex, "pageIndex=" + (pageIndex + 1))%>"
+		method="post">
+		<input stype="cursor:pointer" type="submit" value="next">
+	</form>
+	<%
+		}
+	%>
+	<%-- 		<%
+			if (pageSize != null && pageSize > 0 && pageIndex != null && pageIndex >= 0 && pageIndex < pageSize) {
+		%> --%>
+	<p><%=pageIndex + 1 + "/" + pageSize%></p>
+	<%-- 		<%
+			}
+		%> --%>
+
 	<iframe id="pdf_frame" name="pdf_frame"
 		src="<%=urlStringBuilder.toString()%>" scrolling="no" frameBorder="0"
 		style="height: 620px; width: 100%"> </iframe>