|
|
@@ -2,17 +2,12 @@ package com.uas.report.service.impl;
|
|
|
|
|
|
import java.io.ByteArrayOutputStream;
|
|
|
import java.io.File;
|
|
|
-import java.io.FileOutputStream;
|
|
|
import java.io.IOException;
|
|
|
import java.io.OutputStream;
|
|
|
import java.sql.Connection;
|
|
|
-import java.sql.PreparedStatement;
|
|
|
-import java.sql.ResultSet;
|
|
|
import java.sql.SQLException;
|
|
|
-import java.util.Date;
|
|
|
import java.util.HashMap;
|
|
|
import java.util.Map;
|
|
|
-import java.util.Properties;
|
|
|
|
|
|
import javax.sql.DataSource;
|
|
|
|
|
|
@@ -23,17 +18,12 @@ 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.alibaba.fastjson.JSONObject;
|
|
|
-import com.itextpdf.text.Document;
|
|
|
-import com.itextpdf.text.DocumentException;
|
|
|
-import com.itextpdf.text.pdf.PdfCopy;
|
|
|
-import com.itextpdf.text.pdf.PdfReader;
|
|
|
import com.uas.report.core.exception.ReportException;
|
|
|
+import com.uas.report.service.FileService;
|
|
|
import com.uas.report.service.PrintService;
|
|
|
-import com.uas.report.support.SysConf;
|
|
|
-import com.uas.report.util.ContextUtils;
|
|
|
+import com.uas.report.util.DataSourceUtils;
|
|
|
+import com.uas.report.util.FileUtils;
|
|
|
import com.uas.report.util.ReportConstants;
|
|
|
|
|
|
import net.sf.jasperreports.engine.JRException;
|
|
|
@@ -62,28 +52,22 @@ import net.sf.jasperreports.export.SimplePdfReportConfiguration;
|
|
|
public class PrintServiceImpl implements PrintService {
|
|
|
|
|
|
@Autowired
|
|
|
- private SysConf sysConf;
|
|
|
+ private FileService fileService;
|
|
|
|
|
|
// @Autowired
|
|
|
// private ResourceService resourceService;
|
|
|
|
|
|
private Logger logger = Logger.getLogger(getClass());
|
|
|
|
|
|
- @Override
|
|
|
- public byte[] export(String userName, String reportName, String whereCondition, String otherParameters,
|
|
|
- String exportFileType) {
|
|
|
- return export(userName, null, reportName, whereCondition, otherParameters, exportFileType);
|
|
|
- }
|
|
|
-
|
|
|
@Override
|
|
|
public byte[] export(String userName, String profile, String reportName, String whereCondition,
|
|
|
String otherParameters, String exportFileType) {
|
|
|
DataSource dataSource = null;
|
|
|
if (!StringUtils.isEmpty(profile)) {
|
|
|
- dataSource = getDataSource(userName, profile);
|
|
|
+ dataSource = DataSourceUtils.getPlatformDataSource(userName, profile);
|
|
|
} else {
|
|
|
// 为空,说明不是来自B2C或B2B的请求,而是UAS系统
|
|
|
- dataSource = getUASDataSource(userName);
|
|
|
+ dataSource = DataSourceUtils.getUASDataSource(userName);
|
|
|
}
|
|
|
if (dataSource == null) {
|
|
|
throw new ReportException("获取数据源失败");
|
|
|
@@ -96,21 +80,15 @@ public class PrintServiceImpl implements PrintService {
|
|
|
return null;
|
|
|
}
|
|
|
|
|
|
- @Override
|
|
|
- public Map<String, Object> preview(String userName, String reportName, String whereCondition,
|
|
|
- String otherParameters, Integer pageIndex) {
|
|
|
- return preview(userName, null, reportName, whereCondition, otherParameters, pageIndex);
|
|
|
- }
|
|
|
-
|
|
|
@Override
|
|
|
public Map<String, Object> preview(String userName, String profile, String reportName, String whereCondition,
|
|
|
String otherParameters, Integer pageIndex) {
|
|
|
DataSource dataSource = null;
|
|
|
if (!StringUtils.isEmpty(profile)) {
|
|
|
- dataSource = getDataSource(userName, profile);
|
|
|
+ dataSource = DataSourceUtils.getPlatformDataSource(userName, profile);
|
|
|
} else {
|
|
|
// 为空,说明不是来自B2C或B2B的请求,而是UAS系统
|
|
|
- dataSource = getUASDataSource(userName);
|
|
|
+ dataSource = DataSourceUtils.getUASDataSource(userName);
|
|
|
}
|
|
|
if (dataSource == null) {
|
|
|
throw new ReportException("获取数据源失败");
|
|
|
@@ -122,7 +100,7 @@ public class PrintServiceImpl implements PrintService {
|
|
|
public Integer previewFirstPage(final String userName, final String profile, final String reportName,
|
|
|
final String whereCondition, final String otherParameters, final String pdfFilePath) {
|
|
|
// 先生成第一页pdf
|
|
|
- final Integer pageSize = writePdfData(userName, profile, reportName, whereCondition, otherParameters,
|
|
|
+ final Integer pageSize = createPdfFile(userName, profile, reportName, whereCondition, otherParameters,
|
|
|
pdfFilePath.replace(".pdf", "_1.pdf"), 1);
|
|
|
|
|
|
// 再开线程生成后面页的pdf、总的pdf(即未分页的pdf)、纯数据excel
|
|
|
@@ -131,22 +109,22 @@ public class PrintServiceImpl implements PrintService {
|
|
|
public void run() {
|
|
|
// 生成之后2~5页的pdf,防止数据量较大的情况下,卡在生成总的pdf阶段,此时查看前5页也不会卡顿
|
|
|
for (int i = 2; i <= Math.min(pageSize, 5); i++) {
|
|
|
- writePdfData(userName, profile, reportName, whereCondition, otherParameters,
|
|
|
+ createPdfFile(userName, profile, reportName, whereCondition, otherParameters,
|
|
|
pdfFilePath.replace(".pdf", "_" + i + ".pdf"), i);
|
|
|
}
|
|
|
// 生成总的pdf
|
|
|
- writePdfData(userName, profile, reportName, whereCondition, otherParameters, pdfFilePath, null);
|
|
|
- writePagedPdfFiles(pdfFilePath);
|
|
|
+ createPdfFile(userName, profile, reportName, whereCondition, otherParameters, pdfFilePath, null);
|
|
|
+ fileService.createPagedPdfFiles(pdfFilePath);
|
|
|
// 生成纯数据excel
|
|
|
File file = new File(pdfFilePath.replace(".pdf", ".xls"));
|
|
|
// 文件无效(不存在或过期),创建
|
|
|
- if (!isFileValid(file.getPath())) {
|
|
|
+ if (!fileService.isFileValid(file.getPath(), fileService.getJrxmlFilePath(userName, reportName))) {
|
|
|
byte[] data = export(userName, profile, reportName, whereCondition, otherParameters,
|
|
|
"xls_with_only_data");
|
|
|
if (ArrayUtils.isEmpty(data)) {
|
|
|
throw new ReportException("报表导出失败:" + reportName);
|
|
|
}
|
|
|
- writeDataToFile(file.getPath(), data);
|
|
|
+ FileUtils.create(file.getPath(), data);
|
|
|
}
|
|
|
}
|
|
|
}).start();
|
|
|
@@ -174,7 +152,7 @@ public class PrintServiceImpl implements PrintService {
|
|
|
* 页码
|
|
|
* @return 总页数
|
|
|
*/
|
|
|
- private Integer writePdfData(String userName, String profile, String reportName, String whereCondition,
|
|
|
+ private Integer createPdfFile(String userName, String profile, String reportName, String whereCondition,
|
|
|
String otherParameters, String pdfFilePath, Integer pageIndex) {
|
|
|
File file = new File(pdfFilePath);
|
|
|
Map<String, Object> result = preview(userName, profile, reportName, whereCondition, otherParameters, pageIndex);
|
|
|
@@ -187,100 +165,10 @@ public class PrintServiceImpl implements PrintService {
|
|
|
if (ArrayUtils.isEmpty(data) || pageSize == null) {
|
|
|
throw new ReportException("获取预览数据失败");
|
|
|
}
|
|
|
- writeDataToFile(file.getPath(), data);
|
|
|
+ FileUtils.create(file.getPath(), data);
|
|
|
return pageSize;
|
|
|
}
|
|
|
|
|
|
- @Override
|
|
|
- public void writeDataToFile(String filePath, byte[] data) {
|
|
|
- File file = new File(filePath);
|
|
|
- if (!file.getParentFile().exists()) {
|
|
|
- file.getParentFile().mkdirs();
|
|
|
- }
|
|
|
- try {
|
|
|
- FileOutputStream fos = new FileOutputStream(file);
|
|
|
- fos.write(data);
|
|
|
- fos.flush();
|
|
|
- logger.info("Writed file..." + file.getPath());
|
|
|
- fos.close();
|
|
|
- } catch (IOException e) {
|
|
|
- throw new ReportException(e).setDetailedMessage(e);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public void writePagedPdfFiles(String pdfFilePath) {
|
|
|
- try {
|
|
|
- PdfReader pdfReader = new PdfReader(pdfFilePath);
|
|
|
- for (int i = 1; i <= pdfReader.getNumberOfPages(); i++) {
|
|
|
- Document document = new Document();
|
|
|
- FileOutputStream fileOutputStream = new FileOutputStream(pdfFilePath.replace(".pdf", "_" + i + ".pdf"));
|
|
|
- PdfCopy pdfCopy = new PdfCopy(document, fileOutputStream);
|
|
|
- document.open();
|
|
|
- // 原pdf文件的每一页生成新的pdf
|
|
|
- pdfCopy.addPage(pdfCopy.getImportedPage(pdfReader, i));
|
|
|
- pdfCopy.close();
|
|
|
- // 不关闭,生成的pdf无法正常打开
|
|
|
- document.close();
|
|
|
- fileOutputStream.close();
|
|
|
- }
|
|
|
- pdfReader.close();
|
|
|
- } catch (IOException | DocumentException e) {
|
|
|
- throw new ReportException(e).setDetailedMessage(e);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public int getPageSize(String pdfFilePath) {
|
|
|
- try {
|
|
|
- return new PdfReader(pdfFilePath).getNumberOfPages();
|
|
|
- } catch (IOException e) {
|
|
|
- throw new ReportException(e).setDetailedMessage(e);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public String generateFileName(String userName, String reportName, String whereCondition, String otherParameters) {
|
|
|
- return generateFileName(userName, null, reportName, whereCondition, otherParameters);
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public String generateFileName(String userName, String profile, String reportName, String whereCondition,
|
|
|
- String otherParameters) {
|
|
|
- if (StringUtils.isEmpty(userName) || StringUtils.isEmpty(reportName)) {
|
|
|
- return null;
|
|
|
- }
|
|
|
- StringBuilder stringBuilder = new StringBuilder(userName);
|
|
|
- if (!StringUtils.isEmpty(profile)) {
|
|
|
- stringBuilder.append(profile);
|
|
|
- }
|
|
|
- if (!StringUtils.isEmpty(whereCondition)) {
|
|
|
- stringBuilder.append(whereCondition);
|
|
|
- }
|
|
|
- if (!StringUtils.isEmpty(otherParameters)) {
|
|
|
- stringBuilder.append(otherParameters);
|
|
|
- }
|
|
|
- // 文件名:reportName + hashCode
|
|
|
- return reportName + "_" + stringBuilder.toString().hashCode();
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public boolean isFileValid(String filePath) {
|
|
|
- if (!StringUtils.isEmpty(filePath)) {
|
|
|
- File file = new File(filePath);
|
|
|
- if (file.exists()) {
|
|
|
- long interval = new Date().getTime() - file.lastModified();
|
|
|
- // 剩余的有效期(最高为10分钟)
|
|
|
- long validity = 10 * 60 * 1000 - interval;
|
|
|
- if (validity > 0) {
|
|
|
- logger.info(file.getName() + " will be expired after " + validity / 1000.0 + "s");
|
|
|
- return true;
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- return false;
|
|
|
- }
|
|
|
-
|
|
|
/**
|
|
|
* 输出报表的数据
|
|
|
*
|
|
|
@@ -302,9 +190,8 @@ public class PrintServiceImpl implements PrintService {
|
|
|
// }
|
|
|
|
|
|
// 报表路径为报表根路径REPORT_DIR + 当前账套用户名userName
|
|
|
- String reportDir = new StringBuilder(sysConf.getLocalBaseDir()).append("/").append(userName).toString();
|
|
|
- String jrxmlFilePath = new StringBuilder(reportDir).append("/").append(sysConf.getLocalJrxmlDir()).append("/")
|
|
|
- .append(reportName).append(".jrxml").toString();
|
|
|
+ String reportDir = fileService.getMasterPath(userName);
|
|
|
+ String jrxmlFilePath = fileService.getJrxmlFilePath(userName, reportName);
|
|
|
File jrxmlFile = new File(jrxmlFilePath);
|
|
|
// 报表模板不存在
|
|
|
if (!jrxmlFile.exists()) {
|
|
|
@@ -416,102 +303,6 @@ public class PrintServiceImpl implements PrintService {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- /**
|
|
|
- * 根据当前账套用户名,从主数据库master表获取(UAS系统)账套数据库配置信息,作为报表模板的数据源
|
|
|
- *
|
|
|
- * @param userName
|
|
|
- * 当前账套用户名
|
|
|
- * @return
|
|
|
- */
|
|
|
- private DataSource getUASDataSource(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 (Exception e) {
|
|
|
- throw new ReportException(e).setDetailedMessage(e);
|
|
|
- } finally {
|
|
|
- try {
|
|
|
- if (resultSet != null) {
|
|
|
- resultSet.close();
|
|
|
- }
|
|
|
- } catch (SQLException e) {
|
|
|
- e.printStackTrace();
|
|
|
- }
|
|
|
- try {
|
|
|
- if (preparedStatement != null) {
|
|
|
- preparedStatement.close();
|
|
|
- }
|
|
|
- } catch (SQLException e) {
|
|
|
- e.printStackTrace();
|
|
|
- }
|
|
|
- try {
|
|
|
- if (connection != null) {
|
|
|
- connection.close();
|
|
|
- }
|
|
|
- } catch (SQLException e) {
|
|
|
- throw new ReportException(e).setDetailedMessage(e);
|
|
|
- }
|
|
|
- }
|
|
|
- return null;
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 根据当前账套用户名和profile配置,获取相应B2C、B2B数据源
|
|
|
- *
|
|
|
- * @param userName
|
|
|
- * 当前账套用户名
|
|
|
- * @param profile
|
|
|
- * 用于标识请求源(B2C、B2B)是正式、测试还是开发版本:prod、test、dev
|
|
|
- * @return
|
|
|
- */
|
|
|
- private DataSource getDataSource(String userName, String profile) {
|
|
|
- // 如果userName是B2C或B2B,直接获取配置好的B2C数据源(B2B数据源与B2C相同)
|
|
|
- if (userName.toUpperCase().startsWith("B2C") || userName.toUpperCase().startsWith("B2B")) {
|
|
|
- if (profile.equalsIgnoreCase("dev")) {
|
|
|
- return ContextUtils.getApplicationContext().getBean("b2cDevDataSource", DruidDataSource.class);
|
|
|
- } else if (profile.equalsIgnoreCase("test")) {
|
|
|
- return ContextUtils.getApplicationContext().getBean("b2cTestDataSource", DruidDataSource.class);
|
|
|
- } else if (profile.equalsIgnoreCase("prod")) {
|
|
|
- return ContextUtils.getApplicationContext().getBean("b2cProdDataSource", DruidDataSource.class);
|
|
|
- } else {
|
|
|
- throw new ReportException("profile只能为:dev、test或prod,不可为" + profile);
|
|
|
- }
|
|
|
- } else {
|
|
|
- throw new ReportException("暂时不支持" + userName);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
/**
|
|
|
* 以不同的格式导出报表
|
|
|
*
|