//IE下找不到pdf.worker.js,需要手动赋值 PDFJS.workerSrc = 'static/lib/pdf.js/build/pdf.worker.js'; var canvas = document.getElementById('theCanvas'); var ctx = canvas.getContext('2d'); // 隐藏的iframe,用于加载pdf,以便打印(pdf.js自带的打印有问题) 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 pageSize; // 预览的pdf的缩放级别(为pdf原大小的倍数) var scale; // 浏览器窗口高度 var winHeight; // 浏览器窗口宽度 var winWidth; // 将要打印的总的pdf(整个文档,而不是某一页的pdf)相对路径 var wholePdfPath; // 某一页pdf文件的路径 var pagedPdfPath; // 参数打印类型,可能为PRINT、PREVIEW var printType = getParameter("printType"); // 首次加载页面() var firstRequest = true; // 记录刚加载该页面时的时间 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加载错误,请刷新页面!"; getWindowWidth(); loadData(1); // 缩小,最小不小于原大小的0.2/1.2倍 $("#zoomOut").click(function() { if (scale >= 0.2) { scale = scale / 1.2; changeTextOfSelectScale() renderPage(); } }); // 放大,最大不大于原大小的5*1.2倍 $("#zoomIn").click(function() { if (scale <= 5) { scale = scale * 1.2; changeTextOfSelectScale() renderPage(); } }); // 选择缩放倍数 $("#scaleSelect").change(function() { scale = this.value; renderPage(); }); // 上页 $("#prev").click(prevPage); // 下页 $("#next").click(nextPage); // 手动输入页码 $("#pageIndex").keypress(function(event) { if (!pdfDoc) { return; } // 按Enter键 if (event.keyCode == 13) { var value = document.getElementById("pageIndex").value; // 以非0开头的整数 var regExp = /^([1-9]+\d*)$/; if (regExp.test(value) && value >= 1 && value <= pageSize) { if (value == pageIndex) { return; } if (pageSize > PRINT_MAX_PAGE_SIZE) { alert(ALERT_FILE_TOO_LARGE); return; } pageIndex = value; if (timeout()) { return; } loadData(pageIndex); } else { document.getElementById("pageIndex").value = pageIndex; } } }); // 打印 $("#print").click(function() { if (!pdfDoc) { return; } printPdf(); }); // 下载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; } // 下载纯数据excel $("#downloadExcel").click(function() { if (!pdfDoc) { return; } window.open(downloadUrl("xls")); }); // 下载纯数据excel $("#downloadExcelWithOnlyData").click(function() { if (!pdfDoc) { return; } window.open(downloadUrl("xls_with_only_data")); }); // 键盘左右键进行翻页 $("body").keydown(function(event) { // 如果在选中input输入框或select下拉列表时按左右键,不进行翻页 var activeElementNodeName = document.activeElement.nodeName.toLowerCase(); if (activeElementNodeName == "input" || activeElementNodeName == "select") { return; } if (event.keyCode == 37) {// left prevPage(); } else if (event.keyCode == 39) {// right nextPage(); } }); /** * 获取窗口宽度 */ function getWindowWidth() { if (window.innerWidth) winWidth = window.innerWidth; else if ((document.body) && (document.body.clientWidth)) winWidth = document.body.clientWidth; // 获取窗口高度 if (window.innerHeight) winHeight = window.innerHeight; else if ((document.body) && (document.body.clientHeight)) winHeight = document.body.clientHeight; // 通过深入 Document 内部对 body 进行检测,获取窗口大小 if (document.documentElement && document.documentElement.clientHeight && document.documentElement.clientWidth) { winHeight = document.documentElement.clientHeight; winWidth = document.documentElement.clientWidth; } } /** * 打印 */ function printPdf() { spinner = hideLoading(spinner); if (pageSize > PRINT_MAX_PAGE_SIZE) { alert(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_) { // 更新页码 document.getElementById('pageIndex').value = pageIndex; pdfDoc = pdfDoc_; // 第一页文档渲染完成后,再加载整个文档 if (ifPreloadWholePdf) { if (printType == 'PRINT' && pageSize > PRINT_MAX_PAGE_SIZE) { alert(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); spinner = showLoading(spinner, spinnerContainer); pageIndex = page || 1; var loadPdfDataUrl = "print/loadPdfData" + window.location.search; loadPdfDataUrl = loadPdfDataUrl + "&pageIndex=" + pageIndex; $.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.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); } }, error : function(XMLHttpRequest) { $("#theCanvas").remove(); spinner = hideLoading(spinner); $("#errorMessageContainer").removeAttr("hidden"); // 处理后台传输的自定义的换行标志 var result = JSON.parse(XMLHttpRequest.responseText); var message = result.message; $("#message").html(message); if (result.detailedMessage) { $("#detailedMessageButton").removeAttr("hidden"); } $("#detailedMessageButton").click(function() { $("#detailedMessage").html(result.detailedMessage); $("#detailedMessage").removeAttr("hidden"); }); } }); }; /** * 预加载整个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); } } /** * 每隔一定时间查询文件状态,直到文件有效 */ function waitWholePdfGenerated() { waitWholePdfGeneratedCount++; if (waitWholePdfGeneratedCount >= MAX_WAIT_WHOLE_PDF_GENERATED) { alert(ALERT_WAIT_WHOLE_PDF_GENERATED_TOO_LARGE); window.location.reload(); 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() { 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; }); }); } /** * 获取缩放级别(将pdf显示的宽度调整为窗口宽度的multipleOfWindowWidth倍,获取该情况下pdf宽度为原宽度的倍数) * * @param page * pdf数据 * @param multipleOfWindowWidth * 窗口宽度的倍数 * @returns {Number} 缩放级别(pdf原宽度的倍数) */ function getScale(page, multipleOfWindowWidth) { // 首先获取pdf原始宽度 var viewportWidth = page.getViewport(1).width; return multipleOfWindowWidth / (viewportWidth / winWidth); } /** * 预览前一页 */ function prevPage() { // 验证pdfDoc不存在,是为了避免报表出现编译失败等问题时,仍然试图翻页 if (!pdfDoc || pageIndex <= 1) { return; } if (timeout()) { return; } // 获取前一页的pdf pageIndex--; loadData(pageIndex); } /** * 预览后一页 */ function nextPage() { if (!pdfDoc || pageIndex >= pageSize) { return; } if (pageSize > PRINT_MAX_PAGE_SIZE) { alert(ALERT_FILE_TOO_LARGE); return; } if (timeout()) { return; } pageIndex++; loadData(pageIndex); } /** * 修改缩放下拉框所显示的内容 */ function changeTextOfSelectScale() { var hiddenOption = document.getElementById("hiddenOption"); hiddenOption.removeAttribute("hidden"); hiddenOption.text = (scale * 100).toFixed() + "%"; hiddenOption.selected = true; hiddenOption.hidden = true; } /** * 下载报表 * * @param exportFileType * 导出文件的格式 * @returns {String} 下载链接 */ function downloadUrl(exportFileType) { var downloadUrl = "print/export" + window.location.search; exportFileType = exportFileType || "pdf"; // 导出文件的格式 downloadUrl += "&exportFileType=" + exportFileType; return downloadUrl; } /** * 检查浏览器并提示 */ function checkBrowser() { var userAgent = navigator.userAgent; console.log(userAgent); if (userAgent.indexOf("Chrome") == -1 || userAgent.indexOf("Edge") !== -1) { alert("建议使用最新版Chrome浏览器进行打印"); } } /** * 检查页面是否已过期 * * @returns {Boolean} true,如果已过期 */ function timeout() { var now = new Date(); if (now - startTime >= MAX_TIME) { alert(ALERT_TIMEOUT); window.location.reload(); return true; } return false; }