app.js 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389
  1. //IE下找不到pdf.worker.js,需要手动赋值
  2. PDFJS.workerSrc = 'resources/lib/pdf.js/build/pdf.worker.js';
  3. var canvas = document.getElementById('theCanvas');
  4. var ctx = canvas.getContext('2d');
  5. // 隐藏的iframe,用于加载pdf,以便打印(pdf.js自带的打印有问题)
  6. var hiddenFrame = document.getElementById("hiddenFrame");
  7. // 用于显示正在加载的提示
  8. var spinner;
  9. var spinnerContainer = document.getElementById('viewerContainer');
  10. var pdfDoc;
  11. // 页码
  12. var pageIndex = 1;
  13. // 总页数
  14. var pageSize;
  15. // 预览的pdf的缩放级别(为pdf原大小的倍数)
  16. var scale;
  17. // 浏览器窗口高度
  18. var winHeight;
  19. // 浏览器窗口宽度
  20. var winWidth;
  21. // 将要打印的pdf相对路径
  22. var pdfPath;
  23. // 参数打印类型,可能为PRINT、PREVIEW
  24. var printType = getParameter("printType");
  25. // 是否正在渲染页面
  26. var rendering = false;
  27. // 下一个要渲染的页面
  28. var nextRenderingPage;
  29. var titleJson = {
  30. "Purchase" : "采购订单",
  31. "PurchaseIn" : "采购验收单",
  32. "PurchaseOut" : "采购验退单",
  33. "OtherIn" : "其它入库单",
  34. "OtherOut" : "其它出库单",
  35. "Sale" : "销售订单",
  36. "SaleOut" : "出货单",
  37. "SaleIn" : "销售退货单",
  38. "PayBalance" : "付款单",
  39. "OthReceipts" : "其它收入单",
  40. "OthSpendings" : "其它支出单",
  41. "Verification" : "核销单"
  42. };
  43. var title = titleJson[getParameter("reportName")];
  44. document.title = title ? title : getParameter("reportName");
  45. getWindowWidth();
  46. loadData();
  47. // 缩小,最小不小于原大小的0.2/1.2倍
  48. $("#zoomOut").click(function() {
  49. if (scale >= 0.2) {
  50. scale = scale / 1.2;
  51. changeTextOfSelectScale();
  52. renderPage(pageIndex);
  53. }
  54. });
  55. // 放大,最大不大于原大小的5*1.2倍
  56. $("#zoomIn").click(function() {
  57. if (scale <= 5) {
  58. scale = scale * 1.2;
  59. changeTextOfSelectScale();
  60. renderPage(pageIndex);
  61. }
  62. });
  63. // 选择缩放倍数
  64. $("#scaleSelect").change(function() {
  65. scale = this.value;
  66. renderPage(pageIndex);
  67. });
  68. // 上页
  69. $("#prev").click(prevPage);
  70. // 下页
  71. $("#next").click(nextPage);
  72. // 手动输入页码
  73. $("#pageIndex").keypress(function(event) {
  74. if (!pdfDoc) {
  75. return;
  76. }
  77. // 按Enter键
  78. if (event.keyCode == 13) {
  79. var value = document.getElementById("pageIndex").value;
  80. // 整数
  81. var regExp = /^-*\d+$/;
  82. if (regExp.test(value)) {
  83. value = parseInt(value);
  84. if (value < 1) {
  85. value = 1;
  86. }
  87. if (value > pageSize) {
  88. value = pageSize;
  89. }
  90. if (value == pageIndex) {
  91. // 此时输入值可能是在前面修改的,所以要清除输入
  92. document.getElementById("pageIndex").value = pageIndex;
  93. return;
  94. }
  95. pageIndex = value;
  96. renderPage(pageIndex);
  97. } else {
  98. // 输入不合法,需要清除输入
  99. document.getElementById("pageIndex").value = pageIndex;
  100. }
  101. }
  102. });
  103. // 打印
  104. $("#print").click(function() {
  105. if (!pdfDoc) {
  106. return;
  107. }
  108. printPdf();
  109. });
  110. // 下载pdf
  111. $("#downloadPdf").click(function() {
  112. if (!pdfDoc) {
  113. return;
  114. }
  115. window.open(downloadUrl("pdf"));
  116. });
  117. // 下载word
  118. $("#downloadWord").click(function() {
  119. if (!pdfDoc) {
  120. return;
  121. }
  122. window.open(downloadUrl("doc"));
  123. });
  124. // 下载excel
  125. $("#downloadExcel").click(function() {
  126. if (!pdfDoc) {
  127. return;
  128. }
  129. window.open(downloadUrl("xls"));
  130. });
  131. // 下载纯数据excel
  132. $("#downloadExcelData").click(function() {
  133. if (!pdfDoc) {
  134. return;
  135. }
  136. window.open(downloadUrl("xls_data"));
  137. });
  138. // 键盘左右键进行翻页
  139. $("body").keydown(function(event) {
  140. // 如果在选中input输入框或select下拉列表时按左右键,不进行翻页
  141. var activeElementNodeName = document.activeElement.nodeName.toLowerCase();
  142. if (activeElementNodeName == "input" || activeElementNodeName == "select") {
  143. return;
  144. }
  145. if (event.keyCode == 37) {// left
  146. prevPage();
  147. } else if (event.keyCode == 39) {// right
  148. nextPage();
  149. }
  150. });
  151. /**
  152. * 获取窗口宽度
  153. */
  154. function getWindowWidth() {
  155. if (window.innerWidth)
  156. winWidth = window.innerWidth;
  157. else if ((document.body) && (document.body.clientWidth))
  158. winWidth = document.body.clientWidth;
  159. // 获取窗口高度
  160. if (window.innerHeight)
  161. winHeight = window.innerHeight;
  162. else if ((document.body) && (document.body.clientHeight))
  163. winHeight = document.body.clientHeight;
  164. // 通过深入 Document 内部对 body 进行检测,获取窗口大小
  165. if (document.documentElement && document.documentElement.clientHeight
  166. && document.documentElement.clientWidth) {
  167. winHeight = document.documentElement.clientHeight;
  168. winWidth = document.documentElement.clientWidth;
  169. }
  170. }
  171. /**
  172. * 发送请求,服务器端进行填充报表、生成pdf文件等操作
  173. */
  174. function loadData() {
  175. spinner = showLoading(spinner, spinnerContainer);
  176. var loadPdfDataUrl = "print/pdfPath" + window.location.search
  177. + "&flush=true";
  178. $.ajax({
  179. type : "get",
  180. async : true,
  181. url : loadPdfDataUrl,
  182. success : function(path) {
  183. pdfPath = path;
  184. hiddenFrame.src = pdfPath;
  185. PDFJS.getDocument(pdfPath).then(function(pdfDoc_) {
  186. pdfDoc = pdfDoc_;
  187. pageSize = pdfDoc.numPages;
  188. document.getElementById('pageSize').textContent = pageSize;
  189. renderPage(pageIndex);
  190. if (printType == "PRINT") {
  191. setTimeout("printPdf()", 1000);
  192. }
  193. });
  194. },
  195. error : function(XMLHttpRequest) {
  196. showError(XMLHttpRequest);
  197. }
  198. });
  199. };
  200. /**
  201. * Get page info from document, resize canvas accordingly, and render page
  202. */
  203. function renderPage(pageIndex) {
  204. if (rendering) {
  205. nextRenderingPage = pageIndex;
  206. return;
  207. }
  208. rendering = true;
  209. // 更新页码
  210. document.getElementById("pageIndex").value = pageIndex;
  211. spinner = hideLoading(spinner);
  212. if (!pdfDoc) {
  213. return;
  214. }
  215. if (printType == "PRINT") {
  216. spinner = showLoading(spinner, spinnerContainer);
  217. }
  218. pdfDoc.getPage(pageIndex).then(function(page) {
  219. if (!scale || scale == "auto") {
  220. // 调整为适合的宽度
  221. scale = getScale(page, 0.75);
  222. } else if (scale == "page_width") {
  223. // 调整pdf显示的宽度接近窗口宽度
  224. scale = getScale(page, 0.95);
  225. }
  226. var viewport = page.getViewport(scale);
  227. canvas.height = viewport.height;
  228. canvas.width = viewport.width;
  229. // Render PDF page into canvas context
  230. var renderContext = {
  231. canvasContext : ctx,
  232. viewport : viewport
  233. };
  234. // 开始渲染
  235. var renderTask = page.render(renderContext);
  236. renderTask.promise.then(function() {
  237. rendering = false;
  238. if (nextRenderingPage) {
  239. pageIndex = nextRenderingPage;
  240. renderPage(pageIndex);
  241. nextRenderingPage = undefined;
  242. }
  243. });
  244. });
  245. }
  246. /**
  247. * 获取缩放级别(将pdf显示的宽度调整为窗口宽度的multipleOfWindowWidth倍,获取该情况下pdf宽度为原宽度的倍数)
  248. *
  249. * @param page
  250. * pdf数据
  251. * @param multipleOfWindowWidth
  252. * 窗口宽度的倍数
  253. * @returns {Number} 缩放级别(pdf原宽度的倍数)
  254. */
  255. function getScale(page, multipleOfWindowWidth) {
  256. // 首先获取pdf原始宽度
  257. var viewportWidth = page.getViewport(1).width;
  258. return multipleOfWindowWidth / (viewportWidth / winWidth);
  259. }
  260. /**
  261. * 修改缩放下拉框所显示的内容
  262. */
  263. function changeTextOfSelectScale() {
  264. var hiddenOption = document.getElementById("hiddenOption");
  265. hiddenOption.removeAttribute("hidden");
  266. hiddenOption.text = (scale * 100).toFixed() + "%";
  267. hiddenOption.selected = true;
  268. hiddenOption.hidden = true;
  269. }
  270. /**
  271. * 预览前一页
  272. */
  273. function prevPage() {
  274. // 验证pdfDoc不存在,是为了避免报表出现编译失败等问题时,仍然试图翻页
  275. if (!pdfDoc || pageIndex <= 1) {
  276. return;
  277. }
  278. pageIndex--;
  279. renderPage(pageIndex);
  280. }
  281. /**
  282. * 预览后一页
  283. */
  284. function nextPage() {
  285. if (!pdfDoc || pageIndex >= pageSize) {
  286. return;
  287. }
  288. pageIndex++;
  289. renderPage(pageIndex);
  290. }
  291. /**
  292. * 打印
  293. */
  294. function printPdf() {
  295. spinner = hideLoading(spinner);
  296. if (!pdfDoc) {
  297. return;
  298. }
  299. spinner = showLoading(spinner, spinnerContainer);
  300. checkBrowser();
  301. setTimeout(
  302. "hiddenFrame.contentWindow.print();spinner = hideLoading(spinner)",
  303. 1000);
  304. }
  305. /**
  306. * 下载报表
  307. *
  308. * @param exportFileType
  309. * 导出文件的格式
  310. * @returns {String} 下载链接
  311. */
  312. function downloadUrl(exportFileType) {
  313. var downloadUrl = "print/export" + window.location.search;
  314. exportFileType = exportFileType || "pdf";
  315. // 导出文件的格式
  316. downloadUrl += "&exportFileType=" + exportFileType + "&flush=true";
  317. return downloadUrl;
  318. }
  319. /**
  320. * 检查浏览器并提示
  321. */
  322. function checkBrowser() {
  323. var userAgent = navigator.userAgent;
  324. console.log(userAgent);
  325. if (userAgent.indexOf("Chrome") == -1 || userAgent.indexOf("Edge") !== -1) {
  326. alert(spinnerContainer, "建议使用最新版Chrome浏览器打印");
  327. }
  328. }
  329. /**
  330. * 展示错误信息
  331. *
  332. * @param XMLHttpRequest
  333. */
  334. function showError(XMLHttpRequest) {
  335. $("#theCanvas").remove();
  336. spinner = hideLoading(spinner);
  337. $("#errorMessageContainer").removeAttr("hidden");
  338. var result = JSON.parse(XMLHttpRequest.responseText);
  339. var message = result.message;
  340. $("#message").html(message);
  341. var detailedMessage = result.detailedMessage;
  342. if (detailedMessage) {
  343. // 处理后台传输的自定义的换行标志
  344. detailedMessage = detailedMessage.replace(/\n/g, '<br/>').replace(
  345. /\t/g, '&nbsp;&nbsp;&nbsp;&nbsp;');
  346. $("#detailedMessageButton").removeAttr("hidden");
  347. $("#detailedMessage").html(detailedMessage);
  348. }
  349. function hiddenDetailMessage() {
  350. $("#detailedMessage").attr("hidden", "true");
  351. $("#detailedMessageButton").html("展开");
  352. $("#detailedMessageButton").unbind();
  353. $("#detailedMessageButton").click(showDetailMessage);
  354. }
  355. function showDetailMessage() {
  356. $("#detailedMessage").removeAttr("hidden");
  357. $("#detailedMessageButton").html("收起");
  358. $("#detailedMessageButton").unbind();
  359. $("#detailedMessageButton").click(hiddenDetailMessage);
  360. }
  361. hiddenDetailMessage();
  362. }