فهرست منبع

支持多账套打印报表

sunyj 9 سال پیش
والد
کامیت
9ae518299a

+ 4 - 3
pom.xml

@@ -14,6 +14,7 @@
 		<log4j.version>1.2.16</log4j.version>
 		<servlet.version>3.0-alpha-1</servlet.version>
 		<commons.dbcp.version>1.4</commons.dbcp.version>
+		<druid.version>1.0.24</druid.version>
 	</properties>
 
 	<dependencies>
@@ -32,9 +33,9 @@
 		</dependency>
 
 		<dependency>
-			<groupId>commons-dbcp</groupId>
-			<artifactId>commons-dbcp</artifactId>
-			<version>${commons.dbcp.version}</version>
+			<groupId>com.alibaba</groupId>
+			<artifactId>druid</artifactId>
+			<version>${druid.version}</version>
 		</dependency>
 
 		<!-- log4j -->

+ 16 - 4
src/main/java/com/uas/report/controller/PrintController.java

@@ -36,6 +36,8 @@ public class PrintController {
 	/**
 	 * 打印报表
 	 * 
+	 * @param userName
+	 *            不为null;当前账套用户名
 	 * @param reportName
 	 *            不为null;需要打印的报表的名称,不带任何后缀(如打印采购单,即为"Purchase")
 	 * @param whereCondition
@@ -47,9 +49,14 @@ public class PrintController {
 	 */
 	@RequestMapping
 	@ResponseBody
-	public String print(String reportName, String whereCondition, Map<String, Object> otherParameters,
+	public String print(String userName, String reportName, String whereCondition, Map<String, Object> otherParameters,
 			HttpServletResponse response) {
 		String message = "";
+		if (StringUtils.isEmpty(userName)) {
+			message = "未传入当前账套用户名!";
+			logger.error(message);
+			return message;
+		}
 		if (StringUtils.isEmpty(reportName)) {
 			message = "报表名称无效!";
 			logger.error(message);
@@ -57,7 +64,7 @@ public class PrintController {
 		}
 
 		logger.info("开始打印报表: " + reportName);
-		byte[] results = printService.print(reportName, whereCondition, otherParameters);
+		byte[] results = printService.print(userName, reportName, whereCondition, otherParameters);
 		if (ArrayUtils.isEmpty(results)) {
 			message = "报表 " + reportName + " 打印失败!";
 			logger.error(message);
@@ -90,9 +97,14 @@ public class PrintController {
 	@ResponseBody
 	public String testPrint(HttpServletResponse response) {
 		String reportName = "Purchase";
-		String whereCondition = "where pu_code = 'MP160800017' and pd_qty > 1000";
+		// String userName = "UAS";
+		// String whereCondition = "where pu_code = 'MP160800017' and pd_qty >
+		// 1000";
+		// 多账套测试
+		String userName = "UAS_DEMO";
+		String whereCondition = "where pu_code = 'YFMP160600001'";
 		Map<String, Object> otherParameters = new HashMap<>();
 		otherParameters.put("OTHER_PARAMETER_TEST", "天气真好!");
-		return print(reportName, whereCondition, otherParameters, response);
+		return print(userName, reportName, whereCondition, otherParameters, response);
 	}
 }

+ 3 - 1
src/main/java/com/uas/report/service/PrintService.java

@@ -13,6 +13,8 @@ public interface PrintService {
 	/**
 	 * 打印报表
 	 * 
+	 * @param userName
+	 *            不为null;当前账套用户名
 	 * @param reportName
 	 *            不为null;需要打印的报表的名称,不带任何后缀(如打印采购单,即为"Purchase")
 	 * @param whereCondition
@@ -21,5 +23,5 @@ public interface PrintService {
 	 *            若模板已指定需要的参数,则不可为null;其他参数,区别于whereCondition,报表某些字段的值取决于这些参数
 	 * @return 导出的文件的字节数组
 	 */
-	public byte[] print(String reportName, String whereCondition, Map<String, Object> otherParameters);
+	public byte[] print(String userName, String reportName, String whereCondition, Map<String, Object> otherParameters);
 }

+ 91 - 9
src/main/java/com/uas/report/service/impl/PrintServiceImpl.java

@@ -2,16 +2,22 @@ package com.uas.report.service.impl;
 
 import java.io.File;
 import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
 import java.sql.SQLException;
 import java.util.HashMap;
 import java.util.Map;
+import java.util.Properties;
+
+import javax.sql.DataSource;
 
-import org.apache.commons.dbcp.BasicDataSource;
 import org.apache.log4j.Logger;
 import org.springframework.stereotype.Service;
 import org.springframework.util.CollectionUtils;
 import org.springframework.util.StringUtils;
 
+import com.alibaba.druid.pool.DruidDataSource;
+import com.alibaba.druid.pool.DruidDataSourceFactory;
 import com.uas.report.service.PrintService;
 import com.uas.report.util.ContextUtils;
 import com.uas.report.util.ReportConstants;
@@ -34,13 +40,20 @@ public class PrintServiceImpl implements PrintService {
 	private static Logger logger = Logger.getLogger(PrintService.class);
 
 	@Override
-	public byte[] print(String reportName, String whereCondition, Map<String, Object> otherParameters) {
+	public byte[] print(String userName, String reportName, String whereCondition,
+			Map<String, Object> otherParameters) {
 		byte[] results = null;
-		if (StringUtils.isEmpty(reportName)) {
+		if (StringUtils.isEmpty(userName) || StringUtils.isEmpty(reportName)) {
 			return results;
 		}
 
-		File jrxmlFile = new File(ReportConstants.REPORT_DIR + "jrxml" + File.separator + reportName + ".jrxml");
+		// 报表路径为报表根路径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());
@@ -68,8 +81,9 @@ public class PrintServiceImpl implements PrintService {
 			e.printStackTrace();
 		}
 
+		// 向报表模板传递参数:报表路径、where条件、其他参数
 		Map<String, Object> parameters = new HashMap<>();
-		parameters.put(ReportConstants.PARAMETER_REPORT_DIR, ReportConstants.REPORT_DIR);
+		parameters.put(ReportConstants.PARAMETER_REPORT_DIR, reportDir);
 		if (!StringUtils.isEmpty(whereCondition)) {
 			parameters.put(ReportConstants.PARAMETER_WHERE_CONDITION, whereCondition);
 		}
@@ -78,7 +92,12 @@ public class PrintServiceImpl implements PrintService {
 		}
 
 		try {
-			Connection connection = getDataSource().getConnection();
+			DataSource dataSource = getDataSource(userName);
+			if (dataSource == null) {
+				return null;
+			}
+			Connection connection = dataSource.getConnection();
+			// 打印报表,以字节数组形式导出pdf
 			results = JasperRunManager.runReportToPdf(jasperFilePath, parameters, connection);
 			connection.close();
 		} catch (SQLException e) {
@@ -90,11 +109,74 @@ public class PrintServiceImpl implements PrintService {
 	}
 
 	/**
-	 * 从配置文件中获取dataSource作为报表模板的数据源
+	 * 根据当前账套用户名,从主数据库master表获取账套数据库配置信息,作为报表模板的数据源
 	 * 
+	 * @param userName
+	 *            当前账套用户名
 	 * @return
 	 */
-	private BasicDataSource getDataSource() {
-		return ContextUtils.getApplicationContext().getBean("dataSource", BasicDataSource.class);
+	private DataSource getDataSource(String userName) {
+		// 默认数据源(主数据库)
+		DruidDataSource defaultDataSource = ContextUtils.getApplicationContext().getBean("defaultSob",
+				DruidDataSource.class);
+		if (defaultDataSource == null) {
+			return null;
+		}
+		// 若当前账套用户名为默认数据库用户名
+		if (userName.equals(defaultDataSource.getUsername())) {
+			return defaultDataSource;
+		}
+
+		Connection connection = null;
+		PreparedStatement preparedStatement = null;
+		ResultSet resultSet = null;
+		try {
+			connection = defaultDataSource.getConnection();
+			// 根据当前账套用户名获取其数据库配置信息
+			String sql = "select * from master where MA_USER = ?";
+			preparedStatement = connection.prepareStatement(sql);
+			preparedStatement.setString(1, userName);
+			resultSet = preparedStatement.executeQuery();
+			if (resultSet.next()) {
+				String password = resultSet.getString("MS_PWD");
+				if (!StringUtils.isEmpty(password)) {
+					Properties properties = new Properties();
+					properties.put("driverClassName", defaultDataSource.getDriverClassName());
+					properties.put("url", defaultDataSource.getUrl());
+					properties.put("username", userName);
+					properties.put("password", password);
+					properties.put("testWhileIdle", "true");
+					properties.put("validationQuery", "select 1 from SYS.DUAL");
+					return DruidDataSourceFactory.createDataSource(properties);
+				}
+			}
+		} catch (SQLException e) {
+			e.printStackTrace();
+		} catch (Exception e) {
+			e.printStackTrace();
+		} finally {
+			try {
+				if (resultSet != null) {
+					resultSet.close();
+				}
+			} catch (SQLException e) {
+				e.printStackTrace();
+			}
+			try {
+				if (preparedStatement != null) {
+					preparedStatement.close();
+				}
+			} catch (SQLException e) {
+				e.printStackTrace();
+			}
+			try {
+				connection.close();
+			} catch (SQLException e) {
+				e.printStackTrace();
+			}
+			// defaultDataSource.close();
+		}
+		return null;
+
 	}
 }

+ 2 - 1
src/main/java/com/uas/report/util/ReportConstants.java

@@ -10,9 +10,10 @@ import java.io.File;
  */
 public class ReportConstants {
 	/**
-	 * 报表路径
+	 * 报表路径
 	 */
 	public static final String REPORT_DIR = PathUtils.getFilePath() + "reports" + File.separator;
+	// public static final String REPORT_DIR = "/data/reports" + File.separator;
 
 	/**
 	 * 报表参数 - WHERE_CONDITION,where字句(需含where)

+ 23 - 10
src/main/resources/applicationContext.xml

@@ -21,19 +21,32 @@
 	<!-- 扫描的包 -->
 	<context:component-scan base-package="com.uas.report" />
 
-	<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
-		destroy-method="close">
+	<bean id="defaultSob" class="com.alibaba.druid.pool.DruidDataSource"
+		init-method="init" destroy-method="close"><!-- 标准帐套 -->
 		<property name="driverClassName" value="${jdbc.driverClassName}" />
 		<property name="url" value="${jdbc.url}" />
 		<property name="username" value="${jdbc.username}" />
 		<property name="password" value="${jdbc.password}" />
-		<property name="initialSize" value="${jdbc.initialSize}" />
-		<property name="maxActive" value="${jdbc.maxActive}" />
-		<property name="maxIdle" value="${jdbc.maxIdle}" />
-		<property name="minIdle" value="${jdbc.minIdle}" />
-		<property name="removeAbandoned" value="true" />
-		<property name="timeBetweenEvictionRunsMillis" value="${jdbc.timeBetweenEvictionRunsMillis}" />
-		<property name="minEvictableIdleTimeMillis" value="${jdbc.minEvictableIdleTimeMillis}" />
-	</bean>
+		<property name="initialSize" value="10" />
+		<property name="maxActive" value="200" />
+		<property name="minIdle" value="10" />
+
+		<!-- 配置获取连接等待超时的时间 -->
+		<property name="maxWait" value="60000" />
 
+		<property name="testOnBorrow" value="false" />
+		<property name="testOnReturn" value="false" />
+		<property name="testWhileIdle" value="true" />
+		<property name="validationQuery" value="SELECT 1 FROM SYS.DUAL" />
+		<!-- 配置间隔多久才进行一次检测,检测需要关闭的空闲连接 -->
+		<property name="timeBetweenEvictionRunsMillis" value="60000" />
+		<!-- 配置一个连接在池中最小生存的时间 -->
+		<property name="minEvictableIdleTimeMillis" value="1800000" />
+		<!-- 打开PSCache,并且指定每个连接上PSCache的大小 -->
+		<property name="poolPreparedStatements" value="true" />
+		<property name="maxPoolPreparedStatementPerConnectionSize"
+			value="100" />
+		<!-- 配置监控统计拦截的filters -->
+		<property name="filters" value="stat" />
+	</bean>
 </beans>