فهرست منبع

修改解析引用的子报表的方法

sunyj 9 سال پیش
والد
کامیت
e7e275c474
1فایلهای تغییر یافته به همراه66 افزوده شده و 55 حذف شده
  1. 66 55
      src/main/java/com/uas/report/service/impl/PrintServiceImpl.java

+ 66 - 55
src/main/java/com/uas/report/service/impl/PrintServiceImpl.java

@@ -1,9 +1,7 @@
 package com.uas.report.service.impl;
 
-import java.io.BufferedReader;
 import java.io.ByteArrayOutputStream;
 import java.io.File;
-import java.io.FileReader;
 import java.io.FileWriter;
 import java.io.IOException;
 import java.io.OutputStream;
@@ -24,6 +22,7 @@ import org.apache.log4j.Logger;
 import org.dom4j.Document;
 import org.dom4j.DocumentException;
 import org.dom4j.Element;
+import org.dom4j.Node;
 import org.dom4j.io.SAXReader;
 import org.dom4j.io.XMLWriter;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -178,24 +177,7 @@ public class PrintServiceImpl implements PrintService {
 			else {
 				logger.info("preview fillReport...");
 				jasperPrint = JasperFillManager.fillReport(jasperFilePath, parameters, connection);
-				JRPdfExporter exporter = new JRPdfExporter();
-				if (pageIndex != null) {
-					// 前端显示时页码从1开始,生成报表时页码从0开始
-					pageIndex -= 1;
-					// 页码并非有效数值,重置为第一页
-					if (pageIndex < 0 || pageIndex >= jasperPrint.getPages().size()) {
-						pageIndex = 0;
-					}
-					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();
-
+				exportReportToPdf(jasperPrint, outputStream, pageIndex);
 				logger.info("preview fillReport done...");
 				data = outputStream.toByteArray();
 				outputStream.close();
@@ -237,36 +219,11 @@ public class PrintServiceImpl implements PrintService {
 
 		// 首先解析jrxml文件,检查是否引用子报表,如果是,先(递归)编译子报表
 		try {
-			BufferedReader bufferedReader = new BufferedReader(new FileReader(jrxmlFile));
-			String line;
-			List<String> subJrxmlFilePaths = new ArrayList<>();
-			while (!StringUtils.isEmpty(line = bufferedReader.readLine())) {
-				// 引用的子报表![CDATA[$P{REPORT_DIR} + "/jrxml/FreeClaimQT.jasper"]]
-				if (line.contains("/jrxml/")) {
-					int beginIndex = line.indexOf("/jrxml/") + 7;
-					int endIndex = line.indexOf(".jasper");
-					// 子报表解析失败
-					if (beginIndex == -1 || endIndex == -1) {
-						bufferedReader.close();
-						String message = "嵌套报表源码解析失败:" + jrxmlFile.getName() + "\n子报表引用格式错误:";
-						try {
-							message += line.substring(line.indexOf("$P{REPORT_DIR}"),
-									line.indexOf("]]></subreportExpression>"));
-						} catch (Exception e) {
-							message = line.replaceAll("<subreportExpression><![CDATA[", "")
-									.replaceAll("]]></subreportExpression>", "").trim();
-						}
-						throw new ReportException(message);
-					}
-					String subJrxmlFileName = line.substring(beginIndex, endIndex) + ".jrxml";
-					subJrxmlFilePaths.add(jrxmlFile.getParent() + "/" + subJrxmlFileName);
-				}
-			}
-			bufferedReader.close();
+			List<String> subJrxmlFilePaths = getSubJrxmlFilePath(jrxmlFilePath);
 			for (String subJrxmlFilePath : subJrxmlFilePaths) {
 				maybeCompileJrxmlFile(subJrxmlFilePath, connection);
 			}
-		} catch (IOException e) {
+		} catch (DocumentException e) {
 			throw new ReportException(e).setDetailedMessage(e);
 		}
 
@@ -292,6 +249,35 @@ public class PrintServiceImpl implements PrintService {
 		return jasperFilePath;
 	}
 
+	/**
+	 * 获取报表模板所引用的子报表路径
+	 * 
+	 * @param jrxmlFilePath
+	 * @return
+	 * @throws DocumentException
+	 */
+	private List<String> getSubJrxmlFilePath(String jrxmlFilePath) throws DocumentException {
+		List<String> subJrxmlFilePaths = new ArrayList<>();
+		SAXReader saxReader = new SAXReader();
+		File jrxmlFile = new File(jrxmlFilePath);
+		Document document = saxReader.read(jrxmlFile);
+		@SuppressWarnings("unchecked")
+		// 解析模板中subreportExpression元素
+		List<Node> elements = document.selectNodes("//*[name()='subreportExpression']");
+		for (Node element : elements) {
+			// 格式为$P{REPORT_DIR} + "/jrxml/FreeClaimQT.jasper"
+			String text = element.getText();
+			int beginIndex = text.indexOf("/jrxml/");
+			int endIndex = text.indexOf(".jasper");
+			if (beginIndex < 0 || endIndex < 0) {
+				throw new ReportException("嵌套报表源码解析失败:" + jrxmlFile.getName() + ",子报表引用格式错误:" + text);
+			}
+			beginIndex += "/jrxml/".length();
+			subJrxmlFilePaths.add(jrxmlFile.getParent() + "/" + text.substring(beginIndex, endIndex) + ".jrxml");
+		}
+		return subJrxmlFilePaths;
+	}
+
 	/**
 	 * 编译jrxml报表模板为jasper文件
 	 * 
@@ -310,22 +296,20 @@ public class PrintServiceImpl implements PrintService {
 	}
 
 	/**
-	 * 处理模板中的field
+	 * 处理模板中的field(与数据库中列名进行比较,删除表中无对应列名的field)
 	 * 
 	 * @param jrxmlFilePath
 	 * @param connection
 	 */
 	private void processFields(String jrxmlFilePath, Connection connection) {
-		SAXReader saxReader = new SAXReader();
-		Document document;
 		XMLWriter xmlWriter = null;
 		try {
-			document = saxReader.read(new File(jrxmlFilePath));
+			SAXReader saxReader = new SAXReader();
+			Document document = saxReader.read(new File(jrxmlFilePath));
 			Element rootElement = document.getRootElement();
 			// 查询语句
 			Element queryStringElement = rootElement.element("queryString");
 			String queryString = queryStringElement.getText();
-			logger.info(queryString);
 			// 如果查询语句中含有WHERE_CONDITION参数,需将其替换掉
 			if (queryString.contains("$P!{WHERE_CONDITION}")) {
 				queryString = queryString.substring(0, queryString.indexOf("$P!{WHERE_CONDITION}"))
@@ -335,12 +319,10 @@ public class PrintServiceImpl implements PrintService {
 			else if (queryString.toUpperCase().contains("WHERE")) {
 				queryString = queryString.substring(0, queryString.indexOf("WHERE")) + "where rownum = 1";
 			}
-			logger.info(queryString);
 			List<String> columnNames = getColumnNames(connection, queryString);
 			if (CollectionUtils.isEmpty(columnNames)) {
 				throw new ReportException("未查询到任何列:" + queryString);
 			}
-			logger.info(columnNames);
 			// 指定的field
 			@SuppressWarnings("rawtypes")
 			List fieldElements = rootElement.elements("field");
@@ -375,7 +357,7 @@ public class PrintServiceImpl implements PrintService {
 	}
 
 	/**
-	 * 获取列名
+	 * 从数据库获取列名
 	 * 
 	 * @param connection
 	 * @param sql
@@ -410,6 +392,35 @@ public class PrintServiceImpl implements PrintService {
 		exporter.exportReport();
 	}
 
+	/**
+	 * 以pdf的格式导出报表
+	 * 
+	 * @param jasperPrint
+	 * @param outputStream
+	 * @param pageIndex
+	 * @throws JRException
+	 */
+	private void exportReportToPdf(JasperPrint jasperPrint, OutputStream outputStream, Integer pageIndex)
+			throws JRException {
+		JRPdfExporter exporter = new JRPdfExporter();
+		if (pageIndex != null) {
+			// 前端显示时页码从1开始,生成报表时页码从0开始
+			pageIndex -= 1;
+			// 页码并非有效数值,重置为第一页
+			if (pageIndex < 0 || pageIndex >= jasperPrint.getPages().size()) {
+				pageIndex = 0;
+			}
+			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();
+	}
+
 	/**
 	 * 移除除了Column Header和Detail之外的元素
 	 *