Browse Source

编译模板时修改模板中的field

sunyj 9 years ago
parent
commit
acc6758405
2 changed files with 130 additions and 7 deletions
  1. 14 0
      pom.xml
  2. 116 7
      src/main/java/com/uas/report/service/impl/PrintServiceImpl.java

+ 14 - 0
pom.xml

@@ -53,6 +53,8 @@
 		<axis.version>1.4</axis.version>
 		<axis.version>1.4</axis.version>
 		<wsdl4j.version>1.6.3</wsdl4j.version>
 		<wsdl4j.version>1.6.3</wsdl4j.version>
 		<commons.discovery.version>0.2</commons.discovery.version>
 		<commons.discovery.version>0.2</commons.discovery.version>
+		<dom4j.version>1.6.1</dom4j.version>
+		<jaxen.version>1.1.6</jaxen.version>
 	</properties>
 	</properties>
 
 
 	<dependencies>
 	<dependencies>
@@ -182,6 +184,18 @@
 			<artifactId>wsdl4j</artifactId>
 			<artifactId>wsdl4j</artifactId>
 			<version>${wsdl4j.version}</version>
 			<version>${wsdl4j.version}</version>
 		</dependency>
 		</dependency>
+
+		<!-- dom4j -->
+		<dependency>
+			<groupId>dom4j</groupId>
+			<artifactId>dom4j</artifactId>
+			<version>${dom4j.version}</version>
+		</dependency>
+		<dependency>
+			<groupId>jaxen</groupId>
+			<artifactId>jaxen</artifactId>
+			<version>${jaxen.version}</version>
+		</dependency>
 	</dependencies>
 	</dependencies>
 
 
 	<build>
 	<build>

+ 116 - 7
src/main/java/com/uas/report/service/impl/PrintServiceImpl.java

@@ -4,9 +4,13 @@ import java.io.BufferedReader;
 import java.io.ByteArrayOutputStream;
 import java.io.ByteArrayOutputStream;
 import java.io.File;
 import java.io.File;
 import java.io.FileReader;
 import java.io.FileReader;
+import java.io.FileWriter;
 import java.io.IOException;
 import java.io.IOException;
 import java.io.OutputStream;
 import java.io.OutputStream;
 import java.sql.Connection;
 import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.ResultSetMetaData;
 import java.sql.SQLException;
 import java.sql.SQLException;
 import java.util.ArrayList;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.HashMap;
@@ -17,6 +21,11 @@ import javax.sql.DataSource;
 
 
 import org.apache.commons.lang.ArrayUtils;
 import org.apache.commons.lang.ArrayUtils;
 import org.apache.log4j.Logger;
 import org.apache.log4j.Logger;
+import org.dom4j.Document;
+import org.dom4j.DocumentException;
+import org.dom4j.Element;
+import org.dom4j.io.SAXReader;
+import org.dom4j.io.XMLWriter;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import org.springframework.stereotype.Service;
 import org.springframework.util.CollectionUtils;
 import org.springframework.util.CollectionUtils;
@@ -115,7 +124,6 @@ public class PrintServiceImpl implements PrintService {
 
 
 		userName = processMasterOfB2B(userName, reportName);
 		userName = processMasterOfB2B(userName, reportName);
 		String jrxmlFilePath = fileService.getJrxmlFilePath(userName, reportName);
 		String jrxmlFilePath = fileService.getJrxmlFilePath(userName, reportName);
-		String jasperFilePath = maybeCompileJrxmlFile(jrxmlFilePath);
 
 
 		// 向报表模板传递参数:报表路径、where条件、其他参数
 		// 向报表模板传递参数:报表路径、where条件、其他参数
 		Map<String, Object> parameters = new HashMap<>();
 		Map<String, Object> parameters = new HashMap<>();
@@ -135,6 +143,8 @@ public class PrintServiceImpl implements PrintService {
 			connection = dataSource.getConnection();
 			connection = dataSource.getConnection();
 			logger.info("dataSource.getConnection done..." + userName);
 			logger.info("dataSource.getConnection done..." + userName);
 
 
+			String jasperFilePath = maybeCompileJrxmlFile(jrxmlFilePath, connection);
+
 			Map<String, Object> result = new HashMap<>();
 			Map<String, Object> result = new HashMap<>();
 			byte[] data = null;
 			byte[] data = null;
 			// 从数据库获取数据填充报表
 			// 从数据库获取数据填充报表
@@ -213,7 +223,7 @@ public class PrintServiceImpl implements PrintService {
 	 *            报表模板文件
 	 *            报表模板文件
 	 * @return 编译后的jasper文件路径
 	 * @return 编译后的jasper文件路径
 	 */
 	 */
-	private String maybeCompileJrxmlFile(String jrxmlFilePath) {
+	private String maybeCompileJrxmlFile(String jrxmlFilePath, Connection connection) {
 		if (StringUtils.isEmpty(jrxmlFilePath)) {
 		if (StringUtils.isEmpty(jrxmlFilePath)) {
 			logger.error("参数不能为空:" + jrxmlFilePath);
 			logger.error("参数不能为空:" + jrxmlFilePath);
 			return null;
 			return null;
@@ -254,7 +264,7 @@ public class PrintServiceImpl implements PrintService {
 			}
 			}
 			bufferedReader.close();
 			bufferedReader.close();
 			for (String subJrxmlFilePath : subJrxmlFilePaths) {
 			for (String subJrxmlFilePath : subJrxmlFilePaths) {
-				maybeCompileJrxmlFile(subJrxmlFilePath);
+				maybeCompileJrxmlFile(subJrxmlFilePath, connection);
 			}
 			}
 		} catch (IOException e) {
 		} catch (IOException e) {
 			throw new ReportException(e).setDetailedMessage(e);
 			throw new ReportException(e).setDetailedMessage(e);
@@ -267,14 +277,12 @@ public class PrintServiceImpl implements PrintService {
 			// 报表模板未编译过
 			// 报表模板未编译过
 			if (!jasperFile.exists()) {
 			if (!jasperFile.exists()) {
 				logger.info("正在编译报表模板... " + jrxmlFilePath);
 				logger.info("正在编译报表模板... " + jrxmlFilePath);
-				JasperDesign jasperDesign = JRXmlLoader.load(jrxmlFile);
-				JasperCompileManager.compileReportToFile(jasperDesign, jasperFilePath);
+				compileReportToFile(jrxmlFilePath, jasperFilePath, connection);
 			} else {
 			} else {
 				// 如果在编译之后,报表模板有更改过 ,重新编译
 				// 如果在编译之后,报表模板有更改过 ,重新编译
 				if (jrxmlFile.lastModified() > jasperFile.lastModified()) {
 				if (jrxmlFile.lastModified() > jasperFile.lastModified()) {
 					logger.info("正在重新编译报表模板... " + jrxmlFilePath);
 					logger.info("正在重新编译报表模板... " + jrxmlFilePath);
-					JasperDesign jasperDesign = JRXmlLoader.load(jrxmlFile);
-					JasperCompileManager.compileReportToFile(jasperDesign, jasperFilePath);
+					compileReportToFile(jrxmlFilePath, jasperFilePath, connection);
 				}
 				}
 			}
 			}
 		} catch (JRException e) {
 		} catch (JRException e) {
@@ -284,6 +292,107 @@ public class PrintServiceImpl implements PrintService {
 		return jasperFilePath;
 		return jasperFilePath;
 	}
 	}
 
 
+	/**
+	 * 编译jrxml报表模板为jasper文件
+	 * 
+	 * @param jrxmlFilePath
+	 *            模板文件
+	 * @param jasperFilePath
+	 *            编译后的文件
+	 * @param connection
+	 *            数据库连接
+	 * @throws JRException
+	 */
+	private void compileReportToFile(String jrxmlFilePath, String jasperFilePath, Connection connection)
+			throws JRException {
+		processFields(jrxmlFilePath, connection);
+		JasperCompileManager.compileReportToFile(jrxmlFilePath, jasperFilePath);
+	}
+
+	/**
+	 * 处理模板中的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));
+			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}"))
+						+ "where rownum = 1";
+			}
+			// 如果查询语句中含有where条件,则可能有用到一些参数,需将其替换掉
+			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");
+			boolean needModifying = false;
+			for (int i = 0; i < fieldElements.size(); i++) {
+				Element element = (Element) fieldElements.get(i);
+				String columnName = element.attribute("name").getText();
+				// 如果指定的Field在当前帐套的表中不存在,则删除该Field
+				if (!columnNames.contains(columnName.toUpperCase())) {
+					needModifying = true;
+					rootElement.remove(element);
+					logger.info("Removed... " + columnName);
+				}
+			}
+			// 如果需要修改,则重新写入模板文件
+			if (needModifying) {
+				xmlWriter = new XMLWriter(new FileWriter(jrxmlFilePath));
+				xmlWriter.write(document);
+				xmlWriter.flush();
+			}
+		} catch (DocumentException | SQLException | IOException e) {
+			throw new ReportException(e).setDetailedMessage(e);
+		} finally {
+			if (xmlWriter != null) {
+				try {
+					xmlWriter.close();
+				} catch (IOException e) {
+					throw new ReportException(e).setDetailedMessage(e);
+				}
+			}
+		}
+	}
+
+	/**
+	 * 获取列名
+	 * 
+	 * @param connection
+	 * @param sql
+	 * @return
+	 * @throws SQLException
+	 */
+	private List<String> getColumnNames(Connection connection, String sql) throws SQLException {
+		List<String> result = new ArrayList<>();
+		PreparedStatement preparedStatement = connection.prepareStatement(sql);
+		ResultSet resultSet = preparedStatement.executeQuery();
+		ResultSetMetaData resultSetMetaData = resultSet.getMetaData();
+		for (int i = 1; i <= resultSetMetaData.getColumnCount(); i++) {
+			result.add(resultSetMetaData.getColumnName(i).toUpperCase());
+		}
+		return result;
+	}
+
 	/**
 	/**
 	 * 以xls的格式导出报表
 	 * 以xls的格式导出报表
 	 * 
 	 *