浏览代码

重新组织pdf预览的实现方式

sunyj 8 年之前
父节点
当前提交
b2f52f4917
共有 2 个文件被更改,包括 109 次插入382 次删除
  1. 5 75
      src/main/java/com/uas/report/controller/PrintController.java
  2. 104 307
      src/main/webapp/resources/js/preview/app.js

+ 5 - 75
src/main/java/com/uas/report/controller/PrintController.java

@@ -145,8 +145,8 @@ public class PrintController {
 
 		byte[] data = null;
 
-		String filePath = ReportConstants.GENERATED_FILES_PATH + reportName + "/" + fileService
-				.generateFileName(userName, profile, reportName, whereCondition, otherParameters, exportFileType);
+		String filePath = ReportConstants.GENERATED_FILES_PATH + reportName + "/"
+				+ fileService.generateFileName(userName, profile, whereCondition, otherParameters, exportFileType);
 		if (exportFileType.equals(ReportConstants.EXCEL_WITH_ONLY_DATA_FILE_TYPE)) {
 			filePath += "." + ReportConstants.EXCEL_FILE_TYPE;
 		} else {
@@ -238,9 +238,8 @@ public class PrintController {
 		Map<String, Object> result = new HashMap<>();
 
 		// 相对路径,返回给前端
-		String pdfPath = ReportConstants.GENERATED_FILES_PATH + reportName + "/"
-				+ fileService.generateFileName(userName, profile, reportName, whereCondition, otherParameters,
-						ReportConstants.PDF_FILE_TYPE)
+		String pdfPath = ReportConstants.GENERATED_FILES_PATH + reportName + "/" + fileService
+				.generateFileName(userName, profile, 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) {
@@ -256,21 +255,8 @@ public class PrintController {
 				// 需要生成第一页(可能页数过多,提示用户不支持预览打印),再在后台开线程生成总的pdf
 				// 先生成第一页pdf
 				Integer pageSize = printService.createPdfFile(userName, profile, reportName, whereCondition,
-						otherParameters, file.getPath().replace("." + ReportConstants.PDF_FILE_TYPE,
-								"_1." + ReportConstants.PDF_FILE_TYPE),
-						1);
+						otherParameters, file.getPath(), null);
 				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()));
 			}
@@ -327,60 +313,4 @@ public class PrintController {
 		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;
-	}
-
 }

+ 104 - 307
src/main/webapp/resources/js/preview/app.js

@@ -8,14 +8,13 @@ var hiddenFrame = document.getElementById("hiddenFrame");
 // 用于显示正在加载的提示
 var spinner;
 var spinnerContainer = document.getElementById('viewerContainer');
-
 // 能打印的最大页数(页数超过,需要先下载pdf,再打印)
 var PRINT_MAX_PAGE_SIZE = 200;
 var ALERT_FILE_TOO_LARGE = "PDF超过" + PRINT_MAX_PAGE_SIZE
 		+ "页,建议先下载到本地,再进行查看或打印";
 var pdfDoc;
 // 页码
-var pageIndex;
+var pageIndex = 1;
 // 总页数
 var pageSize;
 // 预览的pdf的缩放级别(为pdf原大小的倍数)
@@ -24,37 +23,24 @@ var scale;
 var winHeight;
 // 浏览器窗口宽度
 var winWidth;
-// 将要打印的总的pdf(整个文档,而不是某一页的pdf)相对路径
-var wholePdfPath;
-// 某一页pdf文件的路径
-var pagedPdfPath;
+// 将要打印的pdf相对路径
+var pdfPath;
 // 参数打印类型,可能为PRINT、PREVIEW
 var printType = getParameter("printType");
-// 首次加载页面
-var firstRequest = true;
-//用于标识是否正在翻页,防止连续快速翻页,影响展示效果
-var paging = false;
-
-// 记录刚加载该页面时的时间
-var startTime = new Date();
-// 记录查询完整pdf状态的次数
-var waitWholePdfGeneratedCount = 0;
-// 页面过期时间为10分钟,之后必须重新加载
-var MAX_TIME = 10 * 60 * 1000;
-// 查询总的pdf状态的次数最高为100次,超过后需要重新加载页面
-var MAX_WAIT_WHOLE_PDF_GENERATED = 100;
-var ALERT_TIMEOUT = "页面已过期,请刷新页面!";
-var ALERT_WAIT_WHOLE_PDF_GENERATED_TOO_LARGE = "PDF加载错误,请刷新页面!";
+// 是否正在渲染页面
+var rendering = false;
+// 下一个要渲染的页面
+var nextRenderingPage;
 
 getWindowWidth();
-loadData(1);
+loadData();
 
 // 缩小,最小不小于原大小的0.2/1.2倍
 $("#zoomOut").click(function() {
 	if (scale >= 0.2) {
 		scale = scale / 1.2;
-		changeTextOfSelectScale()
-		renderPage();
+		changeTextOfSelectScale();
+		renderPage(pageIndex);
 	}
 });
 
@@ -62,15 +48,15 @@ $("#zoomOut").click(function() {
 $("#zoomIn").click(function() {
 	if (scale <= 5) {
 		scale = scale * 1.2;
-		changeTextOfSelectScale()
-		renderPage();
+		changeTextOfSelectScale();
+		renderPage(pageIndex);
 	}
 });
 
 // 选择缩放倍数
 $("#scaleSelect").change(function() {
 	scale = this.value;
-	renderPage();
+	renderPage(pageIndex);
 });
 
 // 上页
@@ -97,11 +83,8 @@ $("#pageIndex").keypress(function(event) {
 				alert(spinnerContainer, ALERT_FILE_TOO_LARGE);
 				return;
 			}
-			pageIndex = value;
-			if (timeout()) {
-				return;
-			}
-			loadData(pageIndex);
+			pageIndex = parseInt(value);
+			renderPage(pageIndex);
 		} else {
 			document.getElementById("pageIndex").value = pageIndex;
 		}
@@ -117,33 +100,12 @@ $("#print").click(function() {
 });
 
 // 下载pdf
-$("#downloadPdf").click(
-		function() {
-			if (!pdfDoc) {
-				return;
-			}
-			if (timeout()) {
-				return;
-			}
-			console.log(new Date().format()
-					+ " ---- subscribed wholePdfGeneratedSignal");
-			$.subscribe("wholePdfGeneratedSignal", downloadPdf);
-			spinner = showLoading(spinner, spinnerContainer);
-			waitWholePdfGenerated();
-		});
-
-/**
- * 下载文件
- */
-function downloadPdf() {
-	spinner = hideLoading(spinner);
-	console.log(new Date().format()
-			+ " ---- received and unsubscribe wholePdfGeneratedSignal");
-	$.unsubscribe("wholePdfGeneratedSignal", downloadPdf);
-	console.log(new Date().format() + " ---- start download...");
-	window.location = downloadUrl("pdf");
-	hiddenFrame.src = wholePdfPath;
-}
+$("#downloadPdf").click(function() {
+	if (!pdfDoc) {
+		return;
+	}
+	window.open(downloadUrl("pdf"));
+});
 
 // 下载word
 $("#downloadWord").click(function() {
@@ -204,120 +166,30 @@ function getWindowWidth() {
 	}
 }
 
-/**
- * 打印
- */
-function printPdf() {
-	spinner = hideLoading(spinner);
-	if (pageSize > PRINT_MAX_PAGE_SIZE) {
-		alert(spinnerContainer, ALERT_FILE_TOO_LARGE);
-		return;
-	}
-	if (!pdfDoc) {
-		return;
-	}
-	if (timeout()) {
-		return;
-	}
-	console.log(new Date().format()
-			+ " ---- subscribed wholePdfGeneratedSignal");
-	$.subscribe("wholePdfGeneratedSignal", print);
-	spinner = showLoading(spinner, spinnerContainer);
-	waitWholePdfGenerated();
-}
-
-/**
- * 取消订阅信号,打印
- */
-function print() {
-	console.log(new Date().format()
-			+ " ---- received and unsubscribe wholePdfGeneratedSignal");
-	$.unsubscribe("wholePdfGeneratedSignal", print);
-	console.log(new Date().format() + " ---- start print...");
-	checkBrowser();
-	setTimeout(
-			"hiddenFrame.contentWindow.print();spinner = hideLoading(spinner)",
-			1000);
-}
-
-/**
- * 获取预览的pdf文档数据,完成后加载整个文档
- * 
- * @param pagedPdfPath
- *            需要进行预览的分页pdf相对路径
- * @param ifPreloadWholePdf
- *            渲染之后,是否预加载整个文档
- */
-function loadPagedPdf(pagedPdfPath, ifPreloadWholePdf) {
-	// var dfd = $.Deferred();
-	PDFJS
-			.getDocument(pagedPdfPath)
-			.then(
-					function(pdfDoc_) {
-						paging = false;
-						// 更新页码
-						document.getElementById('pageIndex').value = pageIndex;
-						pdfDoc = pdfDoc_;
-						// 第一页文档渲染完成后,再加载整个文档
-						if (ifPreloadWholePdf) {
-							if (printType == 'PRINT'
-									&& pageSize > PRINT_MAX_PAGE_SIZE) {
-								alert(spinnerContainer, ALERT_FILE_TOO_LARGE);
-								spinner = hideLoading(spinner);
-							} else {
-								console
-										.log(new Date().format()
-												+ " ---- subscribed wholePdfGeneratedSignal");
-								$.subscribe("wholePdfGeneratedSignal",
-										loadWholePdf);
-								spinner = showLoading(spinner, spinnerContainer);
-								waitWholePdfGenerated();
-							}
-						}
-						// Initial/first page rendering
-						renderPage();
-						// $.when(rend("getDocument promised");
-						// dfd.resolve();
-						// });
-					});
-	// return dfd.promise;
-}
-
 /**
  * 发送请求,服务器端进行填充报表、生成pdf文件等操作
  */
-function loadData(page) {
-	ctx.clearRect(0, 0, canvas.width, canvas.height);
+function loadData() {
 	spinner = showLoading(spinner, spinnerContainer);
-	pageIndex = page || 1;
-	var loadPdfDataUrl = "print/loadPdfData" + window.location.search;
-	loadPdfDataUrl = loadPdfDataUrl + "&pageIndex=" + pageIndex;
-	// 如果是第一次请求(并不是在当前页面进行页码跳转),则强制刷新pdf
-	if (firstRequest) {
-		loadPdfDataUrl = loadPdfDataUrl + "&flush=true";
-	}
+	var loadPdfDataUrl = "print/loadPdfData" + window.location.search
+			+ "&flush=true";
 	$.ajax({
 		type : "get",
 		async : false,
 		url : loadPdfDataUrl,
 		success : function(data) {
-			// 返回的pdf文件路径
-			wholePdfPath = data.pdfPath;
-			// 第pageIndex页的pdf文件路径
-			pagedPdfPath = wholePdfPath.replace(".pdf", "_" + pageIndex
-					+ ".pdf");
-			if (firstRequest) {
-				pageSize = data.pageSize;
+			document.title = getParameter("reportName");
+			pdfPath = data.pdfPath;
+			hiddenFrame.src = pdfPath;
+			PDFJS.getDocument(pdfPath).then(function(pdfDoc_) {
+				pdfDoc = pdfDoc_;
+				pageSize = pdfDoc.numPages;
 				document.getElementById('pageSize').textContent = pageSize;
-				document.title = getParameter("reportName");
-				// 加载第一页文档,并且预加载整个文档
-				loadPagedPdf(pagedPdfPath, true);
-				firstRequest = false;
-				// $.when(getDocument()).done(loadWholePdf);
-				// console.log(renderTask._internalRenderTask.running);
-			} else {
-				loadPagedPdf(pagedPdfPath);
-			}
+				renderPage(pageIndex);
+				if (printType == "PRINT") {
+					setTimeout("printPdf()", 1000);
+				}
+			});
 		},
 		error : function(XMLHttpRequest) {
 			$("#theCanvas").remove();
@@ -340,117 +212,50 @@ function loadData(page) {
 };
 
 /**
- * 预加载整个pdf(大于PRINT_MAX_PAGE_SIZE页,不加载)文件,以提高后续打印速度
- */
-function loadWholePdf() {
-	console.log(new Date().format()
-			+ " ---- received and unsubscribe wholePdfGeneratedSignal");
-	$.unsubscribe("wholePdfGeneratedSignal", loadWholePdf);
-	// 开始加载
-	console.log(new Date().format() + " ---- hiddenFrame loading...");
-	hiddenFrame.src = wholePdfPath;
-	if (printType == "PRINT") {
-		setTimeout("printPdf()", 1000);
-	}
-}
-
-/**
- * 每隔一定时间查询文件状态,直到文件有效
+ * Get page info from document, resize canvas accordingly, and render page
  */
-function waitWholePdfGenerated() {
-	waitWholePdfGeneratedCount++;
-	if (waitWholePdfGeneratedCount >= MAX_WAIT_WHOLE_PDF_GENERATED) {
-		alert(spinnerContainer, ALERT_WAIT_WHOLE_PDF_GENERATED_TOO_LARGE);
+function renderPage(pageIndex) {
+	if (rendering) {
+		nextRenderingPage = pageIndex;
 		return;
 	}
-	var valid = getGeneratedPdfOrXlsInformation("pdf").valid;
-	if (!valid) {
-		console.log(new Date().format() + " ---- 文件还未生成");
-		console.log(new Date().format() + " ---- wait 1000ms")
-		setTimeout("waitWholePdfGenerated()", 1000);
-	} else {
-		console.log(new Date().format() + " ---- 文件已生成");
-		console.log(new Date().format()
-				+ " ---- published wholePdfGeneratedSignal");
-		$.publish("wholePdfGeneratedSignal", waitWholePdfGenerated);
-	}
-}
-
-/**
- * 获取生成的pdf或者xls的信息
- * 
- * @param fileType
- *            文件格式,pdf、xls、xls_with_only_data
- */
-function getGeneratedPdfOrXlsInformation(fileType) {
-	var data;
-	$.ajax({
-		type : "get",
-		async : false,
-		url : "print/getGeneratedPdfOrXlsInformation" + window.location.search
-				+ "&fileType=" + fileType,
-		success : function(result) {
-			console
-					.log(new Date().format() + " ---- "
-							+ JSON.stringify(result));
-			data = result;
-		}
-	});
-	return data;
-}
-
-/**
- * Get page info from document, resize canvas accordingly, and render page
- */
-function renderPage() {
+	rendering = true;
+	// 更新页码
+	document.getElementById("pageIndex").value = pageIndex;
 	spinner = hideLoading(spinner);
-	if (firstRequest && printType == "PRINT" && pageSize <= PRINT_MAX_PAGE_SIZE) {
-		spinner = showLoading(spinner, spinnerContainer);
-	}
 	if (!pdfDoc) {
 		return;
 	}
-	// 每个pdf只有一页
-	pdfDoc
-			.getPage(1)
-			.then(
-					function(page) {
-						if (!scale || scale == "auto") {
-							// 调整为适合的宽度
-							scale = getScale(page, 0.75);
-						} else if (scale == "page_width") {
-							// 调整pdf显示的宽度接近窗口宽度
-							scale = getScale(page, 0.95);
-						}
-						var viewport = page.getViewport(scale);
-						canvas.height = viewport.height;
-						canvas.width = viewport.width;
-						// Render PDF page into canvas context
-						var renderContext = {
-							canvasContext : ctx,
-							viewport : viewport
-						};
-						// 开始渲染
-						var renderTask = page.render(renderContext);
-						$
-								.when(renderTask)
-								.done(
-										function() {
-											// 渲染完成后,发布信号
-											// "renderTaskFinishedSignal"
-											console
-													.log(new Date().format()
-															+ " ---- renderTask finished");
-											console
-													.log(new Date().format()
-															+ " ---- publish renderTaskFinishedSignal");
-											$
-													.publish("renderTaskFinishedSignal");
-											// var renderTaskRunning =
-											// renderTask._internalRenderTask.running;
-											// return !renderTaskRunning;
-										});
-					});
+	if (printType == "PRINT" && pageSize <= PRINT_MAX_PAGE_SIZE) {
+		spinner = showLoading(spinner, spinnerContainer);
+	}
+	pdfDoc.getPage(pageIndex).then(function(page) {
+		if (!scale || scale == "auto") {
+			// 调整为适合的宽度
+			scale = getScale(page, 0.75);
+		} else if (scale == "page_width") {
+			// 调整pdf显示的宽度接近窗口宽度
+			scale = getScale(page, 0.95);
+		}
+		var viewport = page.getViewport(scale);
+		canvas.height = viewport.height;
+		canvas.width = viewport.width;
+		// Render PDF page into canvas context
+		var renderContext = {
+			canvasContext : ctx,
+			viewport : viewport
+		};
+		// 开始渲染
+		var renderTask = page.render(renderContext);
+		renderTask.promise.then(function() {
+			rendering = false;
+			if (nextRenderingPage) {
+				pageIndex = nextRenderingPage;
+				renderPage(pageIndex);
+				nextRenderingPage = undefined;
+			}
+		});
+	});
 }
 
 /**
@@ -468,6 +273,17 @@ function getScale(page, multipleOfWindowWidth) {
 	return multipleOfWindowWidth / (viewportWidth / winWidth);
 }
 
+/**
+ * 修改缩放下拉框所显示的内容
+ */
+function changeTextOfSelectScale() {
+	var hiddenOption = document.getElementById("hiddenOption");
+	hiddenOption.removeAttribute("hidden");
+	hiddenOption.text = (scale * 100).toFixed() + "%";
+	hiddenOption.selected = true;
+	hiddenOption.hidden = true;
+}
+
 /**
  * 预览前一页
  */
@@ -476,15 +292,8 @@ function prevPage() {
 	if (!pdfDoc || pageIndex <= 1) {
 		return;
 	}
-	if (timeout()) {
-		return;
-	}
-	if (!paging) {
-		paging = true;
-		// 获取前一页的pdf
-		pageIndex--;
-		loadData(pageIndex);
-	}
+	pageIndex--;
+	renderPage(pageIndex);
 }
 
 /**
@@ -498,25 +307,27 @@ function nextPage() {
 		alert(spinnerContainer, ALERT_FILE_TOO_LARGE);
 		return;
 	}
-	if (timeout()) {
-		return;
-	}
-	if (!paging) {
-		paging = true;
-		pageIndex++;
-		loadData(pageIndex);
-	}
+	pageIndex++;
+	renderPage(pageIndex);
 }
 
 /**
- * 修改缩放下拉框所显示的内容
+ * 打印
  */
-function changeTextOfSelectScale() {
-	var hiddenOption = document.getElementById("hiddenOption");
-	hiddenOption.removeAttribute("hidden");
-	hiddenOption.text = (scale * 100).toFixed() + "%";
-	hiddenOption.selected = true;
-	hiddenOption.hidden = true;
+function printPdf() {
+	spinner = hideLoading(spinner);
+	if (pageSize > PRINT_MAX_PAGE_SIZE) {
+		alert(spinnerContainer, ALERT_FILE_TOO_LARGE);
+		return;
+	}
+	if (!pdfDoc) {
+		return;
+	}
+	spinner = showLoading(spinner, spinnerContainer);
+	checkBrowser();
+	setTimeout(
+			"hiddenFrame.contentWindow.print();spinner = hideLoading(spinner)",
+			1000);
 }
 
 /**
@@ -541,20 +352,6 @@ function checkBrowser() {
 	var userAgent = navigator.userAgent;
 	console.log(userAgent);
 	if (userAgent.indexOf("Chrome") == -1 || userAgent.indexOf("Edge") !== -1) {
-		alert(spinnerContainer, "建议使用最新版Chrome浏览器进行打印");
+		alert(spinnerContainer, "建议使用最新版Chrome浏览器打印");
 	}
-}
-
-/**
- * 检查页面是否已过期
- * 
- * @returns {Boolean} true,如果已过期
- */
-function timeout() {
-	var now = new Date();
-	if (now - startTime >= MAX_TIME) {
-		alert(spinnerContainer, ALERT_TIMEOUT);
-		return true;
-	}
-	return false;
-}
+}