| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384 |
- package com.uas.report.controller;
- import java.io.File;
- import java.io.FileInputStream;
- import java.io.IOException;
- import java.io.OutputStream;
- import java.net.URLEncoder;
- import java.util.HashMap;
- import java.util.Map;
- import javax.servlet.ServletException;
- import javax.servlet.http.HttpServletRequest;
- import javax.servlet.http.HttpServletResponse;
- import org.slf4j.Logger;
- import org.slf4j.LoggerFactory;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.stereotype.Controller;
- import org.springframework.web.bind.annotation.RequestMapping;
- import org.springframework.web.bind.annotation.ResponseBody;
- import com.uas.report.core.exception.ReportException;
- import com.uas.report.service.FileService;
- import com.uas.report.service.PrintService;
- import com.uas.report.util.ArrayUtils;
- import com.uas.report.util.FileUtils;
- import com.uas.report.util.ReportConstants;
- import com.uas.report.util.ReportUtils;
- import com.uas.report.util.StringUtils;
- /**
- * 报表打印
- *
- * @author sunyj
- * @since 2016年8月16日 下午3:49:02
- */
- @Controller
- @RequestMapping("/print")
- public class PrintController {
- @Autowired
- private PrintService printService;
- @Autowired
- private FileService fileService;
- private static Logger logger = LoggerFactory.getLogger(PrintController.class);
- /**
- * 为UAS系统打印提供服务, 根据printType进行预览、打印、下载pdf、下载纯数据excel等操作
- *
- * @param userName
- * 不为null;当前账套名称
- * @param profile
- * 可选(UAS等系统不必传递该参数),用于标识请求源(B2C、B2B)是正式、测试还是开发版本:prod、test、dev
- * @param reportName
- * 不为null;需要导出的报表的名称,不带任何后缀(如导出采购单,即为"Purchase")
- * @param whereCondition
- * 可为null;where之后的条件(包括where)
- * @param otherParameters
- * 若模板已指定需要的参数,则不可为null;其他参数,区别于whereCondition,报表某些字段的值取决于这些参数;
- * JSON格式,数据为键值对
- * @param printType
- * 打印类型,可为PREVIEW_PRINT_TYPE、PRINT_PRINT_TYPE、PDF_PRINT_TYPE、
- * EXCEL_PRINT_TYPE
- * @param title
- * 导出为文件时的名称
- * @param request
- * @param response
- */
- @RequestMapping()
- public void print(String userName, String profile, String reportName, String whereCondition, String otherParameters,
- String printType, String title, HttpServletRequest request, HttpServletResponse response) {
- userName = userName == null ? null : userName.toUpperCase();
- // printType为空,默认进入预览页
- if (StringUtils.isEmpty(printType)) {
- printType = ReportConstants.PREVIEW_PRINT_TYPE;
- }
- // 预览或打印
- if (printType.equals(ReportConstants.PREVIEW_PRINT_TYPE)
- || printType.equals(ReportConstants.PRINT_PRINT_TYPE)) {
- try {
- request.getRequestDispatcher("preview").forward(request, response);
- } catch (IOException | ServletException e) {
- throw new ReportException(e).setDetailedMessage(e);
- }
- }
- // 下载pdf、纯数据excel
- else if (printType.equals(ReportConstants.PDF_PRINT_TYPE)) {
- export(userName, profile, reportName, whereCondition, otherParameters, ReportConstants.PDF_FILE_TYPE, true,
- title, request, response);
- }
- // 该下载接口供UAS系统使用,应其要求,EXCEL_PRINT_TYPE只能为EXCEL(该值意思本应为下载全部数据的excel),
- // 导致与EXCEL_WITH_ONLY_DATA_FILE_TYPE(下载纯数据的excel)命名不相匹配
- else if (printType.equals(ReportConstants.EXCEL_PRINT_TYPE)) {
- export(userName, profile, reportName, whereCondition, otherParameters,
- ReportConstants.EXCEL_WITH_ONLY_DATA_FILE_TYPE, true, title, request, response);
- }
- // 下载word
- else if (printType.equals(ReportConstants.WORD_PRINT_TYPE)) {
- export(userName, profile, reportName, whereCondition, otherParameters, ReportConstants.WORD_FILE_TYPE, true,
- title, request, response);
- } else {
- throw new ReportException("printType不合法");
- }
- }
- /**
- * 导出报表
- *
- * @param userName
- * 不为null;当前账套名称
- * @param profile
- * 可选(UAS等系统不必传递该参数),用于标识请求源(B2C、B2B)是正式、测试还是开发版本:prod、test、dev
- * @param reportName
- * 不为null;需要导出的报表的名称,不带任何后缀(如导出采购单,即为"Purchase")
- * @param whereCondition
- * 可为null;where之后的条件(包括where)
- * @param otherParameters
- * 若模板已指定需要的参数,则不可为null;其他参数,区别于whereCondition,报表某些字段的值取决于这些参数;
- * JSON格式,数据为键值对
- * @param exportFileType
- * 报表导出的格式,默认为pdf
- * @param flush
- * 是否强制刷新pdf、xls
- * @param title
- * 导出为文件时的名称
- * @param request
- * @param response
- */
- @RequestMapping("/export")
- @ResponseBody
- public void export(String userName, String profile, String reportName, String whereCondition,
- String otherParameters, String exportFileType, Boolean flush, String title, HttpServletRequest request,
- HttpServletResponse response) {
- userName = userName == null ? null : userName.toUpperCase();
- ReportUtils.checkParameters(userName, reportName);
- if (printService.overload(userName, profile, reportName, whereCondition, otherParameters)) {
- throw new ReportException("数据量过大,无法提供服务");
- }
- String masterOfJrxml = printService.getMasterOfJrxml(userName, reportName);
- if (StringUtils.isEmpty(exportFileType)) {
- exportFileType = ReportConstants.PDF_FILE_TYPE;
- }
- byte[] data = null;
- String filePath = ReportConstants.GENERATED_FILES_PATH + reportName + "/" + fileService
- .generateFileName(userName, profile, reportName, whereCondition, otherParameters, exportFileType);
- if (exportFileType.equals(ReportConstants.EXCEL_WITH_ONLY_DATA_FILE_TYPE)) {
- filePath += "." + ReportConstants.EXCEL_FILE_TYPE;
- } else {
- filePath += "." + exportFileType;
- }
- File file = new File(ReportConstants.GENERATED_FILES_DIR + filePath);
- // 指定flush为true(强制刷新pdf、xls)
- // 文件无效(不存在或过期),创建
- if ((flush != null && flush.booleanValue())
- || !fileService.isFileValid(file.getPath(), fileService.getJrxmlFilePath(masterOfJrxml, reportName))) {
- data = printService.export(userName, profile, reportName, whereCondition, otherParameters, exportFileType);
- if (ArrayUtils.isEmpty(data)) {
- throw new ReportException("报表导出失败:" + userName + "/" + reportName + "\n");
- }
- FileUtils.write(file.getPath(), data);
- } else {
- FileInputStream fileInputStream = null;
- try {
- fileInputStream = new FileInputStream(file);
- data = new byte[fileInputStream.available()];
- fileInputStream.read(data);
- } catch (IOException e) {
- throw new ReportException(e).setDetailedMessage(e);
- } finally {
- if (fileInputStream != null) {
- try {
- fileInputStream.close();
- } catch (IOException e) {
- throw new ReportException(e).setDetailedMessage(e);
- }
- }
- }
- }
- try {
- String exportFileName = title;
- if (StringUtils.isEmpty(exportFileName)) {
- exportFileName = reportName;
- }
- if (exportFileType.equals(ReportConstants.EXCEL_WITH_ONLY_DATA_FILE_TYPE)) {
- exportFileName += "." + ReportConstants.EXCEL_FILE_TYPE;
- } else {
- exportFileName += "." + exportFileType;
- }
- response.setHeader("Content-Disposition",
- "attachment;filename=" + URLEncoder.encode(exportFileName, "UTF-8"));
- OutputStream outputStream = response.getOutputStream();
- outputStream.write(data);
- outputStream.flush();
- outputStream.close();
- } catch (IOException e) {
- logger.error("浏览器重复请求!");
- }
- }
- /**
- * 报表预览时获取pdf流
- *
- * @param userName
- * 不为null;当前账套名称
- * @param profile
- * 可选(UAS等系统不必传递该参数),用于标识请求源(B2C、B2B)是正式、测试还是开发版本:prod、test、dev
- * @param reportName
- * 不为null;需要预览的报表的名称,不带任何后缀(如预览采购单,即为"Purchase")
- * @param whereCondition
- * 可为null;where之后的条件(包括where)
- * @param otherParameters
- * 若模板已指定需要的参数,则不可为null;其他参数,区别于whereCondition,报表某些字段的值取决于这些参数;
- * JSON格式,数据为键值对
- * @param pageIndex
- * 分页展示,当前页码,从0开始
- * @param flush
- * 是否强制刷新pdf、xls
- * @param request
- * @param response
- * @return 包括pageSize、pdfPath
- */
- @RequestMapping(value = "/loadPdfData")
- @ResponseBody
- public Map<String, Object> loadPdfData(String userName, final String profile, final String reportName,
- final String whereCondition, final String otherParameters, Integer pageIndex, Boolean flush,
- HttpServletRequest request, HttpServletResponse response) {
- userName = userName == null ? null : userName.toUpperCase();
- ReportUtils.checkParameters(userName, reportName);
- if (printService.overload(userName, profile, reportName, whereCondition, otherParameters)) {
- throw new ReportException("数据量过大,无法提供服务");
- }
- String masterOfJrxml = printService.getMasterOfJrxml(userName, reportName);
- Map<String, Object> result = new HashMap<>();
- // 相对路径,返回给前端
- String pdfPath = ReportConstants.GENERATED_FILES_PATH + reportName + "/"
- + fileService.generateFileName(userName, profile, reportName, whereCondition, otherParameters,
- ReportConstants.PDF_FILE_TYPE)
- + "." + ReportConstants.PDF_FILE_TYPE;
- final File file = new File(ReportConstants.GENERATED_FILES_DIR + pdfPath);
- if (pageIndex == null || pageIndex == 1) {
- // 指定flush为true(强制刷新pdf)
- // 文件无效(不存在或过期),重新创建pdf文件
- if ((flush != null && flush.booleanValue()) || !fileService.isFileValid(file.getPath(),
- fileService.getJrxmlFilePath(masterOfJrxml, reportName))) {
- // 参数pageIndex为null或1,表示是直接打印或预览第一页,
- // 需要生成第一页(可能页数过多,提示用户不支持预览打印),再在后台开线程生成总的pdf
- // 先生成第一页pdf
- Integer pageSize = printService.createPdfFile(userName, profile, reportName, whereCondition,
- otherParameters, file.getPath().replace("." + ReportConstants.PDF_FILE_TYPE,
- "_1." + ReportConstants.PDF_FILE_TYPE),
- 1);
- result.put("pageSize", pageSize);
- // 再开线程生成后面页的pdf、总的pdf(即未分页的pdf)
- final String userNameCopy = userName;
- new Thread(new Runnable() {
- @Override
- public void run() {
- // 生成总的pdf
- printService.createPdfFile(userNameCopy, profile, reportName, whereCondition, otherParameters,
- file.getPath(), null);
- fileService.createPagedPdfFiles(file.getPath());
- }
- }).start();
- } else {
- result.put("pageSize", fileService.getPageSize(file.getPath()));
- }
- } else {
- // 文件无效(不存在或过期),重新创建pdf文件
- if (!fileService.isFileValid(
- file.getPath().replace("." + ReportConstants.PDF_FILE_TYPE,
- "_" + pageIndex + "." + ReportConstants.PDF_FILE_TYPE),
- fileService.getJrxmlFilePath(masterOfJrxml, reportName))) {
- printService.createPdfFile(userName, profile, reportName, whereCondition, otherParameters,
- file.getPath().replace("." + ReportConstants.PDF_FILE_TYPE,
- "_" + pageIndex + "." + ReportConstants.PDF_FILE_TYPE),
- pageIndex);
- }
- }
- result.put("pdfPath", pdfPath);
- return result;
- }
- /**
- * 获取pdf数据(该接口暂时供手机端访问)
- *
- * @param userName
- * 不为null;当前账套名称
- * @param profile
- * 可选(UAS等系统不必传递该参数),用于标识请求源(B2C、B2B)是正式、测试还是开发版本:prod、test、dev
- * @param reportName
- * 不为null;需要预览的报表的名称,不带任何后缀(如预览采购单,即为"Purchase")
- * @param whereCondition
- * 可为null;where之后的条件(包括where)
- * @param otherParameters
- * 若模板已指定需要的参数,则不可为null;其他参数,区别于whereCondition,报表某些字段的值取决于这些参数;
- * JSON格式,数据为键值对
- * @param request
- * @param response
- * @return 包括pageSize、data(或overload)
- */
- @RequestMapping(value = "/pdfData")
- @ResponseBody
- public Map<String, Object> getPdfData(String userName, String profile, String reportName, String whereCondition,
- String otherParameters, HttpServletRequest request, HttpServletResponse response) {
- userName = userName == null ? null : userName.toUpperCase();
- ReportUtils.checkParameters(userName, reportName);
- Map<String, Object> result = new HashMap<>();
- // 判断是否过载
- if (printService.overload(userName, profile, reportName, whereCondition, otherParameters)) {
- result.put("data", "");
- result.put("pageSize", 0);
- result.put("overload", true);
- } else {
- result = printService.preview(userName, profile, reportName, whereCondition, otherParameters, null);
- result.put("overload", false);
- }
- return result;
- }
- /**
- * 获取生成的pdf或者xls的信息
- *
- * @param userName
- * 不为null;当前账套名称
- * @param profile
- * 可选(UAS等系统不必传递该参数),用于标识请求源(B2C、B2B)是正式、测试还是开发版本:prod、test、dev
- * @param reportName
- * 不为null;需要预览的报表的名称,不带任何后缀(如预览采购单,即为"Purchase")
- * @param whereCondition
- * 可为null;where之后的条件(包括where)
- * @param otherParameters
- * 若模板已指定需要的参数,则不可为null;其他参数,区别于whereCondition,报表某些字段的值取决于这些参数;
- * JSON格式,数据为键值对
- * @param fileType
- * 文件格式,pdf、xls、xls_with_only_data
- * @param request
- * @return 文件的信息
- */
- @RequestMapping(value = "/getGeneratedPdfOrXlsInformation")
- @ResponseBody
- public Map<String, Object> getGeneratedPdfOrXlsInformation(String userName, String profile, String reportName,
- String whereCondition, String otherParameters, String fileType, HttpServletRequest request) {
- userName = userName == null ? null : userName.toUpperCase();
- ReportUtils.checkParameters(userName, reportName);
- Map<String, Object> result = new HashMap<>();
- if (StringUtils.isEmpty(fileType)) {
- fileType = ReportConstants.PDF_FILE_TYPE;
- }
- String filePath = ReportConstants.GENERATED_FILES_PATH + reportName + "/" + fileService
- .generateFileName(userName, profile, reportName, whereCondition, otherParameters, fileType);
- File file = null;
- String masterOfJrxml = printService.getMasterOfJrxml(userName, reportName);
- if (fileType.equals(ReportConstants.PDF_FILE_TYPE)) {
- file = new File(ReportConstants.GENERATED_FILES_DIR + filePath + "." + ReportConstants.PDF_FILE_TYPE);
- result.put("valid",
- fileService.isFileValid(file.getPath(), fileService.getJrxmlFilePath(masterOfJrxml, reportName)));
- result.put("size", file.length());
- } else if (fileType.equals(ReportConstants.EXCEL_FILE_TYPE)) {
- file = new File(ReportConstants.GENERATED_FILES_DIR + filePath + "." + ReportConstants.EXCEL_FILE_TYPE);
- result.put("valid",
- fileService.isFileValid(file.getPath(), fileService.getJrxmlFilePath(masterOfJrxml, reportName)));
- result.put("size", file.length());
- } else if (fileType.equals(ReportConstants.EXCEL_WITH_ONLY_DATA_FILE_TYPE)) {
- file = new File(ReportConstants.GENERATED_FILES_DIR + filePath + "." + ReportConstants.EXCEL_FILE_TYPE);
- result.put("valid",
- fileService.isFileValid(file.getPath(), fileService.getJrxmlFilePath(masterOfJrxml, reportName)));
- result.put("size", file.length());
- } else {
- throw new ReportException("fileType只能为pdf、xls、xls_with_only_data");
- }
- result.put("file", file.getPath());
- return result;
- }
- }
|